diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-10-16 02:39:56 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-10-16 02:39:56 +0800 |
| commit | 8cace3f05003c6cb4d38c36890055f03151c2ad4 (patch) | |
| tree | aa739deaac0266f17c4e91b333957501cb1ea2e9 /arch/riscv/trap/trap_vector.S | |
| parent | 3ad39e9878310e5317ee73c9b353c1e2c1c5c4ee (diff) | |
| download | lume-8cace3f05003c6cb4d38c36890055f03151c2ad4.tar.gz lume-8cace3f05003c6cb4d38c36890055f03151c2ad4.tar.xz | |
Remove old code
Signed-off-by: Richard Qin <richard.qin.x@gmail.com>
Diffstat (limited to 'arch/riscv/trap/trap_vector.S')
| -rw-r--r-- | arch/riscv/trap/trap_vector.S | 283 |
1 files changed, 0 insertions, 283 deletions
diff --git a/arch/riscv/trap/trap_vector.S b/arch/riscv/trap/trap_vector.S deleted file mode 100644 index 8e45cae..0000000 --- a/arch/riscv/trap/trap_vector.S +++ /dev/null @@ -1,283 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -/* - * Trap Vector Entry / Exit (RISC-V 64, S-mode) - * - * On trap entry (interrupt / exception / ecall): - * sscratch holds the TrapFrame pointer (set up by kernel before sret). - * We swap sscratch <-> tp, save all 31 GPRs + sstatus + sepc into TrapFrame, - * then load kernel metadata (sp, satp, tp, trap handler) and jump to C++. - * - * On trap return (userret): - * Restore all GPRs + sstatus + sepc from TrapFrame, swap sscratch <-> tp, - * then sret back to user mode. - * - * Layout must match arch::TrapFrame in arch/riscv/include/arch/trapframe.h - * Reference: docs/specs/arch_abstraction.md §7.2 - */ - -#include <arch/trapframe.h> - - .section .text - .globl trap_vector - .globl userret - .align 4 - -/* - * trap_vector — unified S-mode trap entry point (Direct mode) - * - * Precondition: sscratch = pointer to current task's TrapFrame - */ -trap_vector: - /* Step 1: swap sscratch <-> tp. Now tp = TrapFrame*, sscratch = old tp */ - csrrw tp, sscratch, tp - - /* Step 2: save all 31 general-purpose registers into TrapFrame */ - sd ra, TF_RA(tp) - sd sp, TF_SP(tp) - sd gp, TF_GP(tp) - /* tp (x4) is in sscratch — save it later */ - sd t0, TF_T0(tp) - sd t1, TF_T1(tp) - sd t2, TF_T2(tp) - sd s0, TF_S0(tp) - sd s1, TF_S1(tp) - sd a0, TF_A0(tp) - sd a1, TF_A1(tp) - sd a2, TF_A2(tp) - sd a3, TF_A3(tp) - sd a4, TF_A4(tp) - sd a5, TF_A5(tp) - sd a6, TF_A6(tp) - sd a7, TF_A7(tp) - sd s2, TF_S2(tp) - sd s3, TF_S3(tp) - sd s4, TF_S4(tp) - sd s5, TF_S5(tp) - sd s6, TF_S6(tp) - sd s7, TF_S7(tp) - sd s8, TF_S8(tp) - sd s9, TF_S9(tp) - sd s10, TF_S10(tp) - sd s11, TF_S11(tp) - sd t3, TF_T3(tp) - sd t4, TF_T4(tp) - sd t5, TF_T5(tp) - sd t6, TF_T6(tp) - - /* Save the real tp (user's tp) which is now in sscratch */ - csrr t0, sscratch - sd t0, TF_TP(tp) - - /* Step 3: save sstatus */ - csrr t0, sstatus - sd t0, TF_SSTATUS(tp) - - /* Step 4: save sepc (interrupted PC) */ - csrr t0, sepc - sd t0, TF_EPC(tp) - - /* Step 5: load kernel context from TrapFrame metadata */ - ld sp, TF_KERNEL_SP(tp) /* switch to kernel stack */ - ld t1, TF_KERNEL_SATP(tp) /* kernel page table */ - ld t2, TF_KERNEL_CPUID(tp) /* CPU ID for tp */ - ld t3, TF_KERNEL_TRAP(tp) /* C++ trap_handler address */ - - /* Switch to kernel page table */ - csrw satp, t1 - - /* Step 6: flush TLB after page table switch */ - sfence.vma zero, zero - - /* Step 6.5: restore kernel gp (global pointer). - * The compiler uses gp-relative addressing for global variable access - * (e.g. ld reg, offset(gp)). User mode may have set gp to anything, - * so we MUST reload it before entering any C++ code. */ -.option push -.option norelax - la gp, __global_pointer$ -.option pop - - /* Pass TrapFrame* to C++ handler (a0 = tf) */ - mv a0, tp - - /* Set tp = CPU ID (kernel convention) */ - mv tp, t2 - - /* Step 7: jump to C++ trap_handler */ - jalr t3 - - -/* ======================================================================== - * kernelvec — unified S-mode trap entry point for traps FROM S-MODE - * - * Traps from S-mode already have a valid kernel stack pointer in sp. - * We just allocate a TrapFrame on the stack and save registers. - * ======================================================================== */ - .globl kernelvec - .align 4 -kernelvec: - /* Allocate TrapFrame on stack */ - addi sp, sp, -296 - - /* Save all 31 general-purpose registers into TrapFrame */ - sd ra, TF_RA(sp) - /* Save the OLD sp (before we subtracted 296) */ - addi t0, sp, 296 - sd t0, TF_SP(sp) - sd gp, TF_GP(sp) - sd tp, TF_TP(sp) - sd t0, TF_T0(sp) - sd t1, TF_T1(sp) - sd t2, TF_T2(sp) - sd s0, TF_S0(sp) - sd s1, TF_S1(sp) - sd a0, TF_A0(sp) - sd a1, TF_A1(sp) - sd a2, TF_A2(sp) - sd a3, TF_A3(sp) - sd a4, TF_A4(sp) - sd a5, TF_A5(sp) - sd a6, TF_A6(sp) - sd a7, TF_A7(sp) - sd s2, TF_S2(sp) - sd s3, TF_S3(sp) - sd s4, TF_S4(sp) - sd s5, TF_S5(sp) - sd s6, TF_S6(sp) - sd s7, TF_S7(sp) - sd s8, TF_S8(sp) - sd s9, TF_S9(sp) - sd s10, TF_S10(sp) - sd s11, TF_S11(sp) - sd t3, TF_T3(sp) - sd t4, TF_T4(sp) - sd t5, TF_T5(sp) - sd t6, TF_T6(sp) - - /* Save sstatus and sepc */ - csrr t0, sstatus - sd t0, TF_SSTATUS(sp) - csrr t0, sepc - sd t0, TF_EPC(sp) - - /* Call C++ kernel_trap_handler(TrapFrame* tf) */ - mv a0, sp - call kernel_trap_handler - - /* Restore sstatus and sepc */ - ld t0, TF_SSTATUS(sp) - csrw sstatus, t0 - ld t0, TF_EPC(sp) - csrw sepc, t0 - - /* Restore all 31 general-purpose registers */ - ld ra, TF_RA(sp) - ld gp, TF_GP(sp) - ld tp, TF_TP(sp) - ld t0, TF_T0(sp) - ld t1, TF_T1(sp) - ld t2, TF_T2(sp) - ld s0, TF_S0(sp) - ld s1, TF_S1(sp) - ld a0, TF_A0(sp) - ld a1, TF_A1(sp) - ld a2, TF_A2(sp) - ld a3, TF_A3(sp) - ld a4, TF_A4(sp) - ld a5, TF_A5(sp) - ld a6, TF_A6(sp) - ld a7, TF_A7(sp) - ld s2, TF_S2(sp) - ld s3, TF_S3(sp) - ld s4, TF_S4(sp) - ld s5, TF_S5(sp) - ld s6, TF_S6(sp) - ld s7, TF_S7(sp) - ld s8, TF_S8(sp) - ld s9, TF_S9(sp) - ld s10, TF_S10(sp) - ld s11, TF_S11(sp) - ld t3, TF_T3(sp) - ld t4, TF_T4(sp) - ld t5, TF_T5(sp) - ld t6, TF_T6(sp) - - /* Restore sp last */ - ld sp, TF_SP(sp) - - sret - -/* - * userret — return to user mode - * - * Called from C++ as: userret(TrapFrame* tf) - * a0 = pointer to TrapFrame (with user satp already written by caller) - * - * Precondition: interrupts must be disabled by caller. - */ -userret: - /* a0 = TrapFrame pointer, use it as base */ - - /* Step 1: write back epc -> sepc */ - ld t0, TF_EPC(a0) - csrw sepc, t0 - - /* Step 2: write back sstatus */ - ld t0, TF_SSTATUS(a0) - csrw sstatus, t0 - - /* Step 3: caller is responsible for switching satp to user page table - * and flushing TLB before calling userret. */ - - /* Store TrapFrame address into sscratch for next trap entry */ - csrw sscratch, a0 - - /* Use a0 as base to restore all registers */ - mv tp, a0 - - /* Step 4: restore all 31 general-purpose registers */ - ld ra, TF_RA(tp) - ld sp, TF_SP(tp) - ld gp, TF_GP(tp) - /* defer tp restore — we're using it as base */ - ld t0, TF_T0(tp) - ld t1, TF_T1(tp) - ld t2, TF_T2(tp) - ld s0, TF_S0(tp) - ld s1, TF_S1(tp) - ld a0, TF_A0(tp) - ld a1, TF_A1(tp) - ld a2, TF_A2(tp) - ld a3, TF_A3(tp) - ld a4, TF_A4(tp) - ld a5, TF_A5(tp) - ld a6, TF_A6(tp) - ld a7, TF_A7(tp) - ld s2, TF_S2(tp) - ld s3, TF_S3(tp) - ld s4, TF_S4(tp) - ld s5, TF_S5(tp) - ld s6, TF_S6(tp) - ld s7, TF_S7(tp) - ld s8, TF_S8(tp) - ld s9, TF_S9(tp) - ld s10, TF_S10(tp) - ld s11, TF_S11(tp) - ld t3, TF_T3(tp) - ld t4, TF_T4(tp) - ld t5, TF_T5(tp) - ld t6, TF_T6(tp) - - /* Step 5: restore user tp (swap sscratch <-> tp) */ - /* sscratch currently = TrapFrame address, tp = TrapFrame address */ - /* We need: tp = user's tp, sscratch = TrapFrame address */ - /* Load user tp from TrapFrame first, but we can't use any temp reg now. - * Use the sscratch swap trick: */ - ld tp, TF_TP(tp) - - /* sscratch already holds TrapFrame address (set above with csrw) */ - - /* Step 6: sret — return to user mode */ - sret |
