AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
gic.c
Go to the documentation of this file.
1
15
16#include <core/system.h>
17#include <cpu/io.h>
18#include <platform/virt.h>
19
20/* The distributor's registers, and the CPU interface's. */
21#define GICD_CTLR 0x000
22#define GICD_ISENABLER(n) (0x100 + 4 * (n))
23#define GICD_ICENABLER(n) (0x180 + 4 * (n))
24#define GICD_IPRIORITYR(n) (0x400 + 4 * (n))
25#define GICD_ITARGETSR(n) (0x800 + 4 * (n))
26#define GICD_ICFGR(n) (0xC00 + 4 * (n))
27
28#define GICC_CTLR 0x000
29#define GICC_PMR 0x004
30#define GICC_IAR 0x00C
31#define GICC_EOIR 0x010
32
35
38void gic_setup(void)
39{
40 mmio_write32(gicd + GICD_CTLR, 0);
41
42 /* every interrupt masked, of a middle priority, sent to CPU 0 */
43 for (unsigned i = 0; i < IRQ_NR / 32; ++i)
44 mmio_write32(gicd + GICD_ICENABLER(i), 0xFFFFFFFF);
45
46 for (unsigned i = 0; i < IRQ_NR / 4; ++i) {
47 mmio_write32(gicd + GICD_IPRIORITYR(i), 0xA0A0A0A0);
48
49 if (i >= 8) /* SPIs only (a PPI's target is its own CPU) */
50 mmio_write32(gicd + GICD_ITARGETSR(i), 0x01010101);
51 }
52
53 mmio_write32(gicd + GICD_CTLR, 1);
54
55 /* the CPU interface lets every priority through */
56 mmio_write32(gicc + GICC_PMR, 0xF0);
57 mmio_write32(gicc + GICC_CTLR, 1);
58}
59
65void gic_enable(unsigned irq)
66{
67 mmio_write32(gicd + GICD_ISENABLER(irq / 32), 1U << (irq % 32));
68}
69
75void gic_disable(unsigned irq)
76{
77 mmio_write32(gicd + GICD_ICENABLER(irq / 32), 1U << (irq % 32));
78}
79
85unsigned gic_ack(void)
86{
87 return mmio_read32(gicc + GICC_IAR) & 0x3FF;
88}
89
95void gic_eoi(unsigned irq)
96{
97 mmio_write32(gicc + GICC_EOIR, irq);
98}
#define GICD_CTLR
Definition gic.c:21
static uintptr_t gicc
Definition gic.c:34
void gic_setup(void)
Sets up the GIC at boot: every interrupt masked, of the same priority, and sent to CPU 0.
Definition gic.c:38
#define GICC_CTLR
Definition gic.c:28
#define GICD_ICENABLER(n)
Definition gic.c:23
static uintptr_t gicd
Definition gic.c:33
#define GICD_ITARGETSR(n)
Definition gic.c:25
#define GICC_IAR
Definition gic.c:30
void gic_eoi(unsigned irq)
Tells the GIC that an interrupt has been handled (end of interrupt).
Definition gic.c:95
#define GICD_ISENABLER(n)
Definition gic.c:22
#define GICC_PMR
Definition gic.c:29
#define GICD_IPRIORITYR(n)
Definition gic.c:24
unsigned gic_ack(void)
Acknowledges the interrupt that came.
Definition gic.c:85
void gic_disable(unsigned irq)
Disables (masks) an interrupt.
Definition gic.c:75
void gic_enable(unsigned irq)
Enables (unmasks) an interrupt.
Definition gic.c:65
#define GICC_EOIR
Definition gic.c:31
__SIZE_TYPE__ uintptr_t
Definition stddef.h:12
#define VIRT_REG(base)
Definition virt.h:30
#define VIRT_GICC
Definition virt.h:14
#define VIRT_GICD
Definition virt.h:13
#define IRQ_NR
Definition virt.h:43