1 use core::any::Any; 2 use kprobe::ProbeArgs; 3 use riscv::register::{scause::Scause, sstatus::Sstatus}; 4 use system_error::SystemError; 5 6 use crate::{ 7 driver::irqchip::{riscv_intc::riscv_intc_init, riscv_sifive_plic::riscv_sifive_plic_init}, 8 exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber}, 9 libs::align::align_up, 10 }; 11 12 use super::cpu::STACK_ALIGN; 13 14 pub(super) mod entry; 15 mod handle; 16 pub mod ipi; 17 18 pub struct RiscV64InterruptArch; 19 20 impl InterruptArch for RiscV64InterruptArch { 21 unsafe fn arch_irq_init() -> Result<(), SystemError> { 22 Self::interrupt_disable(); 23 riscv_sifive_plic_init()?; 24 // 注意,intc的初始化必须在plic之后,不然会导致plic无法关联上中断 25 riscv_intc_init()?; 26 27 Ok(()) 28 } 29 unsafe fn interrupt_enable() { 30 riscv::interrupt::enable(); 31 } 32 33 unsafe fn interrupt_disable() { 34 riscv::interrupt::disable(); 35 } 36 37 fn is_irq_enabled() -> bool { 38 riscv::register::sstatus::read().sie() 39 } 40 41 unsafe fn save_and_disable_irq() -> IrqFlagsGuard { 42 let sie = riscv::register::sstatus::read().sie(); 43 riscv::register::sstatus::clear_sie(); 44 IrqFlagsGuard::new(IrqFlags::new(sie.into())) 45 } 46 47 unsafe fn restore_irq(flags: IrqFlags) { 48 let sie: bool = flags.flags() != 0; 49 if sie { 50 riscv::register::sstatus::set_sie(); 51 } else { 52 riscv::register::sstatus::clear_sie(); 53 } 54 } 55 56 fn probe_total_irq_num() -> u32 { 57 // todo: 获取中断总数 58 256 59 } 60 61 fn ack_bad_irq(irq: IrqNumber) { 62 todo!("ack_bad_irq: {}", irq.data()); 63 } 64 } 65 66 /// 中断栈帧结构体 67 #[repr(C)] 68 #[derive(Debug, Copy, Clone)] 69 pub struct TrapFrame { 70 pub epc: usize, 71 pub ra: usize, 72 pub sp: usize, 73 pub gp: usize, 74 pub tp: usize, 75 pub t0: usize, 76 pub t1: usize, 77 pub t2: usize, 78 pub s0: usize, 79 pub s1: usize, 80 pub a0: usize, 81 pub a1: usize, 82 pub a2: usize, 83 pub a3: usize, 84 pub a4: usize, 85 pub a5: usize, 86 pub a6: usize, 87 pub a7: usize, 88 pub s2: usize, 89 pub s3: usize, 90 pub s4: usize, 91 pub s5: usize, 92 pub s6: usize, 93 pub s7: usize, 94 pub s8: usize, 95 pub s9: usize, 96 pub s10: usize, 97 pub s11: usize, 98 pub t3: usize, 99 pub t4: usize, 100 pub t5: usize, 101 pub t6: usize, 102 // 以下是中断发生时自动保存的寄存器 103 pub status: Sstatus, 104 pub badaddr: usize, 105 pub cause: Scause, 106 /// a0 value before the syscall 107 pub origin_a0: usize, 108 } 109 110 impl TrapFrame { 111 /// 中断栈帧结构体的大小 112 pub const SIZE: usize = core::mem::size_of::<TrapFrame>(); 113 114 /// 中断栈帧在栈上的大小 115 pub const SIZE_ON_STACK: usize = align_up(Self::SIZE, STACK_ALIGN); 116 /// 判断当前中断是否来自用户模式 117 pub fn is_from_user(&self) -> bool { 118 self.status.spp() == riscv::register::sstatus::SPP::User 119 } 120 121 pub fn new() -> Self { 122 Self { 123 epc: 0, 124 ra: 0, 125 sp: 0, 126 gp: 0, 127 tp: 0, 128 t0: 0, 129 t1: 0, 130 t2: 0, 131 s0: 0, 132 s1: 0, 133 a0: 0, 134 a1: 0, 135 a2: 0, 136 a3: 0, 137 a4: 0, 138 a5: 0, 139 a6: 0, 140 a7: 0, 141 s2: 0, 142 s3: 0, 143 s4: 0, 144 s5: 0, 145 s6: 0, 146 s7: 0, 147 s8: 0, 148 s9: 0, 149 s10: 0, 150 s11: 0, 151 t3: 0, 152 t4: 0, 153 t5: 0, 154 t6: 0, 155 status: unsafe { core::mem::zeroed() }, 156 badaddr: 0, 157 cause: unsafe { core::mem::zeroed() }, 158 origin_a0: 0, 159 } 160 } 161 162 pub fn set_return_value(&mut self, value: usize) { 163 self.a0 = value; 164 } 165 166 /// 设置当前的程序计数器 167 pub fn set_pc(&mut self, pc: usize) { 168 self.epc = pc; 169 } 170 } 171 172 impl ProbeArgs for TrapFrame { 173 fn as_any(&self) -> &dyn Any { 174 self 175 } 176 fn break_address(&self) -> usize { 177 self.epc 178 } 179 fn debug_address(&self) -> usize { 180 self.epc 181 } 182 } 183