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