xref: /DragonOS/kernel/src/arch/riscv64/interrupt/mod.rs (revision 5c4224e5a8244cb0fb32512e70354362fccd6321)
1*5c4224e5SLoGin use riscv::register::{scause::Scause, sstatus::Sstatus};
2f2022a8aSLoGin use system_error::SystemError;
3f2022a8aSLoGin 
4338f6903SLoGin use crate::{
5338f6903SLoGin     driver::irqchip::riscv_intc::riscv_intc_init,
6338f6903SLoGin     exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber},
7*5c4224e5SLoGin     libs::align::align_up,
8338f6903SLoGin };
94fda81ceSLoGin 
10*5c4224e5SLoGin use super::cpu::STACK_ALIGN;
11*5c4224e5SLoGin 
12*5c4224e5SLoGin pub(super) mod entry;
13*5c4224e5SLoGin mod handle;
144fda81ceSLoGin pub mod ipi;
154fda81ceSLoGin 
164fda81ceSLoGin pub struct RiscV64InterruptArch;
174fda81ceSLoGin 
184fda81ceSLoGin impl InterruptArch for RiscV64InterruptArch {
19f2022a8aSLoGin     unsafe fn arch_irq_init() -> Result<(), SystemError> {
20338f6903SLoGin         riscv_intc_init()?;
21338f6903SLoGin 
22338f6903SLoGin         Ok(())
23f2022a8aSLoGin     }
244fda81ceSLoGin     unsafe fn interrupt_enable() {
257a29d4fcSLoGin         riscv::interrupt::enable();
264fda81ceSLoGin     }
274fda81ceSLoGin 
284fda81ceSLoGin     unsafe fn interrupt_disable() {
297a29d4fcSLoGin         riscv::interrupt::disable();
304fda81ceSLoGin     }
314fda81ceSLoGin 
324fda81ceSLoGin     fn is_irq_enabled() -> bool {
337a29d4fcSLoGin         riscv::register::sstatus::read().sie()
344fda81ceSLoGin     }
354fda81ceSLoGin 
364fda81ceSLoGin     unsafe fn save_and_disable_irq() -> IrqFlagsGuard {
377a29d4fcSLoGin         let sie = riscv::register::sstatus::read().sie();
387a29d4fcSLoGin         IrqFlagsGuard::new(IrqFlags::new(sie.into()))
394fda81ceSLoGin     }
404fda81ceSLoGin 
414fda81ceSLoGin     unsafe fn restore_irq(flags: IrqFlags) {
427a29d4fcSLoGin         let sie: bool = flags.flags() != 0;
437a29d4fcSLoGin         if sie {
447a29d4fcSLoGin             riscv::register::sstatus::set_sie();
457a29d4fcSLoGin         } else {
467a29d4fcSLoGin             riscv::register::sstatus::clear_sie();
477a29d4fcSLoGin         }
484fda81ceSLoGin     }
493bc96fa4SLoGin 
503bc96fa4SLoGin     fn probe_total_irq_num() -> u32 {
513bc96fa4SLoGin         // todo: 获取中断总数
523bc96fa4SLoGin         256
533bc96fa4SLoGin     }
543bc96fa4SLoGin 
553bc96fa4SLoGin     fn ack_bad_irq(irq: IrqNumber) {
563bc96fa4SLoGin         todo!("ack_bad_irq: {}", irq.data());
573bc96fa4SLoGin     }
584fda81ceSLoGin }
594fda81ceSLoGin 
604fda81ceSLoGin /// 中断栈帧结构体
614fda81ceSLoGin #[repr(C)]
624fda81ceSLoGin #[derive(Debug, Copy, Clone)]
634fda81ceSLoGin pub struct TrapFrame {
64*5c4224e5SLoGin     epc: usize,
65*5c4224e5SLoGin     ra: usize,
66*5c4224e5SLoGin     sp: usize,
67*5c4224e5SLoGin     gp: usize,
68*5c4224e5SLoGin     tp: usize,
69*5c4224e5SLoGin     t0: usize,
70*5c4224e5SLoGin     t1: usize,
71*5c4224e5SLoGin     t2: usize,
72*5c4224e5SLoGin     s0: usize,
73*5c4224e5SLoGin     s1: usize,
74*5c4224e5SLoGin     a0: usize,
75*5c4224e5SLoGin     a1: usize,
76*5c4224e5SLoGin     a2: usize,
77*5c4224e5SLoGin     a3: usize,
78*5c4224e5SLoGin     a4: usize,
79*5c4224e5SLoGin     a5: usize,
80*5c4224e5SLoGin     a6: usize,
81*5c4224e5SLoGin     a7: usize,
82*5c4224e5SLoGin     s2: usize,
83*5c4224e5SLoGin     s3: usize,
84*5c4224e5SLoGin     s4: usize,
85*5c4224e5SLoGin     s5: usize,
86*5c4224e5SLoGin     s6: usize,
87*5c4224e5SLoGin     s7: usize,
88*5c4224e5SLoGin     s8: usize,
89*5c4224e5SLoGin     s9: usize,
90*5c4224e5SLoGin     s10: usize,
91*5c4224e5SLoGin     s11: usize,
92*5c4224e5SLoGin     t3: usize,
93*5c4224e5SLoGin     t4: usize,
94*5c4224e5SLoGin     t5: usize,
95*5c4224e5SLoGin     t6: usize,
96*5c4224e5SLoGin     // 以下是中断发生时自动保存的寄存器
97*5c4224e5SLoGin     status: Sstatus,
98*5c4224e5SLoGin     badaddr: usize,
99*5c4224e5SLoGin     cause: Scause,
100*5c4224e5SLoGin     /// a0 value before the syscall
101*5c4224e5SLoGin     origin_a0: usize,
1024fda81ceSLoGin }
1034fda81ceSLoGin 
1044fda81ceSLoGin impl TrapFrame {
105*5c4224e5SLoGin     /// 中断栈帧结构体的大小
106*5c4224e5SLoGin     pub const SIZE: usize = core::mem::size_of::<TrapFrame>();
107*5c4224e5SLoGin 
108*5c4224e5SLoGin     /// 中断栈帧在栈上的大小
109*5c4224e5SLoGin     pub const SIZE_ON_STACK: usize = align_up(Self::SIZE, STACK_ALIGN);
1104fda81ceSLoGin     /// 判断当前中断是否来自用户模式
1114fda81ceSLoGin     pub fn from_user(&self) -> bool {
112*5c4224e5SLoGin         self.status.spp() == riscv::register::sstatus::SPP::User
1134fda81ceSLoGin     }
1144fda81ceSLoGin }
115