* riscv64/riscv64/locore.S: Replace x86 trap stubs with RISC-V trap entry and 
exit.
  The alltraps entry saves all 31 GPs and 4 CSRs (scause, stval, sepc, sstatus)
  into a riscv64_saved_state frame on the kernel stack and calls riscv64_trap().
  The return path restores CSRs and registers, then executes sret.
  thread_bootstrap_return, thread_exception_return, and thread_syscall_return
  are implemented as wrappers that jump to the common return path.
* riscv64/riscv64/trap.c: Remove dead x86 code from riscv64_exception stub
  and implement interrupted_pc to return regs->sepc.
---
 riscv64/riscv64/locore.S | 173 ++++++++++++++++++++++++++++-----------
 riscv64/riscv64/trap.c   |  14 +---
 2 files changed, 130 insertions(+), 57 deletions(-)

diff --git a/riscv64/riscv64/locore.S b/riscv64/riscv64/locore.S
index 3d0f4030..45d9c690 100644
--- a/riscv64/riscv64/locore.S
+++ b/riscv64/riscv64/locore.S
@@ -168,66 +168,147 @@ ENTRY(t_debug)
 ENTRY(t_page_fault)
 
 /*
- * All 'exceptions' enter here with:
- *     esp->   trap number
- *             error code
- *             old eip
- *             old cs
- *             old eflags
- *             old esp         if trapped from user
- *             old ss          if trapped from user
+ * RISC-V trap entry/exit.
+ *
+ * On entry, hardware has set:
+ *   scause  - trap cause
+ *   stval   - faulting address or instruction
+ *   sepc    - interrupted PC
+ *   sstatus - previous status (SPP, SPIE, SIE)
+ *
+ * We build a riscv64_saved_state frame (35 * 8 = 280 bytes, padded to 288)
+ * on the kernel stack and call riscv64_trap(regs).
+ *
+ * Frame layout (offsets match struct riscv64_saved_state in thread.h):
+ *   0   t6    8   t5    16  t4    24  t3
+ *   32  s11   40  s10   48  s9    56  s8
+ *   64  s7    72  s6    80  s5    88  s4
+ *   96  s3    104 s2    112 a7    120 a6
+ *   128 a5    136 a4    144 a3    152 a2
+ *   160 a1    168 a0    176 s1    184 fp
+ *   192 t2    200 t1    208 t0    216 tp
+ *   224 gp    232 sp    240 ra
+ *   248 scause  256 stval  264 sepc  272 sstatus
  */
+
+#define FRAME_SIZE 288
+
 ENTRY(alltraps)
-trap_push_segs:
-trap_set_segs:
 trap_from_user:
+trap_from_kernel:
 _take_trap:
-
-/*
- * Return from trap or system call, checking for ASTs.
- * On PCB stack.
- */
+       addi    sp, sp, -FRAME_SIZE
+
+       sd      t6,  0(sp)
+       sd      t5,  8(sp)
+       sd      t4,  16(sp)
+       sd      t3,  24(sp)
+       sd      s11, 32(sp)
+       sd      s10, 40(sp)
+       sd      s9,  48(sp)
+       sd      s8,  56(sp)
+       sd      s7,  64(sp)
+       sd      s6,  72(sp)
+       sd      s5,  80(sp)
+       sd      s4,  88(sp)
+       sd      s3,  96(sp)
+       sd      s2,  104(sp)
+       sd      a7,  112(sp)
+       sd      a6,  120(sp)
+       sd      a5,  128(sp)
+       sd      a4,  136(sp)
+       sd      a3,  144(sp)
+       sd      a2,  152(sp)
+       sd      a1,  160(sp)
+       sd      a0,  168(sp)
+       sd      s1,  176(sp)
+       sd      fp,  184(sp)
+       sd      t2,  192(sp)
+       sd      t1,  200(sp)
+       sd      t0,  208(sp)
+       sd      tp,  216(sp)
+       sd      gp,  224(sp)
+       sd      ra,  240(sp)
+
+       /* Save original sp */
+       addi    t0, sp, FRAME_SIZE
+       sd      t0,  232(sp)
+
+       /* Save CSRs */
+       csrr    t0, scause
+       sd      t0,  248(sp)
+       csrr    t0, stval
+       sd      t0,  256(sp)
+       csrr    t0, sepc
+       sd      t0,  264(sp)
+       csrr    t0, sstatus
+       sd      t0,  272(sp)
+
+       /* Call C: void riscv64_trap(struct riscv64_saved_state *regs) */
+       mv      a0, sp
+       call    riscv64_trap
 
 _return_from_trap:
