3 * - By John Hodge (thePowersGang)
18 extern void *gpIRQHandler;
19 extern tPAddr gGIC_DistributorAddr;
20 extern tPAddr gGIC_InterfaceAddr;
23 typedef void (*tIRQ_Handler)(int, void*);
26 int GIC_Install(char **Arguments);
27 void GIC_IRQHandler(void);
30 MODULE_DEFINE(0, 0x100, armv7_GIC, GIC_Install, NULL, NULL);
31 Uint32 *gpGIC_DistributorBase;
32 Uint32 *gpGIC_InterfaceBase;
33 tIRQ_Handler gaIRQ_Handlers[N_IRQS];
34 void *gaIRQ_HandlerData[N_IRQS];
37 int GIC_Install(char **Arguments)
40 gpGIC_InterfaceBase = (void*)MM_MapHWPages(gGIC_InterfaceAddr, 1);
41 LOG("gpGIC_InterfaceBase = %p", gpGIC_InterfaceBase);
42 gpGIC_DistributorBase = (void*)MM_MapHWPages(gGIC_DistributorAddr, 1);
43 LOG("gpGIC_DistributorBase = %p", gpGIC_DistributorBase);
45 gpGIC_InterfaceBase[GICC_PMR] = 0xFF;
46 gpGIC_InterfaceBase[GICC_CTLR] = 1; // Enable CPU
47 gpGIC_DistributorBase[GICD_CTLR] = 1; // Enable Distributor
49 gpIRQHandler = GIC_IRQHandler;
51 __asm__ __volatile__ ("cpsie if"); // Enable IRQs and FIQs
56 void GIC_IRQHandler(void)
58 Uint32 num = gpGIC_InterfaceBase[GICC_IAR];
59 // Log_Debug("GIC", "IRQ 0x%x", num);
60 gaIRQ_Handlers[num]( num, gaIRQ_HandlerData[num] );
61 gpGIC_InterfaceBase[GICC_EOIR] = num;
64 int IRQ_AddHandler(int IRQ, tIRQ_Handler Handler, void *Ptr)
66 if( IRQ < 0 || IRQ >= N_IRQS-32 ) {
71 IRQ += 32; // 32 internal IRQs
72 LOG("IRQ = %i (after adjust)", IRQ);
73 LOG("mask = 0x%x", 1 << (IRQ & (31-1)));
74 gpGIC_DistributorBase[GICD_ISENABLER0+IRQ/32] = 1 << (IRQ & (32-1));
75 ((Uint8*)&gpGIC_DistributorBase[GICD_ITARGETSR0])[IRQ] = 1;
77 // Log_Warning("GIC", "TODO: Implement IRQ_AddHandler");
79 if( gaIRQ_Handlers[IRQ] )
82 gaIRQ_Handlers[IRQ] = Handler;
83 gaIRQ_HandlerData[IRQ] = Ptr;