15c4224e5SLoGin use riscv::register::{scause::Scause, sstatus::Sstatus}; 2f2022a8aSLoGin use system_error::SystemError; 3f2022a8aSLoGin 4338f6903SLoGin use crate::{ 5*0102d69fSLoGin driver::irqchip::{riscv_intc::riscv_intc_init, riscv_sifive_plic::riscv_sifive_plic_init}, 6338f6903SLoGin exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber}, 75c4224e5SLoGin libs::align::align_up, 8338f6903SLoGin }; 94fda81ceSLoGin 105c4224e5SLoGin use super::cpu::STACK_ALIGN; 115c4224e5SLoGin 125c4224e5SLoGin pub(super) mod entry; 135c4224e5SLoGin 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> { 20*0102d69fSLoGin Self::interrupt_disable(); 21*0102d69fSLoGin riscv_sifive_plic_init()?; 22*0102d69fSLoGin // 注意,intc的初始化必须在plic之后,不然会导致plic无法关联上中断 23338f6903SLoGin riscv_intc_init()?; 24338f6903SLoGin 25338f6903SLoGin Ok(()) 26f2022a8aSLoGin } 274fda81ceSLoGin unsafe fn interrupt_enable() { 287a29d4fcSLoGin riscv::interrupt::enable(); 294fda81ceSLoGin } 304fda81ceSLoGin 314fda81ceSLoGin unsafe fn interrupt_disable() { 327a29d4fcSLoGin riscv::interrupt::disable(); 334fda81ceSLoGin } 344fda81ceSLoGin 354fda81ceSLoGin fn is_irq_enabled() -> bool { 367a29d4fcSLoGin riscv::register::sstatus::read().sie() 374fda81ceSLoGin } 384fda81ceSLoGin 394fda81ceSLoGin unsafe fn save_and_disable_irq() -> IrqFlagsGuard { 407a29d4fcSLoGin let sie = riscv::register::sstatus::read().sie(); 419621ab16SLoGin riscv::register::sstatus::clear_sie(); 427a29d4fcSLoGin IrqFlagsGuard::new(IrqFlags::new(sie.into())) 434fda81ceSLoGin } 444fda81ceSLoGin 454fda81ceSLoGin unsafe fn restore_irq(flags: IrqFlags) { 467a29d4fcSLoGin let sie: bool = flags.flags() != 0; 477a29d4fcSLoGin if sie { 487a29d4fcSLoGin riscv::register::sstatus::set_sie(); 497a29d4fcSLoGin } else { 507a29d4fcSLoGin riscv::register::sstatus::clear_sie(); 517a29d4fcSLoGin } 524fda81ceSLoGin } 533bc96fa4SLoGin 543bc96fa4SLoGin fn probe_total_irq_num() -> u32 { 553bc96fa4SLoGin // todo: 获取中断总数 563bc96fa4SLoGin 256 573bc96fa4SLoGin } 583bc96fa4SLoGin 593bc96fa4SLoGin fn ack_bad_irq(irq: IrqNumber) { 603bc96fa4SLoGin todo!("ack_bad_irq: {}", irq.data()); 613bc96fa4SLoGin } 624fda81ceSLoGin } 634fda81ceSLoGin 644fda81ceSLoGin /// 中断栈帧结构体 654fda81ceSLoGin #[repr(C)] 664fda81ceSLoGin #[derive(Debug, Copy, Clone)] 674fda81ceSLoGin pub struct TrapFrame { 689b96c5b5SLoGin pub epc: usize, 699b96c5b5SLoGin pub ra: usize, 709b96c5b5SLoGin pub sp: usize, 719b96c5b5SLoGin pub gp: usize, 729b96c5b5SLoGin pub tp: usize, 739b96c5b5SLoGin pub t0: usize, 749b96c5b5SLoGin pub t1: usize, 759b96c5b5SLoGin pub t2: usize, 769b96c5b5SLoGin pub s0: usize, 779b96c5b5SLoGin pub s1: usize, 789b96c5b5SLoGin pub a0: usize, 799b96c5b5SLoGin pub a1: usize, 809b96c5b5SLoGin pub a2: usize, 819b96c5b5SLoGin pub a3: usize, 829b96c5b5SLoGin pub a4: usize, 839b96c5b5SLoGin pub a5: usize, 849b96c5b5SLoGin pub a6: usize, 859b96c5b5SLoGin pub a7: usize, 869b96c5b5SLoGin pub s2: usize, 879b96c5b5SLoGin pub s3: usize, 889b96c5b5SLoGin pub s4: usize, 899b96c5b5SLoGin pub s5: usize, 909b96c5b5SLoGin pub s6: usize, 919b96c5b5SLoGin pub s7: usize, 929b96c5b5SLoGin pub s8: usize, 939b96c5b5SLoGin pub s9: usize, 949b96c5b5SLoGin pub s10: usize, 959b96c5b5SLoGin pub s11: usize, 969b96c5b5SLoGin pub t3: usize, 979b96c5b5SLoGin pub t4: usize, 989b96c5b5SLoGin pub t5: usize, 999b96c5b5SLoGin pub t6: usize, 1005c4224e5SLoGin // 以下是中断发生时自动保存的寄存器 1019b96c5b5SLoGin pub status: Sstatus, 1029b96c5b5SLoGin pub badaddr: usize, 1039b96c5b5SLoGin pub cause: Scause, 1045c4224e5SLoGin /// a0 value before the syscall 1059b96c5b5SLoGin pub origin_a0: usize, 1064fda81ceSLoGin } 1074fda81ceSLoGin 1084fda81ceSLoGin impl TrapFrame { 1095c4224e5SLoGin /// 中断栈帧结构体的大小 1105c4224e5SLoGin pub const SIZE: usize = core::mem::size_of::<TrapFrame>(); 1115c4224e5SLoGin 1125c4224e5SLoGin /// 中断栈帧在栈上的大小 1135c4224e5SLoGin pub const SIZE_ON_STACK: usize = align_up(Self::SIZE, STACK_ALIGN); 1144fda81ceSLoGin /// 判断当前中断是否来自用户模式 115b5b571e0SLoGin pub fn is_from_user(&self) -> bool { 1165c4224e5SLoGin self.status.spp() == riscv::register::sstatus::SPP::User 1174fda81ceSLoGin } 118e8eab1acSLoGin 119e8eab1acSLoGin pub fn new() -> Self { 120e8eab1acSLoGin Self { 121e8eab1acSLoGin epc: 0, 122e8eab1acSLoGin ra: 0, 123e8eab1acSLoGin sp: 0, 124e8eab1acSLoGin gp: 0, 125e8eab1acSLoGin tp: 0, 126e8eab1acSLoGin t0: 0, 127e8eab1acSLoGin t1: 0, 128e8eab1acSLoGin t2: 0, 129e8eab1acSLoGin s0: 0, 130e8eab1acSLoGin s1: 0, 131e8eab1acSLoGin a0: 0, 132e8eab1acSLoGin a1: 0, 133e8eab1acSLoGin a2: 0, 134e8eab1acSLoGin a3: 0, 135e8eab1acSLoGin a4: 0, 136e8eab1acSLoGin a5: 0, 137e8eab1acSLoGin a6: 0, 138e8eab1acSLoGin a7: 0, 139e8eab1acSLoGin s2: 0, 140e8eab1acSLoGin s3: 0, 141e8eab1acSLoGin s4: 0, 142e8eab1acSLoGin s5: 0, 143e8eab1acSLoGin s6: 0, 144e8eab1acSLoGin s7: 0, 145e8eab1acSLoGin s8: 0, 146e8eab1acSLoGin s9: 0, 147e8eab1acSLoGin s10: 0, 148e8eab1acSLoGin s11: 0, 149e8eab1acSLoGin t3: 0, 150e8eab1acSLoGin t4: 0, 151e8eab1acSLoGin t5: 0, 152e8eab1acSLoGin t6: 0, 153e8eab1acSLoGin status: unsafe { core::mem::zeroed() }, 154e8eab1acSLoGin badaddr: 0, 155e8eab1acSLoGin cause: unsafe { core::mem::zeroed() }, 156e8eab1acSLoGin origin_a0: 0, 157e8eab1acSLoGin } 158e8eab1acSLoGin } 159e8eab1acSLoGin 160e8eab1acSLoGin pub fn set_return_value(&mut self, value: usize) { 161e8eab1acSLoGin self.a0 = value; 162e8eab1acSLoGin } 1634fda81ceSLoGin } 164