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:
190
crates/adapter-riscv/src/trap/mod.rs
Normal file
190
crates/adapter-riscv/src/trap/mod.rs
Normal 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") }; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user