gic.c

Commit: e6209518 Author: jokerz Raw Copy
1
/* gic.c — GIC-400 driver for Raspberry Pi 5 */
2
3
#include "gic.h"
4
5
void gic_init(void) {
6
    /* Disable distributor */
7
    GICD_CTLR = 0;
8
9
    /* Get number of IRQs supported */
10
    int n = ((GICD_TYPER & 0x1F) + 1) * 32;
11
12
    /* Disable all IRQs */
13
    for (int i = 0; i < n / 32; i++) {
14
        GICD_ICENABLER(i) = 0xFFFFFFFF;
15
        GICD_ICACTIVER(i) = 0xFFFFFFFF;
16
    }
17
18
    /* Set all IRQs to lowest priority */
19
    for (int i = 0; i < n / 4; i++) {
20
        GICD_IPRIORITYR(i) = 0xA0A0A0A0;
21
    }
22
23
    /* Target all SPIs to CPU 0 */
24
    for (int i = 8; i < n / 4; i++) {
25
        GICD_ITARGETSR(i) = 0x01010101;  /* CPU 0 */
26
    }
27
28
    /* All IRQs level-triggered */
29
    for (int i = 0; i < n / 16; i++) {
30
        GICD_ICFGR(i) = 0;
31
    }
32
33
    /* Enable distributor */
34
    GICD_CTLR = 1;
35
36
    /* Set CPU interface priority mask to accept all */
37
    GICC_PMR = 0xFF;
38
39
    /* Enable CPU interface */
40
    GICC_CTLR = 1;
41
}
42
43
void gic_enable_irq(int irq) {
44
    GICD_ISENABLER(irq / 32) = (1U << (irq % 32));
45
}
46
47
void gic_disable_irq(int irq) {
48
    GICD_ICENABLER(irq / 32) = (1U << (irq % 32));
49
}
50
51
int gic_acknowledge(void) {
52
    return (int)(GICC_IAR & 0x3FF);
53
}
54
55
void gic_eoi(int irq) {
56
    GICC_EOIR = (uint32_t)irq;
57
}
58