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