Commit 929ca711 authored by Marek Vasut's avatar Marek Vasut

mxssb: Implement JUMP command

The jump command is almost identical to the CALL command, with the
difference that CALL command saves stack and allows the called code
to return into the BootROM. JUMP command does not do that, it just
sets the PC register to a value and that's it.

The sematics of both commands are almost identical though, therefore
implement JUMP as a minor adjustment to CALL.
Signed-off-by: Marek Vasut's avatarMarek Vasut <marex@denx.de>
parent 2b3426d9
......@@ -97,6 +97,7 @@ struct sb_image_ctx {
* TAG [LAST]
* LOAD address file
* LOAD IVT address IVT_entry_point
* JUMP [HAB] address [r0_arg]
* CALL [HAB] address [r0_arg]
*/
......@@ -756,7 +757,9 @@ err:
return ret;
}
static int sb_build_command_call(struct sb_image_ctx *ictx, struct sb_cmd_list *cmd)
static int sb_build_command_jump_call(struct sb_image_ctx *ictx,
struct sb_cmd_list *cmd,
unsigned int is_call)
{
struct sb_section_ctx *sctx = ictx->sect_tail;
struct sb_cmd_ctx *cctx;
......@@ -765,6 +768,7 @@ static int sb_build_command_call(struct sb_image_ctx *ictx, struct sb_cmd_list *
long dest, arg = 0x0;
uint32_t hab = 0;
int ret;
const char *cmdname = is_call ? "CALL" : "JUMP";
cctx = calloc(1, sizeof(*cctx));
if (!cctx)
......@@ -778,19 +782,19 @@ static int sb_build_command_call(struct sb_image_ctx *ictx, struct sb_cmd_list *
tok = strtok(cmd->cmd, " ");
if (!tok) {
fprintf(stderr,
"#%i ERR: Missing CALL address or 'HAB'!\n",
cmd->lineno);
"#%i ERR: Missing %s address or 'HAB'!\n",
cmd->lineno, cmdname);
ret = -EINVAL;
goto err;
}
/* Check for "HAB" flag. */
if (!strcmp(tok, "HAB")) {
hab = ROM_CALL_CMD_FLAG_HAB;
hab = is_call ? ROM_CALL_CMD_FLAG_HAB : ROM_JUMP_CMD_FLAG_HAB;
tok = strtok(NULL, " ");
if (!tok) {
fprintf(stderr, "#%i ERR: Missing CALL address!\n",
cmd->lineno);
fprintf(stderr, "#%i ERR: Missing %s address!\n",
cmd->lineno, cmdname);
ret = -EINVAL;
goto err;
}
......@@ -798,8 +802,8 @@ static int sb_build_command_call(struct sb_image_ctx *ictx, struct sb_cmd_list *
/* Read load destination address. */
dest = sb_token_to_long(tok);
if (dest < 0) {
fprintf(stderr, "#%i ERR: Incorrect CALL address!\n",
cmd->lineno);
fprintf(stderr, "#%i ERR: Incorrect %s address!\n",
cmd->lineno, cmdname);
ret = -EINVAL;
goto err;
}
......@@ -809,8 +813,8 @@ static int sb_build_command_call(struct sb_image_ctx *ictx, struct sb_cmd_list *
arg = sb_token_to_long(tok);
if (arg < 0) {
fprintf(stderr,
"#%i ERR: Incorrect CALL argument!\n",
cmd->lineno);
"#%i ERR: Incorrect %s argument!\n",
cmd->lineno, cmdname);
ret = -EINVAL;
goto err;
}
......@@ -820,7 +824,7 @@ static int sb_build_command_call(struct sb_image_ctx *ictx, struct sb_cmd_list *
* Construct the command.
*/
ccmd->header.checksum = 0x5a;
ccmd->header.tag = ROM_CALL_CMD;
ccmd->header.tag = is_call ? ROM_CALL_CMD : ROM_JUMP_CMD;
ccmd->header.flags = hab;
ccmd->call.address = dest;
......@@ -846,6 +850,16 @@ err:
return ret;
}
static int sb_build_command_jump(struct sb_image_ctx *ictx, struct sb_cmd_list *cmd)
{
return sb_build_command_jump_call(ictx, cmd, 0);
}
static int sb_build_command_call(struct sb_image_ctx *ictx, struct sb_cmd_list *cmd)
{
return sb_build_command_jump_call(ictx, cmd, 1);
}
static int sb_prefill_image_header(struct sb_image_ctx *ictx)
{
struct sb_boot_image_header *hdr = &ictx->payload;
......@@ -1013,6 +1027,8 @@ static int sb_parse_line(struct sb_image_ctx *ictx, struct sb_cmd_list *cmd)
ret = sb_build_command_tag(ictx, cmd);
else if (!strcmp(tok, "LOAD"))
ret = sb_build_command_load(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 {
......
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