/* gic.c — GIC-400 driver for Raspberry Pi 5 */ #include "gic.h" void gic_init(void) { /* Disable distributor */ GICD_CTLR = 0; /* Get number of IRQs supported */ int n = ((GICD_TYPER & 0x1F) + 1) * 32; /* Disable all IRQs */ for (int i = 0; i < n / 32; i++) { GICD_ICENABLER(i) = 0xFFFFFFFF; GICD_ICACTIVER(i) = 0xFFFFFFFF; } /* Set all IRQs to lowest priority */ for (int i = 0; i < n / 4; i++) { GICD_IPRIORITYR(i) = 0xA0A0A0A0; } /* Target all SPIs to CPU 0 */ for (int i = 8; i < n / 4; i++) { GICD_ITARGETSR(i) = 0x01010101; /* CPU 0 */ } /* All IRQs level-triggered */ for (int i = 0; i < n / 16; i++) { GICD_ICFGR(i) = 0; } /* Enable distributor */ GICD_CTLR = 1; /* Set CPU interface priority mask to accept all */ GICC_PMR = 0xFF; /* Enable CPU interface */ GICC_CTLR = 1; } void gic_enable_irq(int irq) { GICD_ISENABLER(irq / 32) = (1U << (irq % 32)); } void gic_disable_irq(int irq) { GICD_ICENABLER(irq / 32) = (1U << (irq % 32)); } int gic_acknowledge(void) { return (int)(GICC_IAR & 0x3FF); } void gic_eoi(int irq) { GICC_EOIR = (uint32_t)irq; }