X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2Farmv7%2FGIC%2Fgic.c;h=4ace400534b39b837b415e1f3de42d4feaae871f;hb=2bad2a51c08d52a675ab2e27eafab83bf0ae567a;hp=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391;hpb=24a67e79c846f38d5b2a906a6b643fac4f3da6d7;p=tpg%2Facess2.git diff --git a/Modules/armv7/GIC/gic.c b/Modules/armv7/GIC/gic.c index e69de29b..4ace4005 100644 --- a/Modules/armv7/GIC/gic.c +++ b/Modules/armv7/GIC/gic.c @@ -0,0 +1,88 @@ +/* + * ARMv7 GIC Support + * - By John Hodge (thePowersGang) + * + * gic.c + * - GIC Core + */ +#define DEBUG 1 + +#include +#include +#include "gic.h" + +#define N_IRQS 1024 + +// === IMPORTS === +extern void *gpIRQHandler; + +// === TYPES === +typedef void (*tIRQ_Handler)(int, void*); + +// === PROTOTYPES === + int GIC_Install(char **Arguments); +void GIC_IRQHandler(void); + +// === GLOBALS === +MODULE_DEFINE(0, 0x100, armv7_GIC, GIC_Install, NULL, NULL); +Uint32 *gpGIC_DistributorBase; +Uint32 *gpGIC_InterfaceBase; +tPAddr gGIC_DistributorAddr; +tPAddr gGIC_InterfaceAddr; +tIRQ_Handler gaIRQ_Handlers[N_IRQS]; +void *gaIRQ_HandlerData[N_IRQS]; + +// === CODE === +int GIC_Install(char **Arguments) +{ + // Realview PB + gGIC_InterfaceAddr = 0x1e000000; + gGIC_DistributorAddr = 0x1e001000; + + // Initialise + gpGIC_InterfaceBase = (void*)MM_MapHWPages(gGIC_InterfaceAddr, 1); + gpGIC_DistributorBase = (void*)MM_MapHWPages(gGIC_DistributorAddr, 1); + + gpGIC_InterfaceBase[GICC_PMR] = 0xFF; + gpGIC_InterfaceBase[GICC_CTLR] = 1; // Enable CPU + gpGIC_DistributorBase[GICD_CTLR] = 1; // Enable Distributor + + gpIRQHandler = GIC_IRQHandler; + + __asm__ __volatile__ ("cpsie if"); // Enable IRQs and FIQs + + return MODULE_ERR_OK; +} + +void GIC_IRQHandler(void) +{ + Uint32 num = gpGIC_InterfaceBase[GICC_IAR]; + Log_Debug("GIC", "IRQ 0x%x", num); + gaIRQ_Handlers[num]( num, gaIRQ_HandlerData[num] ); + gpGIC_InterfaceBase[GICC_EOIR] = num; +} + +int IRQ_AddHandler(int IRQ, tIRQ_Handler Handler, void *Ptr) +{ + if( IRQ < 0 || IRQ >= N_IRQS-32 ) { + return 1; + } + + LOG("IRQ = %i", IRQ); + IRQ += 32; // 32 internal IRQs + LOG("IRQ = %i (after adjust)", IRQ); + LOG("mask = 0x%x", 1 << (IRQ & (31-1))); + gpGIC_DistributorBase[GICD_ISENABLER0+IRQ/32] = 1 << (IRQ & (32-1)); + ((Uint8*)&gpGIC_DistributorBase[GICD_ITARGETSR0])[IRQ] = 1; + +// Log_Warning("GIC", "TODO: Implement IRQ_AddHandler"); + + if( gaIRQ_Handlers[IRQ] ) + return 2; + + gaIRQ_Handlers[IRQ] = Handler; + gaIRQ_HandlerData[IRQ] = Ptr; + + return 0; +} +