Correct some hart ID usage

This commit is contained in:
Zhang Junyang 2025-09-01 23:15:20 +08:00 committed by Tate, Hongliang Tian
parent 8148072984
commit b86aeffd53
4 changed files with 20 additions and 18 deletions

View File

@ -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);
}

View File

@ -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<Item = u32> + 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);
}
}
}

View File

@ -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,
);
}

View File

@ -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);
}
}