64 lines
1.2 KiB
C
Raw Normal View History

/*
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];
2017-08-08 23:04:17 -03:00
extern void (*main_irq_handler)(void);
2017-08-08 23:04:17 -03:00
irq_handler GIC_AckIRQ(void)
{
2017-08-08 23:04:17 -03:00
u32 xrq = *GIC_IRQACK;
irq_handler ret = NULL;
if (xrq < MAX_IRQ && handler_table[xrq]) {
2017-08-08 23:04:17 -03:00
ret = handler_table[xrq];
*GIC_IRQEND = xrq;
}
2017-08-08 23:04:17 -03:00
return ret;
}
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)
{
2017-08-08 23:04:17 -03:00
*DIC_CONTROL = 0;
*GIC_CONTROL = 0;
2017-08-08 23:04:17 -03:00
*GIC_PRIOMASK = ~0;
for (int i = 0; i < 0x80; i++) {
*GIC_IRQEND = i;
}
for (int i = 0; i < (0x20/4); i++) {
DIC_CLRENABLE[i] = ~0;
DIC_PRIORITY[i] = 0;
}
2017-08-08 23:04:17 -03:00
while(*GIC_PENDING != SPURIOUS_IRQ) {
for (int i=0; i < (0x20/4); i++) {
DIC_CLRPENDING[i] = ~0;
}
}
2017-08-08 23:04:17 -03:00
IRQ_BASE[1] = (u32)&main_irq_handler;
IRQ_BASE[0] = 0xE51FF004;
2017-08-08 23:04:17 -03:00
*GIC_CONTROL = 1;
*DIC_CONTROL = 1;
return;
}