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 pub epc: usize, 65 pub ra: usize, 66 pub sp: usize, 67 pub gp: usize, 68 pub tp: usize, 69 pub t0: usize, 70 pub t1: usize, 71 pub t2: usize, 72 pub s0: usize, 73 pub s1: usize, 74 pub a0: usize, 75 pub a1: usize, 76 pub a2: usize, 77 pub a3: usize, 78 pub a4: usize, 79 pub a5: usize, 80 pub a6: usize, 81 pub a7: usize, 82 pub s2: usize, 83 pub s3: usize, 84 pub s4: usize, 85 pub s5: usize, 86 pub s6: usize, 87 pub s7: usize, 88 pub s8: usize, 89 pub s9: usize, 90 pub s10: usize, 91 pub s11: usize, 92 pub t3: usize, 93 pub t4: usize, 94 pub t5: usize, 95 pub t6: usize, 96 // 以下是中断发生时自动保存的寄存器 97 pub status: Sstatus, 98 pub badaddr: usize, 99 pub cause: Scause, 100 /// a0 value before the syscall 101 pub 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 is_from_user(&self) -> bool { 112 self.status.spp() == riscv::register::sstatus::SPP::User 113 } 114 } 115