forked from Mirror/GodMode9
use hardcoded configuration for ARM11 interrupts
This commit is contained in:
parent
8863979a99
commit
4dc5661d58
@ -76,12 +76,40 @@ static gicIrqHandler gicIrqHandlers[DIC_MAX_IRQ];
|
|||||||
static struct {
|
static struct {
|
||||||
u8 tgt;
|
u8 tgt;
|
||||||
u8 prio;
|
u8 prio;
|
||||||
u8 mode;
|
|
||||||
} gicIrqConfig[DIC_MAX_IRQ];
|
} gicIrqConfig[DIC_MAX_IRQ];
|
||||||
|
|
||||||
// gets used whenever a NULL pointer is passed to gicEnableInterrupt
|
// gets used whenever a NULL pointer is passed to gicEnableInterrupt
|
||||||
static void gicDummyHandler(u32 irqn) { (void)irqn; return; }
|
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)
|
void gicTopHandler(void)
|
||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
@ -189,24 +217,23 @@ void gicLocalReset(void)
|
|||||||
} while(irq_s != GIC_IRQ_SPURIOUS);
|
} while(irq_s != GIC_IRQ_SPURIOUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gicSetIrqCfg(u32 irqn, u32 mode) {
|
static void gicSetIrqCfg(u32 irqn) {
|
||||||
u32 smt, cfg;
|
u32 smt, cfg;
|
||||||
|
|
||||||
smt = irqn & 15;
|
smt = irqn & 15;
|
||||||
cfg = REG_DIC_CFGREG[irqn / 16];
|
cfg = REG_DIC_CFGREG[irqn / 16];
|
||||||
cfg &= ~(3 << smt);
|
cfg &= ~(3 << smt);
|
||||||
cfg |= mode << smt;
|
cfg |= gicGetDefaultIrqCfg(irqn) << smt;
|
||||||
REG_DIC_CFGREG[irqn / 16] = cfg;
|
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?
|
if (handler == NULL) // maybe add runtime ptr checks here too?
|
||||||
handler = gicDummyHandler;
|
handler = gicDummyHandler;
|
||||||
|
|
||||||
gicIrqConfig[irqn].tgt = coremask;
|
gicIrqConfig[irqn].tgt = coremask;
|
||||||
gicIrqConfig[irqn].prio = prio;
|
gicIrqConfig[irqn].prio = prio;
|
||||||
gicIrqConfig[irqn].mode = mode;
|
|
||||||
gicIrqHandlers[irqn] = handler;
|
gicIrqHandlers[irqn] = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,7 +247,7 @@ void gicEnableInterrupt(u32 irqn)
|
|||||||
{
|
{
|
||||||
REG_DIC_PRIORITY[irqn] = gicIrqConfig[irqn].prio;
|
REG_DIC_PRIORITY[irqn] = gicIrqConfig[irqn].prio;
|
||||||
REG_DIC_TARGETCPU[irqn] = gicIrqConfig[irqn].tgt;
|
REG_DIC_TARGETCPU[irqn] = gicIrqConfig[irqn].tgt;
|
||||||
gicSetIrqCfg(irqn, gicIrqConfig[irqn].mode);
|
gicSetIrqCfg(irqn);
|
||||||
|
|
||||||
REG_DIC_CLRPENDING[irqn / 32] |= BIT(irqn & 0x1F);
|
REG_DIC_CLRPENDING[irqn / 32] |= BIT(irqn & 0x1F);
|
||||||
REG_DIC_SETENABLE[irqn / 32] |= BIT(irqn & 0x1F);
|
REG_DIC_SETENABLE[irqn / 32] |= BIT(irqn & 0x1F);
|
||||||
|
@ -87,7 +87,7 @@ void gicLocalReset(void);
|
|||||||
|
|
||||||
#define COREMASK_ALL (BIT(MAX_CPU) - 1)
|
#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 gicClearInterruptConfig(u32 irqn);
|
||||||
|
|
||||||
void gicEnableInterrupt(u32 irqn);
|
void gicEnableInterrupt(u32 irqn);
|
||||||
|
@ -186,9 +186,9 @@ void __attribute__((noreturn)) MainLoop(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// configure interrupts
|
// configure interrupts
|
||||||
gicSetInterruptConfig(PXI_RX_INTERRUPT, BIT(0), GIC_PRIO2, GIC_RISINGEDGE_1N, PXI_RX_Handler);
|
gicSetInterruptConfig(PXI_RX_INTERRUPT, BIT(0), GIC_PRIO2, PXI_RX_Handler);
|
||||||
gicSetInterruptConfig(MCU_INTERRUPT, BIT(0), GIC_PRIO1, GIC_RISINGEDGE_1N, MCU_HandleInterrupts);
|
gicSetInterruptConfig(MCU_INTERRUPT, BIT(0), GIC_PRIO1, MCU_HandleInterrupts);
|
||||||
gicSetInterruptConfig(VBLANK_INTERRUPT, BIT(0), GIC_PRIO0, GIC_RISINGEDGE_1N, VBlank_Handler);
|
gicSetInterruptConfig(VBLANK_INTERRUPT, BIT(0), GIC_PRIO0, VBlank_Handler);
|
||||||
|
|
||||||
// enable interrupts
|
// enable interrupts
|
||||||
gicEnableInterrupt(PXI_RX_INTERRUPT);
|
gicEnableInterrupt(PXI_RX_INTERRUPT);
|
||||||
|
@ -57,7 +57,7 @@ static void SYS_EnableClkMult(void)
|
|||||||
// state might get a bit messed up so it has to be done
|
// state might get a bit messed up so it has to be done
|
||||||
// as early as possible in the initialization chain
|
// as early as possible in the initialization chain
|
||||||
if (SYS_IsNewConsole() && !SYS_ClkMultEnabled()) {
|
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);
|
gicEnableInterrupt(88);
|
||||||
*CFG11_MPCORE_CLKCNT = 0x8001;
|
*CFG11_MPCORE_CLKCNT = 0x8001;
|
||||||
do {
|
do {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user