1 use riscv::register::{scause::Scause, sstatus::Sstatus}; 2 use system_error::SystemError; 3 4 use crate::{ 5 driver::irqchip::riscv_intc::riscv_intc_init, 6 exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber}, 7 libs::align::align_up, 8 }; 9 10 use super::cpu::STACK_ALIGN; 11 12 pub(super) mod entry; 13 mod handle; 14 pub mod ipi; 15 16 pub struct RiscV64InterruptArch; 17 18 impl InterruptArch for RiscV64InterruptArch { 19 unsafe fn arch_irq_init() -> Result<(), SystemError> { 20 riscv_intc_init()?; 21 22 Ok(()) 23 } 24 unsafe fn interrupt_enable() { 25 riscv::interrupt::enable(); 26 } 27 28 unsafe fn interrupt_disable() { 29 riscv::interrupt::disable(); 30 } 31 32 fn is_irq_enabled() -> bool { 33 riscv::register::sstatus::read().sie() 34 } 35 36 unsafe fn save_and_disable_irq() -> IrqFlagsGuard { 37 let sie = riscv::register::sstatus::read().sie(); 38 IrqFlagsGuard::new(IrqFlags::new(sie.into())) 39 } 40 41 unsafe fn restore_irq(flags: IrqFlags) { 42 let sie: bool = flags.flags() != 0; 43 if sie { 44 riscv::register::sstatus::set_sie(); 45 } else { 46 riscv::register::sstatus::clear_sie(); 47 } 48 } 49 50 fn probe_total_irq_num() -> u32 { 51 // todo: 获取中断总数 52 256 53 } 54 55 fn ack_bad_irq(irq: IrqNumber) { 56 todo!("ack_bad_irq: {}", irq.data()); 57 } 58 } 59 60 /// 中断栈帧结构体 61 #[repr(C)] 62 #[derive(Debug, Copy, Clone)] 63 pub struct TrapFrame { 64 epc: usize, 65 ra: usize, 66 sp: usize, 67 gp: usize, 68 tp: usize, 69 t0: usize, 70 t1: usize, 71 t2: usize, 72 s0: usize, 73 s1: usize, 74 a0: usize, 75 a1: usize, 76 a2: usize, 77 a3: usize, 78 a4: usize, 79 a5: usize, 80 a6: usize, 81 a7: usize, 82 s2: usize, 83 s3: usize, 84 s4: usize, 85 s5: usize, 86 s6: usize, 87 s7: usize, 88 s8: usize, 89 s9: usize, 90 s10: usize, 91 s11: usize, 92 t3: usize, 93 t4: usize, 94 t5: usize, 95 t6: usize, 96 // 以下是中断发生时自动保存的寄存器 97 status: Sstatus, 98 badaddr: usize, 99 cause: Scause, 100 /// a0 value before the syscall 101 origin_a0: usize, 102 } 103 104 impl TrapFrame { 105 /// 中断栈帧结构体的大小 106 pub const SIZE: usize = core::mem::size_of::<TrapFrame>(); 107 108 /// 中断栈帧在栈上的大小 109 pub const SIZE_ON_STACK: usize = align_up(Self::SIZE, STACK_ALIGN); 110 /// 判断当前中断是否来自用户模式 111 pub fn from_user(&self) -> bool { 112 self.status.spp() == riscv::register::sstatus::SPP::User 113 } 114 } 115