XenevaOS
Loading...
Searching...
No Matches
Macros | Typedefs | Functions | Variables
gic.c File Reference
#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>
Include dependency graph for gic.c:

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
 
GICAuGetSystemGIC ()
 
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_tgic_regs
 
uint32_tgicc_regs
 
uint64_tgic_dist_mmio
 
uint64_tgic_redist_mmio
 

Detailed Description

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:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

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.

Macro Definition Documentation

◆ GIC_VERSION_1

#define GIC_VERSION_1   0x1

◆ GIC_VERSION_2

#define GIC_VERSION_2   0x2

◆ GIC_VERSION_3

#define GIC_VERSION_3   0x3

◆ GIC_VERSION_4

#define GIC_VERSION_4   0x4

◆ GICC

#define GICC (   n)    (n.gicCMMIO)

◆ GICC_ABPR

#define GICC_ABPR   0x001C

◆ GICC_BPR

#define GICC_BPR   0x0008

◆ GICC_CTLR

#define GICC_CTLR   0x0000

cpu registers offsets

◆ GICC_EOIR

#define GICC_EOIR   0x0010

◆ GICC_HPPIR

#define GICC_HPPIR   0x0018

◆ GICC_IAR

#define GICC_IAR   0x000C

◆ GICC_IIDR

#define GICC_IIDR   0x00FC

◆ GICC_PMR

#define GICC_PMR   0x0004

◆ GICD

#define GICD (   n)    (n.gicDMMIO)

distributor registers

◆ GICD_CTLR

#define GICD_CTLR   0x0000

◆ GICD_ICENABLE

#define GICD_ICENABLE (   n)    (*(volatile uint32_t*)(GICD(__gic) + 0x180 + (n*4)))

◆ GICD_ICFGR

#define GICD_ICFGR (   n)    (*(volatile uint32_t*)(GICD(__gic) + 0x0C00 + (n*4)))

◆ GICD_ICPENDR

#define GICD_ICPENDR (   n)    (0x280 + (n/32)*4)

◆ GICD_IGROUPR

#define GICD_IGROUPR (   n)    (*(volatile uint32_t*)(GICD(__gic) + 0x080 + 4*(n)))

◆ GICD_IIDR

#define GICD_IIDR   0x0008

◆ GICD_IPRIORITYR

#define GICD_IPRIORITYR (   n)    (0x400 + (n))

◆ GICD_IROUTER

#define GICD_IROUTER (   n)    (0x6000 + 8*(n))

◆ GICD_ISENABLER

#define GICD_ISENABLER (   n)    (*(volatile uint32_t*)(GICD(__gic) + 0x100 + 4*(n)))

◆ GICD_ITARGETSR

#define GICD_ITARGETSR (   n)    (*(volatile uint32_t*)(GICD(__gic) + 0x0800 + (n*4)))

◆ GICD_PIDR2

#define GICD_PIDR2   0xFFE8

◆ GICD_PIDR2_ARCHREV

#define GICD_PIDR2_ARCHREV (   x)    (((x) >> 4) & 0xF)

◆ GICD_TYPER

#define GICD_TYPER   0x0004

◆ GICD_TYPER2

#define GICD_TYPER2   0x000C

◆ GICR

#define GICR (   n)    (n.gicRMMIO)

◆ GICR_CTLR

#define GICR_CTLR   0x0000

◆ GICR_CTLR_RWP

#define GICR_CTLR_RWP   (1u << 3)

◆ GICR_ICENABLER0

#define GICR_ICENABLER0   0x10180

◆ GICR_IGROUPR0

#define GICR_IGROUPR0   0x10080

◆ GICR_IIDR

#define GICR_IIDR   0x0004

◆ GICR_IPRIORITYR

#define GICR_IPRIORITYR (   n)    (0x10400 + (n)*4)

◆ GICR_ISENABLER0

#define GICR_ISENABLER0   0x10100

◆ GICR_SGI_BASE

#define GICR_SGI_BASE   0x10000

◆ GICR_STRIDE

#define GICR_STRIDE   0x20000UL

◆ GICR_TYPER

#define GICR_TYPER   0x008

◆ GICR_WAKER

#define GICR_WAKER   0x0014

◆ GICR_WAKER_CA

#define GICR_WAKER_CA   (1u << 2)

◆ GICR_WAKER_PS

#define GICR_WAKER_PS   (1u << 1)

◆ GICV2_CPUID_SHIFT

#define GICV2_CPUID_SHIFT   10

◆ GICV2M_MSI_IIDR

#define GICV2M_MSI_IIDR   0xFCC

◆ GICV2M_MSI_SETSPI_NS

#define GICV2M_MSI_SETSPI_NS   0x040

◆ GICV2M_MSI_TYPER

#define GICV2M_MSI_TYPER   0x008

◆ ISPENDING0

#define ISPENDING0   0x200

◆ MAX_SPIS

#define MAX_SPIS   1024

◆ SET_SPI_NS

#define SET_SPI_NS   0x040

◆ SET_SPI_S

#define SET_SPI_S   0x080

Typedef Documentation

◆ irq_callback

typedef void(* irq_callback) (int spi)

Function Documentation

◆ AuGetSystemGIC()

