Skip to content

Commit 554e158

Browse files
committed
enable the virtual timer interrupt on application processors
The switch from the physical timer (CNTP_*) to the virtual timer (CNTV_*) updated the FDT parsing in init(), which now selects the third interrupt triplet of the "arm,armv8-timer" node (Virtual, PPI 11 / INTID 27). init_cpu() still selected the second triplet (Non-secure Phys, PPI 14 / INTID 30), so every application processor enabled the physical timer PPI in its redistributor while set_oneshot_timer programs the virtual timer. Timer PPIs are per-core: sleeping tasks on the secondary cores were never woken up again. This is why thread_test with --smp 4 timed out: of eight threads only the two scheduled on the boot core finished; the six on the secondary cores slept forever. Skip the same two triplets in init_cpu() so all cores enable the virtual timer interrupt.
1 parent 26fc28e commit 554e158

2 files changed

Lines changed: 10 additions & 9 deletions

File tree

src/arch/aarch64/kernel/interrupts.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,11 +449,19 @@ pub fn init_cpu() {
449449

450450
if let Some(timer_node) = fdt.find_compatible(&["arm,armv8-timer", "arm,armv7-timer"]) {
451451
let irq_slice = timer_node.property("interrupts").unwrap().value;
452-
/* Secure Phys IRQ */
452+
// Select the Virtual Timer triplet, matching `init()`: the kernel
453+
// programs the virtual timer (CNTV_*), and timer PPIs are per-core,
454+
// so every application processor has to enable the *same* interrupt
455+
// in its redistributor that the boot core selected.
456+
/* Secure Phys IRQ — skip */
453457
let (_irqtype, irq_slice) = irq_slice.split_at(size_of::<u32>());
454458
let (_irq, irq_slice) = irq_slice.split_at(size_of::<u32>());
455459
let (_irqflags, irq_slice) = irq_slice.split_at(size_of::<u32>());
456-
/* Non-secure Phys IRQ */
460+
/* Non-secure Phys IRQ — skip */
461+
let (_irqtype, irq_slice) = irq_slice.split_at(size_of::<u32>());
462+
let (_irq, irq_slice) = irq_slice.split_at(size_of::<u32>());
463+
let (_irqflags, irq_slice) = irq_slice.split_at(size_of::<u32>());
464+
/* Virtual Timer IRQ */
457465
let (irqtype, irq_slice) = irq_slice.split_at(size_of::<u32>());
458466
let (irq, irq_slice) = irq_slice.split_at(size_of::<u32>());
459467
let (irqflags, _irq_slice) = irq_slice.split_at(size_of::<u32>());

src/executor/network.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,6 @@ impl<'a> NetworkInterface<'a> {
402402
))]
403403
fn handle_interrupt(&mut self) {
404404
self.get_inner_device().handle_interrupt();
405-
<<<<<<< HEAD
406405
}
407406

408407
#[cfg(all(
@@ -414,20 +413,14 @@ impl<'a> NetworkInterface<'a> {
414413
fn handle_device_configuration_interrupt(&mut self) {
415414
self.get_inner_device()
416415
.handle_device_configuration_interrupt();
417-
=======
418-
>>>>>>> 456cbb6b1 (feat(network): support packet capture file creation)
419416
}
420417

421418
pub(crate) fn set_polling_mode(&mut self, value: bool) {
422419
self.get_inner_device().set_polling_mode(value);
423420
}
424421

425422
/// Gets the device inside the [smoltcp::phy::Tracer] and [smoltcp::phy::PcapWriter] layers.
426-
<<<<<<< HEAD
427423
fn get_inner_device(&mut self) -> &mut NetworkDevice {
428-
=======
429-
fn get_inner_device(&mut self) -> &mut impl NetworkDriver {
430-
>>>>>>> 456cbb6b1 (feat(network): support packet capture file creation)
431424
let device = &mut self.device;
432425
#[cfg(feature = "net-trace")]
433426
let device = device.get_mut();

0 commit comments

Comments
 (0)