diff --git a/src/arch/aarch64/device/generic_timer.rs b/src/arch/aarch64/device/generic_timer.rs index c1a4fff6bf..c65e12676e 100644 --- a/src/arch/aarch64/device/generic_timer.rs +++ b/src/arch/aarch64/device/generic_timer.rs @@ -1,5 +1,5 @@ use alloc::boxed::Box; -use log::{error, info}; +use log::{debug, error, info}; use super::ic_for_chip; use crate::{ @@ -30,7 +30,8 @@ pub unsafe fn init(fdt: &Fdt) { }; timer.init(); if let Some(node) = fdt.find_compatible(&["arm,armv7-timer"]) { - let irq = get_interrupt(fdt, &node, 0).unwrap(); + let irq = get_interrupt(fdt, &node, 1).unwrap(); + debug!("irq = {:?}", irq); if let Some(ic_idx) = ic_for_chip(&fdt, &node) { //PHYS_NONSECURE_PPI only let virq = IRQ_CHIP.irq_chip_list.chips[ic_idx] @@ -101,6 +102,7 @@ impl GenericTimer { impl InterruptHandler for GenericTimer { fn irq_handler(&mut self, irq: u32) { + self.clear_irq(); { *time::OFFSET.lock() += self.clk_freq as u128; diff --git a/src/arch/aarch64/device/irqchip/irq_bcm2835.rs b/src/arch/aarch64/device/irqchip/irq_bcm2835.rs index ee6cd32c61..a8a118bd83 100644 --- a/src/arch/aarch64/device/irqchip/irq_bcm2835.rs +++ b/src/arch/aarch64/device/irqchip/irq_bcm2835.rs @@ -87,7 +87,7 @@ impl Bcm2835ArmInterruptController { .ic .irq_xlate(irq) .unwrap(); - info!("bcm2835arm_ctrl virq = {}", virq); + info!("register bcm2835arm_ctrl as ic_idx {}'s child virq = {}", ic_idx, virq); ret_virq = Some(virq); } Ok((base as usize, size as usize, ret_virq)) diff --git a/src/arch/aarch64/device/irqchip/irq_bcm2836.rs b/src/arch/aarch64/device/irqchip/irq_bcm2836.rs index 3e418dc624..730555ce9d 100644 --- a/src/arch/aarch64/device/irqchip/irq_bcm2836.rs +++ b/src/arch/aarch64/device/irqchip/irq_bcm2836.rs @@ -1,11 +1,11 @@ use super::InterruptController; -use crate::dtb::{ +use crate::{arch::device::{ROOT_IC_IDX, ROOT_IC_IDX_IS_SET}, dtb::{ get_mmio_address, irqchip::{InterruptHandler, IrqCell, IrqDesc}, -}; +}}; use core::{ arch::asm, - ptr::{read_volatile, write_volatile}, + ptr::{read_volatile, write_volatile}, sync::atomic::Ordering, }; use fdt::{node::FdtNode, Fdt}; use log::{debug, info}; @@ -146,6 +146,11 @@ impl InterruptController for Bcm2836ArmInterruptController { *irq_idx = idx + cnt; } + //raspi 3b+ dts doesn't follow the rule to set root parent interrupt controller + //so we should set it manually. + ROOT_IC_IDX.store(ic_idx, Ordering::Relaxed); + ROOT_IC_IDX_IS_SET.store(1, Ordering::Relaxed); + Ok(()) } @@ -162,6 +167,7 @@ impl InterruptController for Bcm2836ArmInterruptController { fn irq_eoi(&mut self, _irq_num: u32) {} fn irq_enable(&mut self, irq_num: u32) { + debug!("bcm2836 enable {}", irq_num); match irq_num { LOCAL_IRQ_CNTPNSIRQ => unsafe { let cpuid: usize; diff --git a/src/arch/aarch64/device/mod.rs b/src/arch/aarch64/device/mod.rs index 5410a3431d..7699fc9e58 100644 --- a/src/arch/aarch64/device/mod.rs +++ b/src/arch/aarch64/device/mod.rs @@ -13,8 +13,17 @@ use crate::dtb::irqchip::IRQ_CHIP; use irqchip::ic_for_chip; pub static ROOT_IC_IDX: AtomicUsize = AtomicUsize::new(0); +pub static ROOT_IC_IDX_IS_SET: AtomicUsize = AtomicUsize::new(0); unsafe fn init_root_ic(fdt: &Fdt) { + + let is_set = ROOT_IC_IDX_IS_SET.load(Ordering::Relaxed); + if is_set != 0 { + let ic_idx = ROOT_IC_IDX.load(Ordering::Relaxed); + info!("Already selected {} as root ic", ic_idx); + return ; + } + let root_irqc_phandle = fdt .root() .property("interrupt-parent") @@ -24,6 +33,7 @@ unsafe fn init_root_ic(fdt: &Fdt) { let ic_idx = IRQ_CHIP .phandle_to_ic_idx(root_irqc_phandle as u32) .unwrap(); + info!("select {} as root ic", ic_idx); ROOT_IC_IDX.store(ic_idx, Ordering::Relaxed); }