GIC * AuGetSystemGIC ( )

◆ AuGICAllocateSPI()

int AuGICAllocateSPI ( )

AuGICAllocateSPI – allocates Shared Peripheral interrupt ID.

◆ AuGICDeallocateSPI()

void AuGICDeallocateSPI ( int  spiID)

AuGICDeallocateSPI – free up an used SPI id.

Parameters
spiID– target spi id

◆ AuGICGetMSIAddress()

uint64_t AuGICGetMSIAddress ( int  interruptID)

AuGICGetMSIAddress – calculate and return MSI address for given spi offset.

Parameters
interruptID– spi offset
Returns
composited MSI address

◆ AuGICGetMSIData()

uint32_t AuGICGetMSIData ( int  interruptID)

AuGICGetMSIData – obtains composited MSI data address of respected interruptID, useful in PCIe.

Parameters
interruptID– interrupt ID of device

◆ gic_inb_()

uint8_t gic_inb_ ( uint64_t mmio_,
int  reg 
)

gic_inb_ – reads a value from mmio register in byte

Parameters
reg– register
Returns
value read from mmio address in BYTE

◆ gic_inl_()

uint32_t gic_inl_ ( uint64_t mmio_,
int  reg 
)

gic_inl_ – reads a value from mmio register in dword

Parameters
reg– register
Returns
value read from mmio address in DWORD

◆ gic_inw_()

uint16_t gic_inw_ ( uint64_t mmio_,
int  reg 
)

gic_inw_ – reads a value from mmio register in word

Parameters
reg– register
Returns
value read from the mmio address in WORD

◆ gic_outb_()

void gic_outb_ ( uint64_t mmio_,
int  reg,
uint8_t  value 
)

gic_outb_ – writes a value to mmio register in byte

Parameters
reg– register
value– value to write

◆ gic_outl_()

void gic_outl_ ( uint64_t mmio_,
int  reg,
uint32_t  value 
)

gic_outl_ – writes a value to mmio register in dword

Parameters
reg– register
value– value to write

◆ gic_outqw()

void gic_outqw ( uint64_t mmio_,
int  reg,
uint64_t  value 
)

gic_outqw – writes a value to mmio registers in qword

Parameters
reg– register
value– value to write

◆ gic_outw_()

void gic_outw_ ( uint64_t mmio_,
int  reg,
uint16_t  value 
)

gic_outw_ – writes a value to mmio register in word

Parameters
reg– register
value– value to write

◆ GICCallSPIHandler()

void GICCallSPIHandler ( int  spi)

GICCallSPIHandler – jump to a callback handler associated with given spi number.

Parameters
spi– SPI number

◆ GICCheckPending()

void GICCheckPending ( uint32_t  irq)

◆ GICClearPendingIRQ()

void GICClearPendingIRQ ( uint32_t  irq)

◆ GICEnableIRQ()

void GICEnableIRQ ( uint32_t  irq)

@briefGICEnableIRQ – enable an IRQ

Parameters
irq– IRQ number

◆ GICEnableSPIIRQ()

void GICEnableSPIIRQ ( uint32_t  irq)

GICEnableIRQ – enable an IRQ.

GICEnableIRQ – enable an SPI IRQ.

Parameters
irq– IRQ number

route it to cpu0

◆ GICInitialize()

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

◆ GICIsIRQEdgeTriggered()

void GICIsIRQEdgeTriggered ( uint32_t  irq)

◆ GICReadIAR()

uint32_t GICReadIAR ( )

GICReadIAR – read interrupt acknowledge register.

◆ GICRegisterSPIHandler()

void GICRegisterSPIHandler ( void *  fptr,
int  spi 
)

GICRegisterSPIHandler – register a spi handler to callback list.

Parameters
fptr– SPI Callback address
spi– SPI number

◆ GICREnablePPI()

void GICREnablePPI ( uint32_t  cpu,
uint32_t  intid 
)

◆ GICRInitialize()

void GICRInitialize ( int  cpu_num)

GICRInitialize – initialize GIC redistributor.

Parameters
cpu_num– desired cpu core number

initialize the cpu interface

◆ GICRSetPPIPriority()

void GICRSetPPIPriority ( uint32_t  cpu,
uint32_t  intid,
uint8_t  prio 
)

◆ GICSendEOI()

void GICSendEOI ( uint32_t  irqnum)

GICSendEOI –sends end of interrupt to GIC cpu interface.

Parameters
irqnum– interrupt ID of the device

◆ GICSetEdgeTriggered()

void GICSetEdgeTriggered ( uint32_t  irq)

◆ GICSetTargetCPU()

void GICSetTargetCPU ( int  spi)

◆ GICSetupTimer()

void GICSetupTimer ( )

◆ GICv2MInitialize()

void GICv2MInitialize ( )

◆ GICVerifyVersion()

uint32_t GICVerifyVersion ( )

GICVerifyVersion – getting the version detail inorder to control initialization sequence.

Variable Documentation

◆ __gic

GIC __gic

◆ gic_dist_mmio

uint64_t* gic_dist_mmio

◆ gic_redist_mmio

uint64_t* gic_redist_mmio

◆ gic_regs

uint32_t* gic_regs

◆ gicc_regs

uint32_t* gicc_regs