15c4224e5SLoGin 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}, 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> { 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(); 38*9621ab16SLoGin riscv::register::sstatus::clear_sie(); 397a29d4fcSLoGin IrqFlagsGuard::new(IrqFlags::new(sie.into())) 404fda81ceSLoGin } 414fda81ceSLoGin 424fda81ceSLoGin unsafe fn restore_irq(flags: IrqFlags) { 437a29d4fcSLoGin let sie: bool = flags.flags() != 0; 447a29d4fcSLoGin if sie { 457a29d4fcSLoGin riscv::register::sstatus::set_sie(); 467a29d4fcSLoGin } else { 477a29d4fcSLoGin riscv::register::sstatus::clear_sie(); 487a29d4fcSLoGin } 494fda81ceSLoGin } 503bc96fa4SLoGin 513bc96fa4SLoGin fn probe_total_irq_num() -> u32 { 523bc96fa4SLoGin // todo: 获取中断总数 533bc96fa4SLoGin 256 543bc96fa4SLoGin } 553bc96fa4SLoGin 563bc96fa4SLoGin fn ack_bad_irq(irq: IrqNumber) { 573bc96fa4SLoGin todo!("ack_bad_irq: {}", irq.data()); 583bc96fa4SLoGin } 594fda81ceSLoGin } 604fda81ceSLoGin 614fda81ceSLoGin /// 中断栈帧结构体 624fda81ceSLoGin #[repr(C)] 634fda81ceSLoGin #[derive(Debug, Copy, Clone)] 644fda81ceSLoGin pub struct TrapFrame { 659b96c5b5SLoGin pub epc: usize, 669b96c5b5SLoGin pub ra: usize, 679b96c5b5SLoGin pub sp: usize, 689b96c5b5SLoGin pub gp: usize, 699b96c5b5SLoGin pub tp: usize, 709b96c5b5SLoGin pub t0: usize, 719b96c5b5SLoGin pub t1: usize, 729b96c5b5SLoGin pub t2: usize, 739b96c5b5SLoGin pub s0: usize, 749b96c5b5SLoGin pub s1: usize, 759b96c5b5SLoGin pub a0: usize, 769b96c5b5SLoGin pub a1: usize, 779b96c5b5SLoGin pub a2: usize, 789b96c5b5SLoGin pub a3: usize, 799b96c5b5SLoGin pub a4: usize, 809b96c5b5SLoGin pub a5: usize, 819b96c5b5SLoGin pub a6: usize, 829b96c5b5SLoGin pub a7: usize, 839b96c5b5SLoGin pub s2: usize, 849b96c5b5SLoGin pub s3: usize, 859b96c5b5SLoGin pub s4: usize, 869b96c5b5SLoGin pub s5: usize, 879b96c5b5SLoGin pub s6: usize, 889b96c5b5SLoGin pub s7: usize, 899b96c5b5SLoGin pub s8: usize, 909b96c5b5SLoGin pub s9: usize, 919b96c5b5SLoGin pub s10: usize, 929b96c5b5SLoGin pub s11: usize, 939b96c5b5SLoGin pub t3: usize, 949b96c5b5SLoGin pub t4: usize, 959b96c5b5SLoGin pub t5: usize, 969b96c5b5SLoGin pub t6: usize, 975c4224e5SLoGin // 以下是中断发生时自动保存的寄存器 989b96c5b5SLoGin pub status: Sstatus, 999b96c5b5SLoGin pub badaddr: usize, 1009b96c5b5SLoGin pub cause: Scause, 1015c4224e5SLoGin /// a0 value before the syscall 1029b96c5b5SLoGin pub origin_a0: usize, 1034fda81ceSLoGin } 1044fda81ceSLoGin 1054fda81ceSLoGin impl TrapFrame { 1065c4224e5SLoGin /// 中断栈帧结构体的大小 1075c4224e5SLoGin pub const SIZE: usize = core::mem::size_of::<TrapFrame>(); 1085c4224e5SLoGin 1095c4224e5SLoGin /// 中断栈帧在栈上的大小 1105c4224e5SLoGin pub const SIZE_ON_STACK: usize = align_up(Self::SIZE, STACK_ALIGN); 1114fda81ceSLoGin /// 判断当前中断是否来自用户模式 112b5b571e0SLoGin pub fn is_from_user(&self) -> bool { 1135c4224e5SLoGin self.status.spp() == riscv::register::sstatus::SPP::User 1144fda81ceSLoGin } 115e8eab1acSLoGin 116e8eab1acSLoGin pub fn new() -> Self { 117e8eab1acSLoGin Self { 118e8eab1acSLoGin epc: 0, 119e8eab1acSLoGin ra: 0, 120e8eab1acSLoGin sp: 0, 121e8eab1acSLoGin gp: 0, 122e8eab1acSLoGin tp: 0, 123e8eab1acSLoGin t0: 0, 124e8eab1acSLoGin t1: 0, 125e8eab1acSLoGin t2: 0, 126e8eab1acSLoGin s0: 0, 127e8eab1acSLoGin s1: 0, 128e8eab1acSLoGin a0: 0, 129e8eab1acSLoGin a1: 0, 130e8eab1acSLoGin a2: 0, 131e8eab1acSLoGin a3: 0, 132e8eab1acSLoGin a4: 0, 133e8eab1acSLoGin a5: 0, 134e8eab1acSLoGin a6: 0, 135e8eab1acSLoGin a7: 0, 136e8eab1acSLoGin s2: 0, 137e8eab1acSLoGin s3: 0, 138e8eab1acSLoGin s4: 0, 139e8eab1acSLoGin s5: 0, 140e8eab1acSLoGin s6: 0, 141e8eab1acSLoGin s7: 0, 142e8eab1acSLoGin s8: 0, 143e8eab1acSLoGin s9: 0, 144e8eab1acSLoGin s10: 0, 145e8eab1acSLoGin s11: 0, 146e8eab1acSLoGin t3: 0, 147e8eab1acSLoGin t4: 0, 148e8eab1acSLoGin t5: 0, 149e8eab1acSLoGin t6: 0, 150e8eab1acSLoGin status: unsafe { core::mem::zeroed() }, 151e8eab1acSLoGin badaddr: 0, 152e8eab1acSLoGin cause: unsafe { core::mem::zeroed() }, 153e8eab1acSLoGin origin_a0: 0, 154e8eab1acSLoGin } 155e8eab1acSLoGin } 156e8eab1acSLoGin 157e8eab1acSLoGin pub fn set_return_value(&mut self, value: usize) { 158e8eab1acSLoGin self.a0 = value; 159e8eab1acSLoGin } 1604fda81ceSLoGin } 161