refactor(adapter-riscv): restructure into hw/, mmu/, trap/ modules with board constants

Add Priority::DEFAULT and TimeSlice::DEFAULT to types crate.
All QEMU virt addresses consolidated in board.rs.
Structure mirrors future adapter-arm/ layout.
This commit is contained in:
2026-10-18 02:05:57 +02:00
parent 66a730b2fe
commit d327794d33
13 changed files with 100 additions and 109 deletions

View File

@@ -0,0 +1,190 @@
use core::arch::global_asm;
#[repr(C)]
pub struct TrapFrame {
pub regs: [usize; 32],
pub sepc: usize,
pub sstatus: usize,
}
impl TrapFrame {
pub fn new() -> Self {
Self {
regs: [0; 32],
sepc: 0,
sstatus: 0,
}
}
}
// sscratch = 0 when in S-mode, = kernel_stack_top when in U-mode.
// On trap: swap sp/sscratch. If sp==0 after swap, we came from S-mode (undo swap).
global_asm!(r#"
.align 4
.globl trap_vector
trap_vector:
csrrw sp, sscratch, sp
bnez sp, _from_user
csrrw sp, sscratch, sp
_from_user:
addi sp, sp, -272
sd x1, 8(sp)
sd x3, 24(sp)
sd x4, 32(sp)
sd x5, 40(sp)
sd x6, 48(sp)
sd x7, 56(sp)
sd x8, 64(sp)
sd x9, 72(sp)
sd x10, 80(sp)
sd x11, 88(sp)
sd x12, 96(sp)
sd x13, 104(sp)
sd x14, 112(sp)
sd x15, 120(sp)
sd x16, 128(sp)
sd x17, 136(sp)
sd x18, 144(sp)
sd x19, 152(sp)
sd x20, 160(sp)
sd x21, 168(sp)
sd x22, 176(sp)
sd x23, 184(sp)
sd x24, 192(sp)
sd x25, 200(sp)
sd x26, 208(sp)
sd x27, 216(sp)
sd x28, 224(sp)
sd x29, 232(sp)
sd x30, 240(sp)
sd x31, 248(sp)
csrr t0, sscratch
sd t0, 16(sp)
csrr t0, sepc
sd t0, 256(sp)
csrr t0, sstatus
sd t0, 264(sp)
mv a0, sp
call trap_handler_rust
ld t0, 256(sp)
csrw sepc, t0
ld t0, 264(sp)
csrw sstatus, t0
andi t1, t0, 0x100
bnez t1, _restore_smode
ld t0, 16(sp)
csrw sscratch, t0
_restore_smode:
ld x1, 8(sp)
ld x3, 24(sp)
ld x4, 32(sp)
ld x5, 40(sp)
ld x6, 48(sp)
ld x7, 56(sp)
ld x8, 64(sp)
ld x9, 72(sp)
ld x10, 80(sp)
ld x11, 88(sp)
ld x12, 96(sp)
ld x13, 104(sp)
ld x14, 112(sp)
ld x15, 120(sp)
ld x16, 128(sp)
ld x17, 136(sp)
ld x18, 144(sp)
ld x19, 152(sp)
ld x20, 160(sp)
ld x21, 168(sp)
ld x22, 176(sp)
ld x23, 184(sp)
ld x24, 192(sp)
ld x25, 200(sp)
ld x26, 208(sp)
ld x27, 216(sp)
ld x28, 224(sp)
ld x29, 232(sp)
ld x30, 240(sp)
ld x31, 248(sp)
addi sp, sp, 272
csrr t0, sstatus
andi t0, t0, 0x100
bnez t0, _sret_smode
csrrw sp, sscratch, sp
_sret_smode:
sret
"#);
const CAUSE_INTERRUPT_BIT: usize = 1 << 63;
const CAUSE_S_TIMER: usize = 5;
const CAUSE_S_EXTERNAL: usize = 9;
const CAUSE_ECALL_U: usize = 8;
pub fn init() {
unsafe extern "C" {
fn trap_vector();
}
unsafe {
let addr = trap_vector as usize;
core::arch::asm!("csrw stvec, {0}", in(reg) addr);
core::arch::asm!("csrw sscratch, zero");
core::arch::asm!("csrs sstatus, {0}", in(reg) 1usize << 1);
let sie_bits = (1usize << 5) | (1usize << 9) | (1usize << 1);
core::arch::asm!("csrs sie, {0}", in(reg) sie_bits);
}
}
pub fn set_kernel_stack(kernel_sp: usize) {
unsafe {
core::arch::asm!("csrw sscratch, {0}", in(reg) kernel_sp);
}
}
#[unsafe(no_mangle)]
extern "C" fn trap_handler_rust(frame: &mut TrapFrame) {
let scause: usize;
unsafe { core::arch::asm!("csrr {0}, scause", out(reg) scause) };
let uart = crate::hw::uart::Uart::new();
if scause & CAUSE_INTERRUPT_BIT != 0 {
let cause = scause & !CAUSE_INTERRUPT_BIT;
match cause {
CAUSE_S_TIMER => {
crate::hw::timer::handle_interrupt();
}
CAUSE_S_EXTERNAL => {
uart.write_str("[EXT]");
}
_ => {}
}
} else {
match scause {
CAUSE_ECALL_U => {
frame.sepc += 4;
uart.write_str("[ecall]\n");
}
_ => {
uart.write_str("FAULT: scause=");
uart.write_hex(scause);
let stval: usize;
unsafe { core::arch::asm!("csrr {0}, stval", out(reg) stval) };
uart.write_str(" stval=");
uart.write_hex(stval);
uart.write_str(" sepc=");
uart.write_hex(frame.sepc);
uart.put_char(b'\n');
loop { unsafe { core::arch::asm!("wfi") }; }
}
}
}
}