From 4dc5661d587e1e726e91d566a81b2c2f6b04b35c Mon Sep 17 00:00:00 2001 From: Wolfvak Date: Sun, 2 Aug 2020 11:40:18 -0300 Subject: [PATCH] use hardcoded configuration for ARM11 interrupts --- arm11/source/arm/gic.c | 39 +++++++++++++++++++++++++++++++++------ arm11/source/arm/gic.h | 2 +- arm11/source/main.c | 6 +++--- arm11/source/system/sys.c | 2 +- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/arm11/source/arm/gic.c b/arm11/source/arm/gic.c index 3c2eeac..f396971 100644 --- a/arm11/source/arm/gic.c +++ b/arm11/source/arm/gic.c @@ -76,12 +76,40 @@ static gicIrqHandler gicIrqHandlers[DIC_MAX_IRQ]; static struct { u8 tgt; u8 prio; - u8 mode; } gicIrqConfig[DIC_MAX_IRQ]; // gets used whenever a NULL pointer is passed to gicEnableInterrupt static void gicDummyHandler(u32 irqn) { (void)irqn; return; } +static const struct { + u8 low, high, mode; +} gicDefaultIrqCfg[] = { + { .low = 0x00, .high = 0x1F, .mode = GIC_RISINGEDGE_NN }, + { .low = 0x20, .high = 0x23, .mode = GIC_LEVELHIGH_1N }, + { .low = 0x24, .high = 0x24, .mode = GIC_RISINGEDGE_1N }, + { .low = 0x25, .high = 0x27, .mode = GIC_LEVELHIGH_1N }, + { .low = 0x28, .high = 0x2D, .mode = GIC_RISINGEDGE_1N }, + { .low = 0x30, .high = 0x3B, .mode = GIC_LEVELHIGH_1N }, + { .low = 0x40, .high = 0x4E, .mode = GIC_RISINGEDGE_1N }, + { .low = 0x4F, .high = 0x4F, .mode = GIC_LEVELHIGH_1N }, + { .low = 0x50, .high = 0x57, .mode = GIC_RISINGEDGE_1N }, + { .low = 0x58, .high = 0x58, .mode = GIC_LEVELHIGH_1N }, + { .low = 0x59, .high = 0x75, .mode = GIC_RISINGEDGE_1N }, + { .low = 0x76, .high = 0x77, .mode = GIC_LEVELHIGH_1N }, + { .low = 0x78, .high = 0x78, .mode = GIC_RISINGEDGE_1N }, + { .low = 0x79, .high = 0x7d, .mode = GIC_LEVELHIGH_1N }, +}; + +static u8 gicGetDefaultIrqCfg(u32 irqn) { + for (unsigned i = 0; i < countof(gicDefaultIrqCfg); i++) { + if ((irqn >= gicDefaultIrqCfg[i].low) && (irqn <= gicDefaultIrqCfg[i].high)) + return gicDefaultIrqCfg[i].mode; + } + // TODO: would it be considerably faster to use bsearch? + + return GIC_RISINGEDGE_1N; +} + void gicTopHandler(void) { while(1) { @@ -189,24 +217,23 @@ void gicLocalReset(void) } while(irq_s != GIC_IRQ_SPURIOUS); } -static void gicSetIrqCfg(u32 irqn, u32 mode) { +static void gicSetIrqCfg(u32 irqn) { u32 smt, cfg; smt = irqn & 15; cfg = REG_DIC_CFGREG[irqn / 16]; cfg &= ~(3 << smt); - cfg |= mode << smt; + cfg |= gicGetDefaultIrqCfg(irqn) << smt; REG_DIC_CFGREG[irqn / 16] = cfg; } -void gicSetInterruptConfig(u32 irqn, u32 coremask, u32 prio, u32 mode, gicIrqHandler handler) +void gicSetInterruptConfig(u32 irqn, u32 coremask, u32 prio, gicIrqHandler handler) { if (handler == NULL) // maybe add runtime ptr checks here too? handler = gicDummyHandler; gicIrqConfig[irqn].tgt = coremask; gicIrqConfig[irqn].prio = prio; - gicIrqConfig[irqn].mode = mode; gicIrqHandlers[irqn] = handler; } @@ -220,7 +247,7 @@ void gicEnableInterrupt(u32 irqn) { REG_DIC_PRIORITY[irqn] = gicIrqConfig[irqn].prio; REG_DIC_TARGETCPU[irqn] = gicIrqConfig[irqn].tgt; - gicSetIrqCfg(irqn, gicIrqConfig[irqn].mode); + gicSetIrqCfg(irqn); REG_DIC_CLRPENDING[irqn / 32] |= BIT(irqn & 0x1F); REG_DIC_SETENABLE[irqn / 32] |= BIT(irqn & 0x1F); diff --git a/arm11/source/arm/gic.h b/arm11/source/arm/gic.h index edbc297..7f1593a 100644 --- a/arm11/source/arm/gic.h +++ b/arm11/source/arm/gic.h @@ -87,7 +87,7 @@ void gicLocalReset(void); #define COREMASK_ALL (BIT(MAX_CPU) - 1) -void gicSetInterruptConfig(u32 irqn, u32 coremask, u32 prio, u32 mode, gicIrqHandler handler); +void gicSetInterruptConfig(u32 irqn, u32 coremask, u32 prio, gicIrqHandler handler); void gicClearInterruptConfig(u32 irqn); void gicEnableInterrupt(u32 irqn); diff --git a/arm11/source/main.c b/arm11/source/main.c index db23ada..0ee47f4 100644 --- a/arm11/source/main.c +++ b/arm11/source/main.c @@ -186,9 +186,9 @@ void __attribute__((noreturn)) MainLoop(void) #endif // configure interrupts - gicSetInterruptConfig(PXI_RX_INTERRUPT, BIT(0), GIC_PRIO2, GIC_RISINGEDGE_1N, PXI_RX_Handler); - gicSetInterruptConfig(MCU_INTERRUPT, BIT(0), GIC_PRIO1, GIC_RISINGEDGE_1N, MCU_HandleInterrupts); - gicSetInterruptConfig(VBLANK_INTERRUPT, BIT(0), GIC_PRIO0, GIC_RISINGEDGE_1N, VBlank_Handler); + gicSetInterruptConfig(PXI_RX_INTERRUPT, BIT(0), GIC_PRIO2, PXI_RX_Handler); + gicSetInterruptConfig(MCU_INTERRUPT, BIT(0), GIC_PRIO1, MCU_HandleInterrupts); + gicSetInterruptConfig(VBLANK_INTERRUPT, BIT(0), GIC_PRIO0, VBlank_Handler); // enable interrupts gicEnableInterrupt(PXI_RX_INTERRUPT); diff --git a/arm11/source/system/sys.c b/arm11/source/system/sys.c index 6bccc64..fafb21a 100755 --- a/arm11/source/system/sys.c +++ b/arm11/source/system/sys.c @@ -57,7 +57,7 @@ static void SYS_EnableClkMult(void) // state might get a bit messed up so it has to be done // as early as possible in the initialization chain if (SYS_IsNewConsole() && !SYS_ClkMultEnabled()) { - gicSetInterruptConfig(88, BIT(0), GIC_PRIO_HIGHEST, GIC_RISINGEDGE_1N, NULL); + gicSetInterruptConfig(88, BIT(0), GIC_PRIO_HIGHEST, NULL); gicEnableInterrupt(88); *CFG11_MPCORE_CLKCNT = 0x8001; do {