-
 _return_to_user:
-
-/*
- * Return from kernel mode to interrupted thread.
+       /* Restore sstatus and sepc */
+       ld      t0, 272(sp)
+       csrw    sstatus, t0
+       ld      t0, 264(sp)
+       csrw    sepc, t0
+
+       /* Restore caller-saved and callee-saved registers */
+       ld      t6,  0(sp)
+       ld      t5,  8(sp)
+       ld      t4,  16(sp)
+       ld      t3,  24(sp)
+       ld      s11, 32(sp)
+       ld      s10, 40(sp)
+       ld      s9,  48(sp)
+       ld      s8,  56(sp)
+       ld      s7,  64(sp)
+       ld      s6,  72(sp)
+       ld      s5,  80(sp)
+       ld      s4,  88(sp)
+       ld      s3,  96(sp)
+       ld      s2,  104(sp)
+       ld      a7,  112(sp)
+       ld      a6,  120(sp)
+       ld      a5,  128(sp)
+       ld      a4,  136(sp)
+       ld      a3,  144(sp)
+       ld      a2,  152(sp)
+       ld      a1,  160(sp)
+       ld      a0,  168(sp)
+       ld      s1,  176(sp)
+       ld      fp,  184(sp)
+       ld      t2,  192(sp)
+       ld      t1,  200(sp)
+       ld      t0,  208(sp)
+       ld      tp,  216(sp)
+       ld      gp,  224(sp)
+       ld      ra,  240(sp)
+       ld      sp,  232(sp)
+
+       sret
+END(alltraps)
+
+/*
+ * Return from kernel as if from an exception.
+ * Called as a C function; saved state is on the current stack.
  */
-
-_return_from_kernel:
-_kret_popl_gs:
-_kret_popl_fs:
-_kret_popl_es:
-_kret_popl_ds:
-_kret_iret:
-
-
-/*
- * Trap from kernel mode.  No need to switch stacks.
- */
-trap_from_kernel:
-#if    MACH_KDB || MACH_TTD
-#else  /* MACH_KDB || MACH_TTD */
-#endif /* MACH_KDB || MACH_TTD */
-
-
-/*
- *     Called as a function, makes the current thread
- *     return from the kernel as if from an exception.
- */
-
 ENTRY(thread_exception_return)
 ENTRY(thread_bootstrap_return)
+       j       _return_from_trap
+END(thread_bootstrap_return)
 
 /*
- *     Called as a function, makes the current thread
- *     return from the kernel as if from a syscall.
- *     Takes the syscall's return code as an argument.
+ * Return from syscall.  a0 = return code.
+ * Stored into the saved state's a0 slot on the stack.
  */
-
 ENTRY(thread_syscall_return)
+       sd      a0, 168(sp)
+       j       _return_from_trap
+END(thread_syscall_return)
 
 ENTRY(call_continuation)
 
diff --git a/riscv64/riscv64/trap.c b/riscv64/riscv64/trap.c
index 014e48cf..4e790d68 100644
--- a/riscv64/riscv64/trap.c
+++ b/riscv64/riscv64/trap.c
@@ -169,15 +169,7 @@ riscv64_exception(
        int     code,
        long    subcode)
 {
-       spl_t   s;
-
-       /*
-        * Turn off delayed FPU error handling.
-        */
-       panic("TODO: not implemented");
-
-       exception(exc, code, subcode);
-       /*NOTREACHED*/
+       panic("riscv64_exception: exc=%d code=%d", exc, code);
 }
 
 #if    MACH_PCSAMPLE > 0
@@ -187,8 +179,8 @@ riscv64_exception(
 unsigned
 interrupted_pc(const thread_t t)
 {
-       panic("TODO: not implemented");
-       return 0;
+       struct riscv64_saved_state *regs = USER_REGS(t);
+       return regs->sepc;
 }
 #endif /* MACH_PCSAMPLE > 0 */
 
-- 
2.43.0


Reply via email to