forked from Mirror/GodMode9
58 lines
1.1 KiB
C
58 lines
1.1 KiB
C
/*
|
|
Written by Wolfvak, specially sublicensed under the GPLv2
|
|
Read LICENSE for more details
|
|
*/
|
|
|
|
#include <types.h>
|
|
#include <cpu.h>
|
|
#include <gic.h>
|
|
|
|
#define IRQ_BASE ((vu32*)0x1FFFFFA0)
|
|
|
|
irq_handler handler_table[MAX_IRQ];
|
|
|
|
void __attribute__((interrupt("IRQ"))) gic_irq_handler(void)
|
|
{
|
|
u32 xrq, ss;
|
|
CPU_EnterCritical(&ss);
|
|
xrq = *GIC_IRQACK;
|
|
if (xrq < MAX_IRQ && handler_table[xrq]) {
|
|
(handler_table[xrq])(xrq);
|
|
}
|
|
*GIC_IRQEND = xrq;
|
|
CPU_LeaveCritical(&ss);
|
|
return;
|
|
}
|
|
|
|
void GIC_Configure(u32 irq_id, irq_handler hndl)
|
|
{
|
|
handler_table[irq_id] = hndl;
|
|
DIC_CLRENABLE[irq_id/32] |= BIT(irq_id & 0x1F);
|
|
DIC_SETENABLE[irq_id/32] |= BIT(irq_id & 0x1F);
|
|
DIC_PROCTGT[irq_id] = 1;
|
|
return;
|
|
}
|
|
|
|
void GIC_Reset(void)
|
|
{
|
|
*GIC_CONTROL = 0;
|
|
*GIC_PRIOMASK = ~0;
|
|
|
|
for (int i = 0; i < (BIT(9)-1); i++) {
|
|
*GIC_IRQEND |= i;
|
|
}
|
|
|
|
*DIC_CONTROL = 0;
|
|
for (int i = 0; i < (0x20/4); i++) {
|
|
DIC_CLRENABLE[i] = ~0;
|
|
DIC_PRIORITY[i] = 0;
|
|
}
|
|
|
|
*DIC_CONTROL = 1;
|
|
*GIC_CONTROL = 1;
|
|
|
|
IRQ_BASE[1] = (u32)gic_irq_handler;
|
|
IRQ_BASE[0] = 0xE51FF004;
|
|
return;
|
|
}
|