From d18d41fc0280335587f39b0d03f640177c766a09 Mon Sep 17 00:00:00 2001 From: Paul Mathieu Date: Tue, 24 Jun 2025 23:02:38 -0700 Subject: [PATCH] mbv: small refactor interrupts --- mbv/apps/timer/timer.cc | 9 +++++---- mbv/apps/uart/uart.cc | 9 +++++---- mbv/hal/intc.cc | 6 +++++- mbv/hal/intc.h | 4 ++++ mbv/hal/interrupts.cc | 28 +++++++++++++++++++++------- mbv/hal/interrupts.h | 3 +++ 6 files changed, 43 insertions(+), 16 deletions(-) diff --git a/mbv/apps/timer/timer.cc b/mbv/apps/timer/timer.cc index 1c97a76..c8159b4 100644 --- a/mbv/apps/timer/timer.cc +++ b/mbv/apps/timer/timer.cc @@ -25,9 +25,8 @@ void SetupTimer() { timer->SetupAsWdt(100'000'000); timer->EnableT1(); - SetIsr(TIMER0_IRQN, Timer0Isr); - SetIrqEnabled(TIMER0_IRQN, true); - EnableInterrupts(); + intc::SetIsr(TIMER0_IRQN, Timer0Isr); + intc::SetIrqEnabled(TIMER0_IRQN, true); } } // namespace @@ -37,8 +36,10 @@ int main() { leds->data = 0xa0; SetupTimer(); - SetExternalInterruptHandler(InterruptHandler); + intc::EnableInterrupts(); + SetExternalInterruptHandler(intc::InterruptHandler); EnableExternalInterrupts(); + EnableInterrupts(true); leds->data = 0xa1; diff --git a/mbv/apps/uart/uart.cc b/mbv/apps/uart/uart.cc index 1e0da91..e962709 100644 --- a/mbv/apps/uart/uart.cc +++ b/mbv/apps/uart/uart.cc @@ -41,8 +41,8 @@ void InitUarts() { XUartLite_SetRecvHandler(uart0, HandleUartRxFromIsr, nullptr); XUartLite_EnableInterrupt(uart0); - SetIsr(UART0_IRQN, Uart0Isr); - SetIrqEnabled(UART0_IRQN, true); + intc::SetIsr(UART0_IRQN, Uart0Isr); + intc::SetIrqEnabled(UART0_IRQN, true); } } // namespace @@ -52,9 +52,10 @@ int main() { leds->data = 0xa0; InitUarts(); - EnableInterrupts(); - SetExternalInterruptHandler(InterruptHandler); + intc::EnableInterrupts(); + SetExternalInterruptHandler(intc::InterruptHandler); EnableExternalInterrupts(); + EnableInterrupts(true); int counter = 0; diff --git a/mbv/hal/intc.cc b/mbv/hal/intc.cc index fe13989..48a175b 100644 --- a/mbv/hal/intc.cc +++ b/mbv/hal/intc.cc @@ -1,7 +1,9 @@ #include "intc.h" +// this interrupt controller is tied to the pol0 design #include "pol0.h" +namespace intc { namespace { struct IntC { @@ -22,7 +24,7 @@ struct IntC { IntC* intc = reinterpret_cast(INTC_BASE); Isr isrs[NIRQ] = {}; -} +} // namespace bool SetIrqEnabled(uint8_t irqn, bool enabled) { uint32_t mask = 1 << irqn; @@ -60,3 +62,5 @@ void InterruptHandler() { } } } + +} // namespace intc diff --git a/mbv/hal/intc.h b/mbv/hal/intc.h index 156af0e..7e463ec 100644 --- a/mbv/hal/intc.h +++ b/mbv/hal/intc.h @@ -2,6 +2,8 @@ #include +namespace intc { + using Isr = void(*)(void); /// Returns: true if the IRQ was previously enabled @@ -14,3 +16,5 @@ void EnableInterrupts(); // Feed this to the CPU's interrupt handler void InterruptHandler(); + +} // namespace intc diff --git a/mbv/hal/interrupts.cc b/mbv/hal/interrupts.cc index a9d777d..c4a7df5 100644 --- a/mbv/hal/interrupts.cc +++ b/mbv/hal/interrupts.cc @@ -1,5 +1,6 @@ #include +#include "bios.h" #include "interrupts.h" namespace { @@ -26,27 +27,40 @@ void TrapHandler() { mip &= ~(kMieExternalInterruptMask); asm volatile("csrw mip, %0" :: "r"(mip)); + } else { + BiosWozmon(); } } -} +} // namespace void SetExternalInterruptHandler(Isr handler) { external_handler = handler; } void EnableExternalInterrupts() { - uint32_t mstatus; uint32_t mie; Isr trap = TrapHandler; - asm volatile("csrr %0, mstatus" : "=r"(mstatus)); asm volatile("csrr %0, mie" : "=r"(mie)); - asm volatile("csrw mtvec, %0" :: "r"(trap)); - mie |= kMieExternalInterruptMask; asm volatile("csrw mie, %0" :: "r"(mie)); - mstatus |= kMstatusMieMask; - asm volatile("csrw mstatus, %0" :: "r"(mstatus)); +} + +bool EnableInterrupts(bool on) { + uint32_t mstatus; + bool was_on; + asm volatile("csrr %0, mstatus" : "=r"(mstatus)); + + was_on = (mstatus & kMstatusMieMask) > 0; + + if (on) { + mstatus |= kMstatusMieMask; + } else { + mstatus &= ~kMstatusMieMask; + } + + asm volatile("csrw mstatus, %0" :: "r"(mstatus)); + return was_on; } diff --git a/mbv/hal/interrupts.h b/mbv/hal/interrupts.h index ec09d51..66ec20f 100644 --- a/mbv/hal/interrupts.h +++ b/mbv/hal/interrupts.h @@ -4,3 +4,6 @@ using Isr = void(*)(); void SetExternalInterruptHandler(Isr handler); void EnableExternalInterrupts(); + +/** Returns true if interrupts were enabled, false otherwise */ +bool EnableInterrupts(bool on);