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