Message ID | 20240828095243.90491-3-itachis@FreeBSD.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | bsd-user: Comprehensive RISCV Support | expand |
On Wed, Aug 28, 2024 at 7:53 PM Ajeet Singh <itachis6234@gmail.com> wrote: > > From: Mark Corbin <mark@dibsco.co.uk> > > Implemented the RISC-V CPU execution loop, including handling various > exceptions and system calls. The loop continuously executes CPU > instructions,processes exceptions, and handles system calls by invoking > FreeBSD syscall handlers. > > Signed-off-by: Mark Corbin <mark@dibsco.co.uk> > Signed-off-by: Ajeet Singh <itachis@FreeBSD.org> > Co-authored-by: Jessica Clarke <jrtc27@jrtc27.com> > Co-authored-by: Kyle Evans <kevans@FreeBSD.org> > Reviewed-by: Richard Henderson <richard.henderson@linaro.org> > --- > bsd-user/riscv/target_arch_cpu.h | 94 ++++++++++++++++++++++++++++++++ > 1 file changed, 94 insertions(+) > > diff --git a/bsd-user/riscv/target_arch_cpu.h b/bsd-user/riscv/target_arch_cpu.h > index e17c910ae9..ba589909e2 100644 > --- a/bsd-user/riscv/target_arch_cpu.h > +++ b/bsd-user/riscv/target_arch_cpu.h > @@ -36,4 +36,98 @@ static inline void target_cpu_init(CPURISCVState *env, > env->pc = regs->sepc; > } > > +static inline void target_cpu_loop(CPURISCVState *env) > +{ > + CPUState *cs = env_cpu(env); > + int trapnr; > + abi_long ret; > + unsigned int syscall_num; > + int32_t signo, code; > + > + for (;;) { > + cpu_exec_start(cs); > + trapnr = cpu_exec(cs); > + cpu_exec_end(cs); > + process_queued_cpu_work(cs); > + > + signo = 0; > + > + switch (trapnr) { > + case EXCP_INTERRUPT: > + /* just indicate that signals should be handled asap */ > + break; > + case EXCP_ATOMIC: > + cpu_exec_step_atomic(cs); > + break; > + case RISCV_EXCP_U_ECALL: > + syscall_num = env->gpr[xT0]; > + env->pc += TARGET_INSN_SIZE; > + /* Compare to cpu_fetch_syscall_args() in riscv/riscv/trap.c */ > + if (TARGET_FREEBSD_NR___syscall == syscall_num || > + TARGET_FREEBSD_NR_syscall == syscall_num) { > + ret = do_freebsd_syscall(env, > + env->gpr[xA0], > + env->gpr[xA1], > + env->gpr[xA2], > + env->gpr[xA3], > + env->gpr[xA4], > + env->gpr[xA5], > + env->gpr[xA6], > + env->gpr[xA7], > + 0); > + } else { > + ret = do_freebsd_syscall(env, > + syscall_num, > + env->gpr[xA0], > + env->gpr[xA1], > + env->gpr[xA2], > + env->gpr[xA3], > + env->gpr[xA4], > + env->gpr[xA5], > + env->gpr[xA6], > + env->gpr[xA7] There is trailing white space on these lines and in a few other patches in this series. Can you run ./scripts/checkpatch.pl against the changes and then send a v5 with the issues addressed Alistair > + ); > + } > + > + /* > + * Compare to cpu_set_syscall_retval() in > + * riscv/riscv/vm_machdep.c > + */ > + if (ret >= 0) { > + env->gpr[xA0] = ret; > + env->gpr[xT0] = 0; > + } else if (ret == -TARGET_ERESTART) { > + env->pc -= TARGET_INSN_SIZE; > + } else if (ret != -TARGET_EJUSTRETURN) { > + env->gpr[xA0] = -ret; > + env->gpr[xT0] = 1; > + } > + break; > + case RISCV_EXCP_ILLEGAL_INST: > + signo = TARGET_SIGILL; > + code = TARGET_ILL_ILLOPC; > + break; > + case RISCV_EXCP_BREAKPOINT: > + signo = TARGET_SIGTRAP; > + code = TARGET_TRAP_BRKPT; > + break; > + case EXCP_DEBUG: > + signo = TARGET_SIGTRAP; > + code = TARGET_TRAP_BRKPT; > + break; > + default: > + fprintf(stderr, "qemu: unhandled CPU exception " > + "0x%x - aborting\n", trapnr); > + cpu_dump_state(cs, stderr, 0); > + abort(); > + } > + > + if (signo) { > + force_sig_fault(signo, code, env->pc); > + } > + > + process_pending_signals(env); > + } > +} > + > #endif /* TARGET_ARCH_CPU_H */ > -- > 2.34.1 > >
diff --git a/bsd-user/riscv/target_arch_cpu.h b/bsd-user/riscv/target_arch_cpu.h index e17c910ae9..ba589909e2 100644 --- a/bsd-user/riscv/target_arch_cpu.h +++ b/bsd-user/riscv/target_arch_cpu.h @@ -36,4 +36,98 @@ static inline void target_cpu_init(CPURISCVState *env, env->pc = regs->sepc; } +static inline void target_cpu_loop(CPURISCVState *env) +{ + CPUState *cs = env_cpu(env); + int trapnr; + abi_long ret; + unsigned int syscall_num; + int32_t signo, code; + + for (;;) { + cpu_exec_start(cs); + trapnr = cpu_exec(cs); + cpu_exec_end(cs); + process_queued_cpu_work(cs); + + signo = 0; + + switch (trapnr) { + case EXCP_INTERRUPT: + /* just indicate that signals should be handled asap */ + break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; + case RISCV_EXCP_U_ECALL: + syscall_num = env->gpr[xT0]; + env->pc += TARGET_INSN_SIZE; + /* Compare to cpu_fetch_syscall_args() in riscv/riscv/trap.c */ + if (TARGET_FREEBSD_NR___syscall == syscall_num || + TARGET_FREEBSD_NR_syscall == syscall_num) { + ret = do_freebsd_syscall(env, + env->gpr[xA0], + env->gpr[xA1], + env->gpr[xA2], + env->gpr[xA3], + env->gpr[xA4], + env->gpr[xA5], + env->gpr[xA6], + env->gpr[xA7], + 0); + } else { + ret = do_freebsd_syscall(env, + syscall_num, + env->gpr[xA0], + env->gpr[xA1], + env->gpr[xA2], + env->gpr[xA3], + env->gpr[xA4], + env->gpr[xA5], + env->gpr[xA6], + env->gpr[xA7] + ); + } + + /* + * Compare to cpu_set_syscall_retval() in + * riscv/riscv/vm_machdep.c + */ + if (ret >= 0) { + env->gpr[xA0] = ret; + env->gpr[xT0] = 0; + } else if (ret == -TARGET_ERESTART) { + env->pc -= TARGET_INSN_SIZE; + } else if (ret != -TARGET_EJUSTRETURN) { + env->gpr[xA0] = -ret; + env->gpr[xT0] = 1; + } + break; + case RISCV_EXCP_ILLEGAL_INST: + signo = TARGET_SIGILL; + code = TARGET_ILL_ILLOPC; + break; + case RISCV_EXCP_BREAKPOINT: + signo = TARGET_SIGTRAP; + code = TARGET_TRAP_BRKPT; + break; + case EXCP_DEBUG: + signo = TARGET_SIGTRAP; + code = TARGET_TRAP_BRKPT; + break; + default: + fprintf(stderr, "qemu: unhandled CPU exception " + "0x%x - aborting\n", trapnr); + cpu_dump_state(cs, stderr, 0); + abort(); + } + + if (signo) { + force_sig_fault(signo, code, env->pc); + } + + process_pending_signals(env); + } +} + #endif /* TARGET_ARCH_CPU_H */