diff --git a/soc/arm/qemu_raspi3/intc_bcm2837.c b/soc/arm/qemu_raspi3/intc_bcm2837.c index e6ccbfe487d919b766889ce0f33ddc36927d9cf0..efd626501b4e8daef35d1d6fd47e45f68b4e5aca 100644 --- a/soc/arm/qemu_raspi3/intc_bcm2837.c +++ b/soc/arm/qemu_raspi3/intc_bcm2837.c @@ -79,8 +79,6 @@ static void armctrl_irq_enable(unsigned int irq) { printk("armctrl_irq_enable irq=%d, bank=%d, bit=%d, addr=%p\n", irq, bank, bank_bit, addr); sys_write32((1 << bank_bit), addr); - - irq_enabled[irq] = true; } static void armctrl_irq_disable(unsigned int irq) { @@ -90,8 +88,6 @@ static void armctrl_irq_disable(unsigned int irq) { printk("armctrl_irq_enable irq=%d, bank=%d, bit=%d, addr=%p\n", irq, bank, bank_bit, addr); sys_write32((1 << bank_bit), addr); - - irq_enabled[irq] = false; } /* BCM2836 ARM-local peripherals manual, section 4.10 "Core interrupt sources" */ @@ -113,6 +109,7 @@ static void l1_irq_enable(unsigned int l1_irq) { static void l1_irq_disable(unsigned int l1_irq) { __ASSERT_NO_MSG(l1_irq < L1_NUM_IRQS); + printk("Warning: l1_irq_disable(%d) not implemented.\n", l1_irq); } void z_soc_irq_init(void) { @@ -123,7 +120,6 @@ int z_soc_irq_is_enabled(unsigned int irq) { /* Manual does not explicitly state that reading from armctrl_reg_enable * indicates if an IRQ was enabled, also Xinu does not do it like * this. That's why we have irq_enabled. */ - return irq_enabled[irq]; } @@ -133,6 +129,7 @@ void z_soc_irq_enable(unsigned int irq) { } else { l1_irq_enable(irq - ARMCTRL_NUM_IRQS); } + irq_enabled[irq] = true; } void z_soc_irq_disable(unsigned int irq) { @@ -141,6 +138,7 @@ void z_soc_irq_disable(unsigned int irq) { } else { l1_irq_disable(irq - ARMCTRL_NUM_IRQS); } + irq_enabled[irq] = false; } void z_soc_irq_priority_set(unsigned int irq, unsigned int prio, unsigned int flags) { @@ -159,13 +157,7 @@ void z_soc_irq_priority_set(unsigned int irq, unsigned int prio, unsigned int fl * - https://embedded-xinu.readthedocs.io/en/latest/arm/rpi/BCM2835-Interrupt-Controller.html */ unsigned int z_soc_irq_get_active(void) { - printk("z_soc_irq_get_active"); - for (unsigned int irq = 0; irq < ARMCTRL_NUM_IRQS; irq++) { - if (!irq_is_enabled(irq)) { - continue; - } - int bank, bank_bit; armctrl_irq_to_bank(irq, &bank, &bank_bit); @@ -175,16 +167,28 @@ unsigned int z_soc_irq_get_active(void) { if (is_pending) { /* Clear pending to allow us to detect when this IRQ occurs again (nested irq). */ sys_write32(bank_pending & ~(1 << bank_bit), BCM2836_ARMCTRL_BASE + armctrl_reg_pending[bank]); + if (!irq_is_enabled(irq)) { + printk("Warning: IRQ %d was triggered while disabled.\n", irq); + continue; + } return irq; } } - /* TODO: Check if it was a core timer / mailbox interrupt by checking - * the bit in the "core interrupt soruce" register of the current - * core. */ int cpu_id = arch_curr_cpu()->id; intptr_t core_interrupt_sources_addr = 0x40000060 + cpu_id * 4; - printk("*%p == %x\n", (void *) core_interrupt_sources_addr, sys_read32(core_interrupt_sources_addr)); + uint32_t pending = sys_read32(core_interrupt_sources_addr); + for (unsigned int l1_irq = 0; l1_irq < L1_NUM_IRQS; l1_irq++) { + unsigned int irq = ARMCTRL_NUM_IRQS + l1_irq; + if (pending & (1 << l1_irq)) { + sys_write32(pending & ~(1 << l1_irq), core_interrupt_sources_addr); + if (!irq_is_enabled(irq)) { + printk("Warning: IRQ %d was triggered while disabled.\n", irq); + continue; + } + return irq; + } + } __ASSERT_NO_MSG(false); CODE_UNREACHABLE;