3 * - By John Hodge (thePowersGang)
18 extern void *gpIRQHandler;
21 typedef void (*tIRQ_Handler)(int, void*);
24 int GIC_Install(char **Arguments);
25 void GIC_IRQHandler(void);
28 MODULE_DEFINE(0, 0x100, armv7_GIC, GIC_Install, NULL, NULL);
29 Uint32 *gpGIC_DistributorBase;
30 Uint32 *gpGIC_InterfaceBase;
31 tPAddr gGIC_DistributorAddr;
32 tPAddr gGIC_InterfaceAddr;
33 tIRQ_Handler gaIRQ_Handlers[N_IRQS];
34 void *gaIRQ_HandlerData[N_IRQS];
37 int GIC_Install(char **Arguments)
40 gGIC_InterfaceAddr = 0x1e000000;
41 gGIC_DistributorAddr = 0x1e001000;
44 gpGIC_InterfaceBase = (void*)MM_MapHWPages(gGIC_InterfaceAddr, 1);
45 LOG("gpGIC_InterfaceBase = %p", gpGIC_InterfaceBase);
46 gpGIC_DistributorBase = (void*)MM_MapHWPages(gGIC_DistributorAddr, 1);
47 LOG("gpGIC_DistributorBase = %p", gpGIC_DistributorBase);
49 gpGIC_InterfaceBase[GICC_PMR] = 0xFF;
50 gpGIC_InterfaceBase[GICC_CTLR] = 1; // Enable CPU
51 gpGIC_DistributorBase[GICD_CTLR] = 1; // Enable Distributor
53 gpIRQHandler = GIC_IRQHandler;
55 __asm__ __volatile__ ("cpsie if"); // Enable IRQs and FIQs
60 void GIC_IRQHandler(void)
62 Uint32 num = gpGIC_InterfaceBase[GICC_IAR];
63 // Log_Debug("GIC", "IRQ 0x%x", num);
64 gaIRQ_Handlers[num]( num, gaIRQ_HandlerData[num] );
65 gpGIC_InterfaceBase[GICC_EOIR] = num;
68 int IRQ_AddHandler(int IRQ, tIRQ_Handler Handler, void *Ptr)
70 if( IRQ < 0 || IRQ >= N_IRQS-32 ) {
75 IRQ += 32; // 32 internal IRQs
76 LOG("IRQ = %i (after adjust)", IRQ);
77 LOG("mask = 0x%x", 1 << (IRQ & (31-1)));
78 gpGIC_DistributorBase[GICD_ISENABLER0+IRQ/32] = 1 << (IRQ & (32-1));
79 ((Uint8*)&gpGIC_DistributorBase[GICD_ITARGETSR0])[IRQ] = 1;
81 // Log_Warning("GIC", "TODO: Implement IRQ_AddHandler");
83 if( gaIRQ_Handlers[IRQ] )
86 gaIRQ_Handlers[IRQ] = Handler;
87 gaIRQ_HandlerData[IRQ] = Ptr;