Commit 346cd235 authored by Marek Vasut's avatar Marek Vasut

mxssb: Rework the tokenization of DCD commands

Instead of having a large if-else-block of DCD commands, tokenize
the commands, split them in the command and size part and analyze
that consistently. This also makes it much easier implementation
wise.
Signed-off-by: Marek Vasut's avatarMarek Vasut <marex@denx.de>
parent f4c3d2a0
......@@ -36,36 +36,36 @@
* | 0xba2 == 0xd00d
* :
*/
#define SB_HAB_DCD_WRITE 0xcc
#define SB_HAB_DCD_CHECK 0xcf
#define SB_HAB_DCD_NOOP 0xc0
enum sb_dcd_cmd {
SB_DCD_WRITE1 = 0xcc000001, /* Addr.1 = Value.1 */
SB_DCD_WRITE2 = 0xcc000002, /* Addr.2 = Value.2 */
SB_DCD_WRITE4 = 0xcc000004, /* Addr.4 = Value.4 */
SB_DCD_ANDC1 = 0xcc000011, /* Addr.1 &= ~Value.1 */
SB_DCD_ANDC2 = 0xcc000012, /* Addr.2 &= ~Value.2 */
SB_DCD_ANDC4 = 0xcc000014, /* Addr.4 &= ~Value.4 */
SB_DCD_ORR1 = 0xcc000019, /* Addr.1 |= Value.1 */
SB_DCD_ORR2 = 0xcc00001a, /* Addr.2 |= Value.2 */
SB_DCD_ORR4 = 0xcc00001c, /* Addr.4 |= Value.4 */
SB_DCD_CHK_EQZ1 = 0xcf000001, /* (Addr.1 & Value.1) == 0 */
SB_DCD_CHK_EQZ2 = 0xcf000002, /* (Addr.2 & Value.2) == 0 */
SB_DCD_CHK_EQZ4 = 0xcf000004, /* (Addr.4 & Value.4) == 0 */
SB_DCD_CHK_EQ1 = 0xcf000011, /* (Addr.1 & Value.1) == Value.1 */
SB_DCD_CHK_EQ2 = 0xcf000012, /* (Addr.2 & Value.2) == Value.2 */
SB_DCD_CHK_EQ4 = 0xcf000014, /* (Addr.4 & Value.4) == Value.4 */
SB_DCD_CHK_NEQ1 = 0xcf000009, /* (Addr.1 & Value.1) != Value.1 */
SB_DCD_CHK_NEQ2 = 0xcf00000a, /* (Addr.2 & Value.2) != Value.2 */
SB_DCD_CHK_NEQ4 = 0xcf00000c, /* (Addr.4 & Value.4) != Value.4 */
SB_DCD_CHK_NEZ1 = 0xcf000019, /* (Addr.1 & Value.1) != 0 */
SB_DCD_CHK_NEZ2 = 0xcf00001a, /* (Addr.2 & Value.2) != 0 */
SB_DCD_CHK_NEZ4 = 0xcf00001c, /* (Addr.4 & Value.4) != 0 */
SB_DCD_NOOP = 0xc0000000, /* NOP */
};
#define SB_HAB_DCD_WRITE 0xccUL
#define SB_HAB_DCD_CHECK 0xcfUL
#define SB_HAB_DCD_NOOP 0xc0UL
#define SB_HAB_DCD_MASK_BIT (1 << 3)
#define SB_HAB_DCD_SET_BIT (1 << 4)
/* Addr.n = Value.n */
#define SB_DCD_WRITE \
(SB_HAB_DCD_WRITE << 24)
/* Addr.n &= ~Value.n */
#define SB_DCD_ANDC \
((SB_HAB_DCD_WRITE << 24) | SB_HAB_DCD_SET_BIT)
/* Addr.n |= Value.n */
#define SB_DCD_ORR \
((SB_HAB_DCD_WRITE << 24) | SB_HAB_DCD_SET_BIT | SB_HAB_DCD_MASK_BIT)
/* (Addr.n & Value.n) == 0 */
#define SB_DCD_CHK_EQZ \
(SB_HAB_DCD_CHECK << 24)
/* (Addr.n & Value.n) == Value.n */
#define SB_DCD_CHK_EQ \
((SB_HAB_DCD_CHECK << 24) | SB_HAB_DCD_SET_BIT)
/* (Addr.n & Value.n) != Value.n */
#define SB_DCD_CHK_NEQ \
((SB_HAB_DCD_CHECK << 24) | SB_HAB_DCD_MASK_BIT)
/* (Addr.n & Value.n) != 0 */
#define SB_DCD_CHK_NEZ \
((SB_HAB_DCD_CHECK << 24) | SB_HAB_DCD_SET_BIT | SB_HAB_DCD_MASK_BIT)
/* NOP */
#define SB_DCD_NOOP \
(SB_HAB_DCD_NOOP << 24)
struct sb_dcd_ctx {
struct sb_dcd_ctx *dcd;
......@@ -670,7 +670,7 @@ err_dcd:
static int sb_build_dcd_block(struct sb_image_ctx *ictx,
struct sb_cmd_list *cmd,
enum sb_dcd_cmd type)
uint32_t type)
{
char *tok;
uint32_t address, value, length;
......@@ -1526,67 +1526,71 @@ static int sb_parse_line(struct sb_image_ctx *ictx, struct sb_cmd_list *cmd)
return -EINVAL;
}
/* Section commands */
if (ictx->in_section && !strcmp(tok, "NOP"))
ret = sb_build_command_nop(ictx);
else if (ictx->in_section && !strcmp(tok, "TAG"))
ret = sb_build_command_tag(ictx, cmd);
else if (ictx->in_section && !strcmp(tok, "LOAD"))
ret = sb_build_command_load(ictx, cmd);
else if (ictx->in_section && !strcmp(tok, "FILL"))
ret = sb_build_command_fill(ictx, cmd);
else if (ictx->in_section && !strcmp(tok, "JUMP"))
ret = sb_build_command_jump(ictx, cmd);
else if (ictx->in_section && !strcmp(tok, "CALL"))
ret = sb_build_command_call(ictx, cmd);
else if (ictx->in_section && !strcmp(tok, "MODE"))
ret = sb_build_command_mode(ictx, cmd);
/* DCD commands */
else if (ictx->in_dcd && !strcmp(tok, "WRITE.1"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_WRITE1);
else if (ictx->in_dcd && !strcmp(tok, "WRITE.2"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_WRITE2);
else if (ictx->in_dcd && !strcmp(tok, "WRITE.4"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_WRITE4);
else if (ictx->in_dcd && !strcmp(tok, "ANDC.1"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_ANDC1);
else if (ictx->in_dcd && !strcmp(tok, "ANDC.2"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_ANDC2);
else if (ictx->in_dcd && !strcmp(tok, "ANDC.4"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_ANDC4);
else if (ictx->in_dcd && !strcmp(tok, "ORR.1"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_ORR1);
else if (ictx->in_dcd && !strcmp(tok, "ORR.2"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_ORR2);
else if (ictx->in_dcd && !strcmp(tok, "ORR.4"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_ORR4);
else if (ictx->in_dcd && !strcmp(tok, "EQZ.1"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_EQZ1);
else if (ictx->in_dcd && !strcmp(tok, "EQZ.2"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_EQZ2);
else if (ictx->in_dcd && !strcmp(tok, "EQZ.4"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_EQZ4);
else if (ictx->in_dcd && !strcmp(tok, "EQ.1"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_EQ1);
else if (ictx->in_dcd && !strcmp(tok, "EQ.2"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_EQ2);
else if (ictx->in_dcd && !strcmp(tok, "EQ.4"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_EQ4);
else if (ictx->in_dcd && !strcmp(tok, "NEQ.1"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_NEQ1);
else if (ictx->in_dcd && !strcmp(tok, "NEQ.2"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_NEQ2);
else if (ictx->in_dcd && !strcmp(tok, "NEQ.4"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_NEQ4);
else if (ictx->in_dcd && !strcmp(tok, "NEZ.1"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_NEZ1);
else if (ictx->in_dcd && !strcmp(tok, "NEZ.2"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_NEZ2);
else if (ictx->in_dcd && !strcmp(tok, "NEZ.4"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_NEZ4);
else if (ictx->in_dcd && !strcmp(tok, "NOOP"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_NOOP);
else {
if (ictx->in_section) {
/* Section commands */
if (!strcmp(tok, "NOP"))
ret = sb_build_command_nop(ictx);
else if (!strcmp(tok, "TAG"))
ret = sb_build_command_tag(ictx, cmd);
else if (!strcmp(tok, "LOAD"))
ret = sb_build_command_load(ictx, cmd);
else if (!strcmp(tok, "FILL"))
ret = sb_build_command_fill(ictx, cmd);
else if (!strcmp(tok, "JUMP"))
ret = sb_build_command_jump(ictx, cmd);
else if (!strcmp(tok, "CALL"))
ret = sb_build_command_call(ictx, cmd);
else if (!strcmp(tok, "MODE"))
ret = sb_build_command_mode(ictx, cmd);
else {
fprintf(stderr,
"#%i ERR: Unsupported instruction '%s'!\n",
cmd->lineno, tok);
return -ENOTSUP;
}
} else if (ictx->in_dcd) {
char *lptr;
uint32_t ilen;
tok = strtok_r(tok, ".", &lptr);
if (!tok || (strlen(tok) == 0) || (lptr && strlen(lptr) != 1)) {
fprintf(stderr, "#%i ERR: Invalid line!\n", cmd->lineno);
return -EINVAL;
}
if (lptr && (lptr[0] != '1' && lptr[0] != '2' && lptr[0] != '4')) {
fprintf(stderr, "#%i ERR: Invalid instruction width!\n",
cmd->lineno);
return -EINVAL;
}
if (lptr)
ilen = lptr[0] - '1';
/* DCD commands */
if (!strcmp(tok, "WRITE"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_WRITE | ilen);
else if (!strcmp(tok, "ANDC"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_ANDC | ilen);
else if (!strcmp(tok, "ORR"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_ORR | ilen);
else if (!strcmp(tok, "EQZ"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_EQZ | ilen);
else if (!strcmp(tok, "EQ"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_EQ | ilen);
else if (!strcmp(tok, "NEQ"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_NEQ | ilen);
else if (!strcmp(tok, "NEZ"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_CHK_NEZ | ilen);
else if (!strcmp(tok, "NOOP"))
ret = sb_build_dcd_block(ictx, cmd, SB_DCD_NOOP);
else {
fprintf(stderr,
"#%i ERR: Unsupported instruction '%s'!\n",
cmd->lineno, tok);
return -ENOTSUP;
}
} else {
fprintf(stderr, "#%i ERR: Unsupported instruction '%s'!\n",
cmd->lineno, tok);
return -ENOTSUP;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment