Skip to content

Commit

Permalink
linux-user/nios2: Fix EA vs PC confusion
Browse files Browse the repository at this point in the history
The real kernel will talk about the user PC as EA,
because that's where the hardware will have copied it,
and where it expects to put it to then use ERET.
But qemu does not emulate all of the exception stuff
while emulating user-only.  Manipulate PC directly.

This fixes signal entry and return, and eliminates
some slight confusion from target_cpu_copy_regs.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <20211221025012.1057923-6-richard.henderson@linaro.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
  • Loading branch information
rth7680 authored and vivier committed Jan 6, 2022
1 parent f5ef0e5 commit 8222d8b
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 7 deletions.
5 changes: 1 addition & 4 deletions linux-user/nios2/cpu_loop.c
Expand Up @@ -155,9 +155,6 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
env->regs[R_SP] = regs->sp;
env->regs[R_GP] = regs->gp;
env->regs[CR_ESTATUS] = regs->estatus;
env->regs[R_EA] = regs->ea;
/* TODO: unsigned long orig_r7; */

/* Emulate eret when starting thread. */
env->regs[R_PC] = regs->ea;
/* TODO: unsigned long orig_r7; */
}
6 changes: 3 additions & 3 deletions linux-user/nios2/signal.c
Expand Up @@ -73,7 +73,7 @@ static void rt_setup_ucontext(struct target_ucontext *uc, CPUNios2State *env)
__put_user(env->regs[R_RA], &gregs[23]);
__put_user(env->regs[R_FP], &gregs[24]);
__put_user(env->regs[R_GP], &gregs[25]);
__put_user(env->regs[R_EA], &gregs[27]);
__put_user(env->regs[R_PC], &gregs[27]);
__put_user(env->regs[R_SP], &gregs[28]);
}

Expand Down Expand Up @@ -122,7 +122,7 @@ static int rt_restore_ucontext(CPUNios2State *env, struct target_ucontext *uc,
__get_user(env->regs[R_GP], &gregs[25]);
/* Not really necessary no user settable bits */
__get_user(temp, &gregs[26]);
__get_user(env->regs[R_EA], &gregs[27]);
__get_user(env->regs[R_PC], &gregs[27]);

__get_user(env->regs[R_RA], &gregs[23]);
__get_user(env->regs[R_SP], &gregs[28]);
Expand Down Expand Up @@ -181,7 +181,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
env->regs[4] = sig;
env->regs[5] = frame_addr + offsetof(struct target_rt_sigframe, info);
env->regs[6] = frame_addr + offsetof(struct target_rt_sigframe, uc);
env->regs[R_EA] = ka->_sa_handler;
env->regs[R_PC] = ka->_sa_handler;

unlock_user_struct(frame, frame_addr, 1);
}
Expand Down

0 comments on commit 8222d8b

Please sign in to comment.