Basic trap handler

master
WangRunji 7 years ago
parent 4c1137a107
commit da6dd763d7

@ -0,0 +1,104 @@
.macro SAVE_ALL
# store sp in sscratch
csrw sscratch, sp
# provide room for trap frame
addi sp, sp, -36 * 4
# save x registers except x2 (sp)
sw x1, 1*4(sp)
sw x3, 3*4(sp)
sw x4, 4*4(sp)
sw x5, 5*4(sp)
sw x6, 6*4(sp)
sw x7, 7*4(sp)
sw x8, 8*4(sp)
sw x9, 9*4(sp)
sw x10, 10*4(sp)
sw x11, 11*4(sp)
sw x12, 12*4(sp)
sw x13, 13*4(sp)
sw x14, 14*4(sp)
sw x15, 15*4(sp)
sw x16, 16*4(sp)
sw x17, 17*4(sp)
sw x18, 18*4(sp)
sw x19, 19*4(sp)
sw x20, 20*4(sp)
sw x21, 21*4(sp)
sw x22, 22*4(sp)
sw x23, 23*4(sp)
sw x24, 24*4(sp)
sw x25, 25*4(sp)
sw x26, 26*4(sp)
sw x27, 27*4(sp)
sw x28, 28*4(sp)
sw x29, 29*4(sp)
sw x30, 30*4(sp)
sw x31, 31*4(sp)
# get sp, sstatus, sepc, sbadvaddr, scause
csrr s0, sscratch
csrr s1, sstatus
csrr s2, sepc
csrr s3, sbadaddr
csrr s4, scause
# store sp, sstatus, sepc, sbadvaddr, scause
sw s0, 2*4(sp)
sw s1, 32*4(sp)
sw s2, 33*4(sp)
sw s3, 34*4(sp)
sw s4, 35*4(sp)
.endm
.macro RESTORE_ALL
# sstatus and sepc may be changed in ISR
lw s1, 32*4(sp)
lw s2, 33*4(sp)
csrw sstatus, s1
csrw sepc, s2
# restore x registers except x2 (sp)
lw x1, 1*4(sp)
lw x3, 3*4(sp)
lw x4, 4*4(sp)
lw x5, 5*4(sp)
lw x6, 6*4(sp)
lw x7, 7*4(sp)
lw x8, 8*4(sp)
lw x9, 9*4(sp)
lw x10, 10*4(sp)
lw x11, 11*4(sp)
lw x12, 12*4(sp)
lw x13, 13*4(sp)
lw x14, 14*4(sp)
lw x15, 15*4(sp)
lw x16, 16*4(sp)
lw x17, 17*4(sp)
lw x18, 18*4(sp)
lw x19, 19*4(sp)
lw x20, 20*4(sp)
lw x21, 21*4(sp)
lw x22, 22*4(sp)
lw x23, 23*4(sp)
lw x24, 24*4(sp)
lw x25, 25*4(sp)
lw x26, 26*4(sp)
lw x27, 27*4(sp)
lw x28, 28*4(sp)
lw x29, 29*4(sp)
lw x30, 30*4(sp)
lw x31, 31*4(sp)
# restore sp last
lw x2, 2*4(sp)
.endm
.section .text
.globl __alltraps
__alltraps:
SAVE_ALL
move a0, sp
jal rust_trap
.globl __trapret
__trapret:
RESTORE_ALL
# return from supervisor call
sret

@ -0,0 +1,30 @@
use super::riscv::register::*;
pub fn init() {
unsafe {
// Set the exception vector address
stvec::write(__alltraps as usize, stvec::TrapMode::Direct);
// Enable interrupt
sstatus::set_sie();
}
}
#[no_mangle]
pub extern fn rust_trap(tf: &mut TrapFrame) {
println!("Trap:\n{:#x?}", tf);
loop {}
}
#[derive(Debug, Clone)]
#[repr(C)]
pub struct TrapFrame {
x: [usize; 32],
sstatus: sstatus::Sstatus,
sepc: usize,
sbadaddr: usize,
scause: scause::Scause,
}
extern {
fn __alltraps();
}

@ -2,7 +2,12 @@ extern crate riscv;
extern crate bbl; extern crate bbl;
pub mod serial; pub mod serial;
pub mod interrupt;
pub fn test() { pub fn init() {
println!("Hello RISCV! {}", 123); println!("Hello RISCV! {}", 123);
interrupt::init();
// Trigger interrupt
unsafe { asm!("mret"); }
loop {}
} }

@ -60,8 +60,9 @@ extern crate x86_64;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
extern crate xmas_elf; extern crate xmas_elf;
pub use arch::interrupt::rust_trap;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub use arch::interrupt::{rust_trap, set_return_rsp}; pub use arch::interrupt::set_return_rsp;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use linked_list_allocator::LockedHeap; use linked_list_allocator::LockedHeap;
@ -106,7 +107,7 @@ mod arch;
#[no_mangle] #[no_mangle]
#[cfg(target_arch = "riscv")] #[cfg(target_arch = "riscv")]
pub extern fn rust_main() -> ! { pub extern fn rust_main() -> ! {
arch::test(); arch::init();
loop {} loop {}
} }

Loading…
Cancel
Save