|
XenevaOS
|
#include <Hal/AA64/gic.h>#include <aucon.h>#include <Mm/vmmngr.h>#include <Hal/AA64/aa64lowlevel.h>#include <Drivers/uart.h>#include <process.h>#include <dtb.h>#include <Hal/AA64/sched.h>#include <Board/RPI3bp/rpi3bp.h>
Macros | |
| #define | GICD(n) (n.gicDMMIO) |
| #define | GICD_CTLR 0x0000 |
| #define | GICD_TYPER 0x0004 |
| #define | GICD_IIDR 0x0008 |
| #define | GICD_TYPER2 0x000C |
| #define | GICD_PIDR2 0xFFE8 |
| #define | GICD_PIDR2_ARCHREV(x) (((x) >> 4) & 0xF) |
| #define | GIC_VERSION_1 0x1 |
| #define | GIC_VERSION_2 0x2 |
| #define | GIC_VERSION_3 0x3 |
| #define | GIC_VERSION_4 0x4 |
| #define | GICD_ISENABLER(n) (*(volatile uint32_t*)(GICD(__gic) + 0x100 + 4*(n))) |
| #define | GICD_IPRIORITYR(n) (0x400 + (n)) |
| #define | GICD_IGROUPR(n) (*(volatile uint32_t*)(GICD(__gic) + 0x080 + 4*(n))) |
| #define | GICD_ICENABLE(n) (*(volatile uint32_t*)(GICD(__gic) + 0x180 + (n*4))) |
| #define | GICD_ICFGR(n) (*(volatile uint32_t*)(GICD(__gic) + 0x0C00 + (n*4))) |
| #define | GICD_ITARGETSR(n) (*(volatile uint32_t*)(GICD(__gic) + 0x0800 + (n*4))) |
| #define | GICD_IROUTER(n) (0x6000 + 8*(n)) |
| #define | GICD_ICPENDR(n) (0x280 + (n/32)*4) |
| #define | ISPENDING0 0x200 |
| #define | GICC_CTLR 0x0000 |
| #define | GICC_PMR 0x0004 |
| #define | GICC_BPR 0x0008 |
| #define | GICC_IAR 0x000C |
| #define | GICC_EOIR 0x0010 |
| #define | GICC_HPPIR 0x0018 |
| #define | GICC_ABPR 0x001C |
| #define | GICC_IIDR 0x00FC |
| #define | GICC(n) (n.gicCMMIO) |
| #define | GICR_CTLR 0x0000 |
| #define | GICR_IIDR 0x0004 |
| #define | GICR_WAKER 0x0014 |
| #define | GICR_TYPER 0x008 |
| #define | GICR_STRIDE 0x20000UL |
| #define | GICR_IGROUPR0 0x10080 |
| #define | GICR_ISENABLER0 0x10100 |
| #define | GICR_ICENABLER0 0x10180 |
| #define | GICR_IPRIORITYR(n) (0x10400 + (n)*4) |
| #define | GICR_SGI_BASE 0x10000 |
| #define | GICR_WAKER_PS (1u << 1) |
| #define | GICR_WAKER_CA (1u << 2) |
| #define | GICR_CTLR_RWP (1u << 3) |
| #define | GICR(n) (n.gicRMMIO) |
| #define | MAX_SPIS 1024 |
| #define | SET_SPI_NS 0x040 |
| #define | SET_SPI_S 0x080 |
| #define | GICV2M_MSI_TYPER 0x008 |
| #define | GICV2M_MSI_SETSPI_NS 0x040 |
| #define | GICV2M_MSI_IIDR 0xFCC |
| #define | GICV2_CPUID_SHIFT 10 |
Typedefs | |
| typedef void(* | irq_callback) (int spi) |
Functions | |
| void | gic_outqw (uint64_t *mmio_, int reg, uint64_t value) |
| gic_outqw – writes a value to mmio registers in qword | |
| void | gic_outl_ (uint64_t *mmio_, int reg, uint32_t value) |
| gic_outl_ – writes a value to mmio register in dword | |
| uint32_t | gic_inl_ (uint64_t *mmio_, int reg) |
| gic_inl_ – reads a value from mmio register in dword | |
| void | gic_outw_ (uint64_t *mmio_, int reg, uint16_t value) |
| gic_outw_ – writes a value to mmio register in word | |
| uint16_t | gic_inw_ (uint64_t *mmio_, int reg) |
| gic_inw_ – reads a value from mmio register in word | |
| void | gic_outb_ (uint64_t *mmio_, int reg, uint8_t value) |
| gic_outb_ – writes a value to mmio register in byte | |
| uint8_t | gic_inb_ (uint64_t *mmio_, int reg) |
| gic_inb_ – reads a value from mmio register in byte | |
| GIC * | AuGetSystemGIC () |
| uint64_t | AuGICGetMSIAddress (int interruptID) |
| AuGICGetMSIAddress – calculate and return MSI address for given spi offset. | |
| uint32_t | AuGICGetMSIData (int interruptID) |
| AuGICGetMSIData – obtains composited MSI data address of respected interruptID, useful in PCIe. | |
| int | AuGICAllocateSPI () |
| AuGICAllocateSPI – allocates Shared Peripheral interrupt ID. | |
| void | AuGICDeallocateSPI (int spiID) |
| AuGICDeallocateSPI – free up an used SPI id. | |
| void | GICv2MInitialize () |
| uint32_t | GICVerifyVersion () |
| GICVerifyVersion – getting the version detail inorder to control initialization sequence. | |
| void | GICRInitialize (int cpu_num) |
| GICRInitialize – initialize GIC redistributor. | |
| void | GICInitialize () |
| GICInitialize – initialize the gic controller, it can be parsed through ACPI MADT or hard-coding. | |
| void | GICREnablePPI (uint32_t cpu, uint32_t intid) |
| void | GICRSetPPIPriority (uint32_t cpu, uint32_t intid, uint8_t prio) |
| void | GICEnableIRQ (uint32_t irq) |
| void | GICSetEdgeTriggered (uint32_t irq) |
| void | GICIsIRQEdgeTriggered (uint32_t irq) |
| void | GICEnableSPIIRQ (uint32_t irq) |
| GICEnableIRQ – enable an IRQ. | |
| void | GICSetTargetCPU (int spi) |
| void | GICClearPendingIRQ (uint32_t irq) |
| void | GICCheckPending (uint32_t irq) |
| uint32_t | GICReadIAR () |
| GICReadIAR – read interrupt acknowledge register. | |
| void | GICSendEOI (uint32_t irqnum) |
| GICSendEOI –sends end of interrupt to GIC cpu interface. | |
| void | GICSetupTimer () |
| void | GICRegisterSPIHandler (void *fptr, int spi) |
| GICRegisterSPIHandler – register a spi handler to callback list. | |
| void | GICCallSPIHandler (int spi) |
| GICCallSPIHandler – jump to a callback handler associated with given spi number. | |
Variables | |
| GIC | __gic |
| uint32_t * | gic_regs |
| uint32_t * | gicc_regs |
| uint64_t * | gic_dist_mmio |
| uint64_t * | gic_redist_mmio |
BSD 2-Clause License
Copyright (c) 2022-2025, Manas Kamal Choudhury All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
| #define GIC_VERSION_1 0x1 |
| #define GIC_VERSION_2 0x2 |
| #define GIC_VERSION_3 0x3 |
| #define GIC_VERSION_4 0x4 |
| #define GICC | ( | n | ) | (n.gicCMMIO) |
| #define GICC_ABPR 0x001C |
| #define GICC_BPR 0x0008 |
| #define GICC_CTLR 0x0000 |
cpu registers offsets
| #define GICC_EOIR 0x0010 |
| #define GICC_HPPIR 0x0018 |
| #define GICC_IAR 0x000C |
| #define GICC_IIDR 0x00FC |
| #define GICC_PMR 0x0004 |
| #define GICD | ( | n | ) | (n.gicDMMIO) |
distributor registers
| #define GICD_CTLR 0x0000 |
| #define GICD_ICPENDR | ( | n | ) | (0x280 + (n/32)*4) |
| #define GICD_IIDR 0x0008 |
| #define GICD_IPRIORITYR | ( | n | ) | (0x400 + (n)) |
| #define GICD_IROUTER | ( | n | ) | (0x6000 + 8*(n)) |
| #define GICD_PIDR2 0xFFE8 |
| #define GICD_PIDR2_ARCHREV | ( | x | ) | (((x) >> 4) & 0xF) |
| #define GICD_TYPER 0x0004 |
| #define GICD_TYPER2 0x000C |
| #define GICR | ( | n | ) | (n.gicRMMIO) |
| #define GICR_CTLR 0x0000 |
| #define GICR_CTLR_RWP (1u << 3) |
| #define GICR_ICENABLER0 0x10180 |
| #define GICR_IGROUPR0 0x10080 |
| #define GICR_IIDR 0x0004 |
| #define GICR_IPRIORITYR | ( | n | ) | (0x10400 + (n)*4) |
| #define GICR_ISENABLER0 0x10100 |
| #define GICR_SGI_BASE 0x10000 |
| #define GICR_STRIDE 0x20000UL |
| #define GICR_TYPER 0x008 |
| #define GICR_WAKER 0x0014 |
| #define GICR_WAKER_CA (1u << 2) |
| #define GICR_WAKER_PS (1u << 1) |
| #define GICV2_CPUID_SHIFT 10 |
| #define GICV2M_MSI_IIDR 0xFCC |
| #define GICV2M_MSI_SETSPI_NS 0x040 |
| #define GICV2M_MSI_TYPER 0x008 |
| #define ISPENDING0 0x200 |
| #define MAX_SPIS 1024 |
| #define SET_SPI_NS 0x040 |
| #define SET_SPI_S 0x080 |
| typedef void(* irq_callback) (int spi) |
| GIC * AuGetSystemGIC | ( | ) |
| int AuGICAllocateSPI | ( | ) |
AuGICAllocateSPI – allocates Shared Peripheral interrupt ID.
| void AuGICDeallocateSPI | ( | int | spiID | ) |
AuGICDeallocateSPI – free up an used SPI id.
| spiID | – target spi id |
| uint64_t AuGICGetMSIAddress | ( | int | interruptID | ) |
AuGICGetMSIAddress – calculate and return MSI address for given spi offset.
| interruptID | – spi offset |
| uint32_t AuGICGetMSIData | ( | int | interruptID | ) |
AuGICGetMSIData – obtains composited MSI data address of respected interruptID, useful in PCIe.
| interruptID | – interrupt ID of device |
gic_inb_ – reads a value from mmio register in byte
| reg | – register |
gic_inl_ – reads a value from mmio register in dword
| reg | – register |
gic_inw_ – reads a value from mmio register in word
| reg | – register |
gic_outb_ – writes a value to mmio register in byte
| reg | – register |
| value | – value to write |
gic_outl_ – writes a value to mmio register in dword
| reg | – register |
| value | – value to write |
gic_outqw – writes a value to mmio registers in qword
| reg | – register |
| value | – value to write |
gic_outw_ – writes a value to mmio register in word
| reg | – register |
| value | – value to write |
| void GICCallSPIHandler | ( | int | spi | ) |
GICCallSPIHandler – jump to a callback handler associated with given spi number.
| spi | – SPI number |
| void GICCheckPending | ( | uint32_t | irq | ) |
| void GICClearPendingIRQ | ( | uint32_t | irq | ) |
| void GICEnableIRQ | ( | uint32_t | irq | ) |
@briefGICEnableIRQ – enable an IRQ
| irq | – IRQ number |
| void GICEnableSPIIRQ | ( | uint32_t | irq | ) |
GICEnableIRQ – enable an IRQ.
GICEnableIRQ – enable an SPI IRQ.
| irq | – IRQ number |
route it to cpu0
| void GICInitialize | ( | ) |
GICInitialize – initialize the gic controller, it can be parsed through ACPI MADT or hard-coding.
@TODO : we need to rely on DTB, here we're doing it manually according to SOC_TARGET build
map Redist to MMIO, for one redistributor 128 KiB, for 4 cores, it consumes 512 KiB 128 pages, for now not supporting multi cores, only one core is needed
| void GICIsIRQEdgeTriggered | ( | uint32_t | irq | ) |
| uint32_t GICReadIAR | ( | ) |
GICReadIAR – read interrupt acknowledge register.
| void GICRegisterSPIHandler | ( | void * | fptr, |
| int | spi | ||
| ) |
GICRegisterSPIHandler – register a spi handler to callback list.
| fptr | – SPI Callback address |
| spi | – SPI number |
| void GICRInitialize | ( | int | cpu_num | ) |
GICRInitialize – initialize GIC redistributor.
| cpu_num | – desired cpu core number |
initialize the cpu interface
| void GICSendEOI | ( | uint32_t | irqnum | ) |
GICSendEOI –sends end of interrupt to GIC cpu interface.
| irqnum | – interrupt ID of the device |
| void GICSetEdgeTriggered | ( | uint32_t | irq | ) |
| void GICSetTargetCPU | ( | int | spi | ) |
| void GICSetupTimer | ( | ) |
| void GICv2MInitialize | ( | ) |
| uint32_t GICVerifyVersion | ( | ) |
GICVerifyVersion – getting the version detail inorder to control initialization sequence.
| GIC __gic |
| uint64_t* gic_dist_mmio |
| uint64_t* gic_redist_mmio |
| uint32_t* gic_regs |
| uint32_t* gicc_regs |