diff options
| author | Richard Henderson <richard.henderson@linaro.org> | 2022-04-26 13:12:37 -0700 |
|---|---|---|
| committer | Richard Henderson <richard.henderson@linaro.org> | 2022-04-26 13:12:37 -0700 |
| commit | 88d5814e6b02515f823086abb91dc7cdbb31c9f1 (patch) | |
| tree | dcce7c9d3f084a14aca85dcef4feb65ff63a48a3 /linux-user/nios2/cpu_loop.c | |
| parent | eab18e4021b80a03729424385c506e2454cd635c (diff) | |
| parent | 7f176c5a0bcb70492f3b158a36311e75f1eb87d7 (diff) | |
| download | focaccia-qemu-88d5814e6b02515f823086abb91dc7cdbb31c9f1.tar.gz focaccia-qemu-88d5814e6b02515f823086abb91dc7cdbb31c9f1.zip | |
Merge tag 'pull-nios2-20220426' of https://gitlab.com/rth7680/qemu into staging
Fix nios2-linux-user syscalls. Fix nios2-linux-user sigreturn. Enable tests for nios2-linux-user. Remove special handling of SIGSEGV. Check supervisor for eret, bret. Split special registers out of env->regs[]. Clean up interrupt processing. Raise unaligned data and destination exceptions. Set TLBMISC fields correctly on exceptions. Prevent writes to read-only or reserved control fields. Use tcg_constant_tl(). Implement shadow register sets. Implement external interrupt controller interface. Implement vectored interrupt controller. Enable semihosting tests for nios2-softmmu. # -----BEGIN PGP SIGNATURE----- # # iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmJoNuQdHHJpY2hhcmQu # aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+a0ggAhawc3tod4OTHRlRq # rvZrJK740bNMo8rtidDnh71+IGjBiz8pXahqkE78cADtMzNmQoScwWbjht3cuMN2 # TMV0sbNDeA2OB98QzX6JTbCRtEfQAB7pyjpFvg6oXhYYSfwwhWbTR9QsYTHjq157 # ZKOprafoSlmDlgWJhlAikLdvJb07/5jgmvsLbBzu8/G/HiJ4HhHyjZxL1wNz1t/+ # 0KTAbnn3SWGDAhLGS/P6BMZKeU1EAExAwo7CtZeUbs+9QCfeM3cBAurG3WB1Vw14 # ERPoGPPrARtoNPtgQFMHu0am3HH5HtneuzJfWaLT96rrwNyTrYY0EYti1NtFDW8O # CCz42Q== # =MHar # -----END PGP SIGNATURE----- # gpg: Signature made Tue 26 Apr 2022 11:16:04 AM PDT # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [ultimate] * tag 'pull-nios2-20220426' of https://gitlab.com/rth7680/qemu: (68 commits) tests/tcg/nios2: Add test-shadow-1 tests/tcg/nios2: Add semihosting multiarch tests hw/nios2: Machine with a Vectored Interrupt Controller hw/nios2: Move memory regions into Nios2Machine hw/nios2: Introduce Nios2MachineState hw/intc: Vectored Interrupt Controller (VIC) linux-user/nios2: Handle various SIGILL exceptions target/nios2: Advance pc when raising exceptions target/nios2: Implement EIC interrupt processing target/nios2: Update helper_eret for shadow registers target/nios2: Implement rdprs, wrprs target/nios2: Introduce shadow register sets target/nios2: Implement Misaligned destination exception target/nios2: Use tcg_gen_lookup_and_goto_ptr target/nios2: Use gen_goto_tb for DISAS_TOO_MANY target/nios2: Hoist set of is_jmp into gen_goto_tb target/nios2: Create gen_jumpr target/nios2: Enable unaligned traps for system mode target/nios2: Drop CR_STATUS_EH from tb->flags target/nios2: Introduce dest_gpr ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'linux-user/nios2/cpu_loop.c')
| -rw-r--r-- | linux-user/nios2/cpu_loop.c | 96 |
1 files changed, 46 insertions, 50 deletions
diff --git a/linux-user/nios2/cpu_loop.c b/linux-user/nios2/cpu_loop.c index 1e93ef34e6..da77ede76b 100644 --- a/linux-user/nios2/cpu_loop.c +++ b/linux-user/nios2/cpu_loop.c @@ -26,7 +26,6 @@ void cpu_loop(CPUNios2State *env) { CPUState *cs = env_cpu(env); - target_siginfo_t info; int trapnr, ret; for (;;) { @@ -39,6 +38,30 @@ void cpu_loop(CPUNios2State *env) /* just indicate that signals should be handled asap */ break; + case EXCP_DIV: + /* Match kernel's handle_diverror_c(). */ + env->pc -= 4; + force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTDIV, env->pc); + break; + + case EXCP_UNALIGN: + case EXCP_UNALIGND: + force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, + env->ctrl[CR_BADADDR]); + break; + + case EXCP_ILLEGAL: + case EXCP_UNIMPL: + /* Match kernel's handle_illegal_c(). */ + env->pc -= 4; + force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->pc); + break; + case EXCP_SUPERI: + /* Match kernel's handle_supervisor_instr(). */ + env->pc -= 4; + force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVOPC, env->pc); + break; + case EXCP_TRAP: switch (env->error_code) { case 0: @@ -49,32 +72,41 @@ void cpu_loop(CPUNios2State *env) env->regs[7], env->regs[8], env->regs[9], 0, 0); - if (env->regs[2] == 0) { /* FIXME: syscall 0 workaround */ - ret = 0; + if (ret == -QEMU_ESIGRETURN) { + /* rt_sigreturn has set all state. */ + break; } - + if (ret == -QEMU_ERESTARTSYS) { + env->pc -= 4; + break; + } + /* + * See the code after translate_rc_and_ret: all negative + * values are errors (aided by userspace restricted to 2G), + * errno is returned positive in r2, and error indication + * is a boolean in r7. + */ env->regs[2] = abs(ret); - /* Return value is 0..4096 */ - env->regs[7] = ret > 0xfffff000u; - env->regs[R_PC] += 4; + env->regs[7] = ret < 0; break; case 1: qemu_log_mask(CPU_LOG_INT, "\nTrap 1\n"); - force_sig_fault(TARGET_SIGUSR1, 0, env->regs[R_PC]); + force_sig_fault(TARGET_SIGUSR1, 0, env->pc); break; case 2: qemu_log_mask(CPU_LOG_INT, "\nTrap 2\n"); - force_sig_fault(TARGET_SIGUSR2, 0, env->regs[R_PC]); + force_sig_fault(TARGET_SIGUSR2, 0, env->pc); break; case 31: qemu_log_mask(CPU_LOG_INT, "\nTrap 31\n"); - force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->regs[R_PC]); + /* Match kernel's breakpoint_c(). */ + env->pc -= 4; + force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc); break; default: qemu_log_mask(CPU_LOG_INT, "\nTrap %d\n", env->error_code); - force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLTRP, - env->regs[R_PC]); + force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLTRP, env->pc); break; case 16: /* QEMU specific, for __kuser_cmpxchg */ @@ -99,27 +131,13 @@ void cpu_loop(CPUNios2State *env) o = env->regs[5]; n = env->regs[6]; env->regs[2] = qatomic_cmpxchg(h, o, n) - o; - env->regs[R_PC] += 4; } break; } break; case EXCP_DEBUG: - info.si_signo = TARGET_SIGTRAP; - info.si_errno = 0; - info.si_code = TARGET_TRAP_BRKPT; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - break; - case 0xaa: - { - info.si_signo = TARGET_SIGSEGV; - info.si_errno = 0; - /* TODO: check env->error_code */ - info.si_code = TARGET_SEGV_MAPERR; - info._sifields._sigfault._addr = env->regs[R_PC]; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - } + force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc); break; default: EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n", @@ -133,28 +151,6 @@ void cpu_loop(CPUNios2State *env) void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) { - env->regs[0] = 0; - env->regs[1] = regs->r1; - env->regs[2] = regs->r2; - env->regs[3] = regs->r3; - env->regs[4] = regs->r4; - env->regs[5] = regs->r5; - env->regs[6] = regs->r6; - env->regs[7] = regs->r7; - env->regs[8] = regs->r8; - env->regs[9] = regs->r9; - env->regs[10] = regs->r10; - env->regs[11] = regs->r11; - env->regs[12] = regs->r12; - env->regs[13] = regs->r13; - env->regs[14] = regs->r14; - env->regs[15] = regs->r15; - /* TODO: unsigned long orig_r2; */ - env->regs[R_RA] = regs->ra; - env->regs[R_FP] = regs->fp; env->regs[R_SP] = regs->sp; - env->regs[R_GP] = regs->gp; - env->regs[CR_ESTATUS] = regs->estatus; - env->regs[R_PC] = regs->ea; - /* TODO: unsigned long orig_r7; */ + env->pc = regs->ea; } |