From be74abde2c01112d53e0fd86b47a4874ec940663 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 8 Oct 2011 18:48:27 +0800 Subject: [PATCH] Modules/armv7 - GIC support coming along --- Modules/armv7/GIC/gic.c | 40 +++++++++++++++++++++++++++++ Modules/armv7/GIC/gic.h | 57 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 Modules/armv7/GIC/gic.h diff --git a/Modules/armv7/GIC/gic.c b/Modules/armv7/GIC/gic.c index 90682f64..190b9953 100644 --- a/Modules/armv7/GIC/gic.c +++ b/Modules/armv7/GIC/gic.c @@ -5,23 +5,63 @@ * gic.c * - GIC Core */ +#define DEBUG 1 + #include #include +#include "gic.h" + +// === IMPORTS === +extern void *gpIRQHandler; // === 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; // === 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); + gpGIC_InterfaceBase[GICC_EOIR] = 1; +} + int IRQ_AddHandler(int IRQ, void (*Handler)(int, void*), void *Ptr) { + 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"); return 0; } diff --git a/Modules/armv7/GIC/gic.h b/Modules/armv7/GIC/gic.h new file mode 100644 index 00000000..d7a5a8dc --- /dev/null +++ b/Modules/armv7/GIC/gic.h @@ -0,0 +1,57 @@ +/* + * ARMv7 GIC Support + * - By John Hodge (thePowersGang) + * + * gic.h + * - GIC Core Definitions + */ +#ifndef _ARM7_GIC_H_ +#define _ARM7_GIC_H_ + +enum eGICD_Registers +{ + GICD_CTLR = 0x000/4, // Distributor Control Register + GICD_TYPER = 0x004/4, // Interrupt Controller Type + GICD_IIDR = 0x008/4, // Distributor Implementer Identifcation + + GICD_IGROUPR0 = 0x080/4, // Interrupt Group Register (#0) + GICD_ISENABLER0 = 0x100/4, // Interrupt Set-Enable Register #0 (128*8=1024) + GICD_ICENABLER0 = 0x180/4, // Interrupt Clear-Enable Register #0 + GICD_ISPENDR0 = 0x200/4, // Interrupt Set-Pending Register #0 + GICD_ICPENDR0 = 0x280/4, // Interrupt Clear-Pending Register #0 + GICD_ISACTIVER0 = 0x300/4, // Interrupt Set-Active Register (GICv2) + GICD_ICACTIVER0 = 0x380/4, // Interrupt Clear-Active Register (GICv2) + + GICD_IPRIORITYR0 = 0x400/4, // Interrupt priority registers (254*4 = ) + + GICD_ITARGETSR0 = 0x800/4, // Interrupt Processor Targets Register (8*4) + + GICD_ICFGR0 = 0xC00/4, // Interrupt Configuration Register (64*4) + GICD_NSACR0 = 0xE00/4, // Non-secure Access Control Register (64*4) + GICD_SIGR = 0xF00/4, // Software Generated Interrupt Register (Write Only) + GICD_CPENDSGIR0 = 0xF10/4, // SGI Clear-Pending Registers (4*4) + GICD_SPENDSGIR0 = 0xF20/4, // SGI Set-Pending Registers (4*4) +}; + +enum eGICC_Registers +{ + GICC_CTLR = 0x000/4, // CPU Interface Control Register + GICC_PMR = 0x004/4, // Interrupt Priority Mask Register + GICC_BPR = 0x008/4, // Binary Point Register + GICC_IAR = 0x00C/4, // Interrupt Acknowledge Register + GICC_EOIR = 0x010/4, // End of Interrupt Register + GICC_RPR = 0x014/4, // Running Priority Register + GICC_HPPIR = 0x018/4, // Highest Priority Pending Interrupt Register + GICC_ABPR = 0x01C/4, // Aliased Binary Point Register + GICC_AIAR = 0x020/4, // Aliased Interrupt Acknowledge Register, + GICC_AEOIR = 0x024/4, // Aliased End of Interrupt Register + GICC_AHPPIR = 0x028/4, // Aliased Highest Priority Pending Interrupt Register + + GICC_APR0 = 0x0D0/4, // Active Priorities Registers (4*4) + GICC_NSAPR0 = 0x0E0/4, // Non-secure Active Priorities Registers (4*4) + + GICC_IIDR = 0x0FC/4, // CPU Interface Identifcation Register + GICC_DIR = 0x0FC/4, // Deactivate Interrupt Register (Write Only) +}; + +#endif -- 2.20.1