use hardcoded configuration for ARM11 interrupts

This commit is contained in:
Wolfvak 2020-08-02 11:40:18 -03:00
parent 8863979a99
commit 4dc5661d58
4 changed files with 38 additions and 11 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 {