mbv: small refactor interrupts

This commit is contained in:
Paul Mathieu 2025-06-24 23:02:38 -07:00
parent 6553fa04aa
commit d18d41fc02
6 changed files with 43 additions and 16 deletions

View File

@ -25,9 +25,8 @@ void SetupTimer() {
timer->SetupAsWdt(100'000'000); timer->SetupAsWdt(100'000'000);
timer->EnableT1(); timer->EnableT1();
SetIsr(TIMER0_IRQN, Timer0Isr); intc::SetIsr(TIMER0_IRQN, Timer0Isr);
SetIrqEnabled(TIMER0_IRQN, true); intc::SetIrqEnabled(TIMER0_IRQN, true);
EnableInterrupts();
} }
} // namespace } // namespace
@ -37,8 +36,10 @@ int main() {
leds->data = 0xa0; leds->data = 0xa0;
SetupTimer(); SetupTimer();
SetExternalInterruptHandler(InterruptHandler); intc::EnableInterrupts();
SetExternalInterruptHandler(intc::InterruptHandler);
EnableExternalInterrupts(); EnableExternalInterrupts();
EnableInterrupts(true);
leds->data = 0xa1; leds->data = 0xa1;

View File

@ -41,8 +41,8 @@ void InitUarts() {
XUartLite_SetRecvHandler(uart0, HandleUartRxFromIsr, nullptr); XUartLite_SetRecvHandler(uart0, HandleUartRxFromIsr, nullptr);
XUartLite_EnableInterrupt(uart0); XUartLite_EnableInterrupt(uart0);
SetIsr(UART0_IRQN, Uart0Isr); intc::SetIsr(UART0_IRQN, Uart0Isr);
SetIrqEnabled(UART0_IRQN, true); intc::SetIrqEnabled(UART0_IRQN, true);
} }
} // namespace } // namespace
@ -52,9 +52,10 @@ int main() {
leds->data = 0xa0; leds->data = 0xa0;
InitUarts(); InitUarts();
EnableInterrupts(); intc::EnableInterrupts();
SetExternalInterruptHandler(InterruptHandler); SetExternalInterruptHandler(intc::InterruptHandler);
EnableExternalInterrupts(); EnableExternalInterrupts();
EnableInterrupts(true);
int counter = 0; int counter = 0;

View File

@ -1,7 +1,9 @@
#include "intc.h" #include "intc.h"
// this interrupt controller is tied to the pol0 design
#include "pol0.h" #include "pol0.h"
namespace intc {
namespace { namespace {
struct IntC { struct IntC {
@ -22,7 +24,7 @@ struct IntC {
IntC* intc = reinterpret_cast<IntC*>(INTC_BASE); IntC* intc = reinterpret_cast<IntC*>(INTC_BASE);
Isr isrs[NIRQ] = {}; Isr isrs[NIRQ] = {};
} } // namespace
bool SetIrqEnabled(uint8_t irqn, bool enabled) { bool SetIrqEnabled(uint8_t irqn, bool enabled) {
uint32_t mask = 1 << irqn; uint32_t mask = 1 << irqn;
@ -60,3 +62,5 @@ void InterruptHandler() {
} }
} }
} }
} // namespace intc

View File

@ -2,6 +2,8 @@
#include <cstdint> #include <cstdint>
namespace intc {
using Isr = void(*)(void); using Isr = void(*)(void);
/// Returns: true if the IRQ was previously enabled /// Returns: true if the IRQ was previously enabled
@ -14,3 +16,5 @@ void EnableInterrupts();
// Feed this to the CPU's interrupt handler // Feed this to the CPU's interrupt handler
void InterruptHandler(); void InterruptHandler();
} // namespace intc

View File

@ -1,5 +1,6 @@
#include <cstdint> #include <cstdint>
#include "bios.h"
#include "interrupts.h" #include "interrupts.h"
namespace { namespace {
@ -26,27 +27,40 @@ void TrapHandler() {
mip &= ~(kMieExternalInterruptMask); mip &= ~(kMieExternalInterruptMask);
asm volatile("csrw mip, %0" :: "r"(mip)); asm volatile("csrw mip, %0" :: "r"(mip));
} else {
BiosWozmon();
} }
} }
} } // namespace
void SetExternalInterruptHandler(Isr handler) { void SetExternalInterruptHandler(Isr handler) {
external_handler = handler; external_handler = handler;
} }
void EnableExternalInterrupts() { void EnableExternalInterrupts() {
uint32_t mstatus;
uint32_t mie; uint32_t mie;
Isr trap = TrapHandler; Isr trap = TrapHandler;
asm volatile("csrr %0, mstatus" : "=r"(mstatus));
asm volatile("csrr %0, mie" : "=r"(mie)); asm volatile("csrr %0, mie" : "=r"(mie));
asm volatile("csrw mtvec, %0" :: "r"(trap)); asm volatile("csrw mtvec, %0" :: "r"(trap));
mie |= kMieExternalInterruptMask; mie |= kMieExternalInterruptMask;
asm volatile("csrw mie, %0" :: "r"(mie)); 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;
} }

View File

@ -4,3 +4,6 @@ using Isr = void(*)();
void SetExternalInterruptHandler(Isr handler); void SetExternalInterruptHandler(Isr handler);
void EnableExternalInterrupts(); void EnableExternalInterrupts();
/** Returns true if interrupts were enabled, false otherwise */
bool EnableInterrupts(bool on);