diff --git a/ostd/src/arch/riscv/irq/chip/mod.rs b/ostd/src/arch/riscv/irq/chip/mod.rs index 9d1a8b4c4..42c2fd3e5 100644 --- a/ostd/src/arch/riscv/irq/chip/mod.rs +++ b/ostd/src/arch/riscv/irq/chip/mod.rs @@ -17,7 +17,6 @@ use crate::{ boot::DEVICE_TREE, irq::{chip::plic::Plic, HwIrqLine, InterruptSource}, }, - cpu::CpuId, io::IoMemAllocatorBuilder, irq::IrqLine, sync::{LocalIrqDisabled, SpinLock}, @@ -92,9 +91,9 @@ impl IrqChip { plic.map_interrupt_source_to(interrupt_source_in_fdt.interrupt, &irq_line)?; plic.set_priority(interrupt_source_in_fdt.interrupt, 1); - // FIXME: Here we only enable external insterrupt on the BSP. We should - // enable it on APs as well when SMP is supported. - plic.set_interrupt_enabled(CpuId::bsp().into(), interrupt_source_in_fdt.interrupt, true); + plic.managed_harts().for_each(|hart| { + plic.set_interrupt_enabled(hart, interrupt_source_in_fdt.interrupt, true) + }); Ok(MappedIrqLine { irq_line, @@ -145,9 +144,8 @@ impl IrqChip { let InterruptSourceOnChip { index, interrupt } = &mapped_irq_line.interrupt_source_on_chip; let plic = &mut plics[*index]; - // FIXME: Here we only disable external insterrupt on the BSP. We should - // disable it on APs as well when SMP is supported. - plic.set_interrupt_enabled(CpuId::bsp().into(), *interrupt, false); + plic.managed_harts() + .for_each(|hart| plic.set_interrupt_enabled(hart, *interrupt, false)); plic.set_priority(*interrupt, 0); plic.unmap_interrupt_source(*interrupt); } diff --git a/ostd/src/arch/riscv/irq/chip/plic.rs b/ostd/src/arch/riscv/irq/chip/plic.rs index 976419460..fe46ac45a 100644 --- a/ostd/src/arch/riscv/irq/chip/plic.rs +++ b/ostd/src/arch/riscv/irq/chip/plic.rs @@ -108,6 +108,11 @@ impl Plic { unsafe { self.io_mem.write_once(offset, &interrupt_source) }; } + /// Gets an iterator of harts managed by this PLIC. + pub(super) fn managed_harts(&self) -> impl Iterator + use<'_> { + self.hart_to_target_mapping.keys().copied() + } + /// Initializes the PLIC. pub(super) fn init(&mut self) { // Initialize priorities of all interrupt sources to 0. @@ -115,20 +120,20 @@ impl Plic { self.set_priority(interrupt_source, 0); } - for hart in self.hart_to_target_mapping.keys() { + for hart in self.managed_harts() { // Disable all interrupt sources for all targets. for interrupt_source in 1..self.num_interrupt_sources() { - self.set_interrupt_enabled(*hart, interrupt_source, false); + self.set_interrupt_enabled(hart, interrupt_source, false); } // Set all targets' thresholds to 0 to allow all priority levels. - self.set_threshold(*hart, 0); + self.set_threshold(hart, 0); // Clear all pending claims. - while let irq_num = self.claim_interrupt(*hart) + while let irq_num = self.claim_interrupt(hart) && irq_num != 0 { - self.complete_interrupt(*hart, irq_num); + self.complete_interrupt(hart, irq_num); } } } diff --git a/ostd/src/arch/riscv/irq/mod.rs b/ostd/src/arch/riscv/irq/mod.rs index fa9e9bd8b..be70d97e6 100644 --- a/ostd/src/arch/riscv/irq/mod.rs +++ b/ostd/src/arch/riscv/irq/mod.rs @@ -12,7 +12,7 @@ pub(crate) use ipi::{send_ipi, HwCpuId}; pub(crate) use ops::{disable_local, enable_local, enable_local_and_halt, is_local_enabled}; pub(crate) use remapping::IrqRemapping; -use crate::{arch::irq::chip::InterruptSourceOnChip, cpu::CpuId}; +use crate::arch::irq::chip::InterruptSourceOnChip; pub(crate) const IRQ_NUM_MIN: u8 = 0; pub(crate) const IRQ_NUM_MAX: u8 = 255; @@ -51,7 +51,7 @@ impl HwIrqLine { InterruptSource::External(interrupt_source_on_chip) => { IRQ_CHIP.get().unwrap().complete_interrupt( // No races because we are in IRQs. - CpuId::current_racy().into(), + crate::arch::boot::smp::get_current_hart_id(), *interrupt_source_on_chip, ); } diff --git a/ostd/src/arch/riscv/trap/mod.rs b/ostd/src/arch/riscv/trap/mod.rs index cc6428509..7e2779dad 100644 --- a/ostd/src/arch/riscv/trap/mod.rs +++ b/ostd/src/arch/riscv/trap/mod.rs @@ -21,7 +21,7 @@ use crate::{ irq::{disable_local, enable_local, HwIrqLine, InterruptSource, IRQ_CHIP}, timer::TIMER_IRQ_NUM, }, - cpu::{CpuId, PrivilegeLevel}, + cpu::PrivilegeLevel, ex_table::ExTable, irq::call_irq_callback_functions, mm::MAX_USERSPACE_VADDR, @@ -115,9 +115,8 @@ pub(super) fn handle_irq(trap_frame: &TrapFrame, interrupt: Interrupt, priv_leve ); } Interrupt::SupervisorExternal => { - // No races because we are in IRQs. - let current_cpu = CpuId::current_racy().into(); - while let Some(hw_irq_line) = IRQ_CHIP.get().unwrap().claim_interrupt(current_cpu) { + let hart_id = crate::arch::boot::smp::get_current_hart_id(); + while let Some(hw_irq_line) = IRQ_CHIP.get().unwrap().claim_interrupt(hart_id) { call_irq_callback_functions(trap_frame, &hw_irq_line, priv_level); } }