mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
arm64: Add an initial GICv5 driver
Add an initial driver for the GICv5 interrupt controller. This provides host-only support for the GICv5 interrupt controller. It is specified in the ARM-AES-0070 document & based on version 00eac0. In the GICv5 there are 3 interrupt spaces: PPI, SPI, and LPI. Unlike previous interrupt controllers they don't share a single interrupt ID range, so PPI IRQ 1 and SPI IRQ 1 are different interrupts. There is a common irqsrc stricture that encodes this information as it is common across the interrupt types. Unlike previous GIC versions there are no software generated interrupts that can target a configurable collection of CPUs. These have been replaced with LPIs, where each CPU will have one allocated for each IPI type. This driver handles the CPU interface and interrupt routing service (IRS). The CPU interface provides the interface to manage and handle interrupts, while the IRS handles routing LPIs and SPIs to the target CPU. Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D54250
This commit is contained in:
1 parent
cd94485281
commit
c84261da6f
5 files changed
+2695
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,300 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 The FreeBSD Foundation
|
||||
* Copyright (c) 2025 Arm Ltd
|
||||
*
|
||||
* 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 AUTHOR 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/cpu.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/smp.h>
|
||||
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
#include <dev/ofw/ofw_subr.h>
|
||||
|
||||
#include <arm/arm/gic_common.h>
|
||||
#include "gicv5var.h"
|
||||
|
||||
#include "pci_if.h"
|
||||
|
||||
struct gicv5_fdt_devinfo {
|
||||
struct gicv5_devinfo di_base;
|
||||
struct ofw_bus_devinfo di_dinfo;
|
||||
};
|
||||
|
||||
static device_probe_t gicv5_fdt_probe;
|
||||
static device_probe_t gicv5_fdt_attach;
|
||||
|
||||
static ofw_bus_get_devinfo_t gicv5_fdt_get_devinfo;
|
||||
|
||||
static device_method_t gicv5_fdt_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, gicv5_fdt_probe),
|
||||
DEVMETHOD(device_attach, gicv5_fdt_attach),
|
||||
|
||||
/* ofw_bus interface */
|
||||
DEVMETHOD(ofw_bus_get_devinfo, gicv5_fdt_get_devinfo),
|
||||
DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
|
||||
DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
|
||||
DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
|
||||
DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
|
||||
DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
|
||||
|
||||
/* End */
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS_1(gic, gicv5_fdt_driver, gicv5_fdt_methods,
|
||||
sizeof(struct gicv5_softc), gicv5_driver);
|
||||
|
||||
EARLY_DRIVER_MODULE(gicv5, simplebus, gicv5_fdt_driver, 0, 0,
|
||||
BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
|
||||
|
||||
static int
|
||||
gicv5_fdt_probe(device_t dev)
|
||||
{
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
if (!ofw_bus_is_compatible(dev, "arm,gic-v5"))
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "ARM Generic Interrupt Controller v5");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static void
|
||||
gicv5_fdt_add_child(device_t dev, phandle_t node, struct gicv5_irs *irs,
|
||||
pcell_t addr_cells, pcell_t size_cells)
|
||||
{
|
||||
struct gicv5_fdt_devinfo *di;
|
||||
|
||||
di = malloc(sizeof(*di), M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
di->di_base.di_irs = irs;
|
||||
if (ofw_bus_gen_setup_devinfo(&di->di_dinfo, node)) {
|
||||
if (bootverbose) {
|
||||
device_printf(dev,
|
||||
"Could not set up devinfo\n");
|
||||
}
|
||||
free(di, M_DEVBUF);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize and populate resource list. */
|
||||
resource_list_init(&di->di_base.di_rl);
|
||||
ofw_bus_reg_to_rl(dev, node, addr_cells, size_cells,
|
||||
&di->di_base.di_rl);
|
||||
|
||||
if (!gicv5_add_child(dev, &di->di_base)) {
|
||||
if (bootverbose) {
|
||||
device_printf(dev,
|
||||
"Could not add child: %s\n",
|
||||
di->di_dinfo.obd_name);
|
||||
}
|
||||
resource_list_free(&di->di_base.di_rl);
|
||||
ofw_bus_gen_destroy_devinfo(&di->di_dinfo);
|
||||
free(di, M_DEVBUF);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gicv5_fdt_add_irs_children(device_t dev, struct gicv5_irs *irs,
|
||||
phandle_t node, pcell_t addr_cells, pcell_t size_cells)
|
||||
{
|
||||
phandle_t child;
|
||||
|
||||
for (child = OF_child(node); child != 0; child = OF_peer(child))
|
||||
gicv5_fdt_add_child(dev, child, irs, addr_cells, size_cells);
|
||||
}
|
||||
|
||||
static void
|
||||
gicv5_fdt_add_children(device_t dev)
|
||||
{
|
||||
char compat[16];
|
||||
struct gicv5_softc *sc;
|
||||
phandle_t node;
|
||||
pcell_t addr_cells, size_cells;
|
||||
phandle_t child;
|
||||
u_int irs_idx;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
node = ofw_bus_get_node(dev);
|
||||
|
||||
if (OF_getencprop(node, "#address-cells", &addr_cells,
|
||||
sizeof(addr_cells)) == -1) {
|
||||
device_printf(dev, "Unable to read #address-cells\n");
|
||||
return;
|
||||
}
|
||||
if (OF_getencprop(node, "#size-cells", &size_cells,
|
||||
sizeof(size_cells)) == -1) {
|
||||
device_printf(dev, "Unable to read #size-cells\n");
|
||||
return;
|
||||
}
|
||||
|
||||
irs_idx = 0;
|
||||
/* Find children nodes to attach devices to */
|
||||
for (child = OF_child(node); child != 0; child = OF_peer(child)) {
|
||||
if (OF_getprop(child, "compatible", compat, sizeof(compat)) < 0)
|
||||
continue;
|
||||
|
||||
/* Don't connect to the IRS, but connect to its children */
|
||||
if (strcmp(compat, "arm,gic-v5-irs") == 0) {
|
||||
MPASS(irs_idx < sc->gic_nirs);
|
||||
gicv5_fdt_add_irs_children(dev, sc->gic_irs[irs_idx],
|
||||
child, addr_cells, size_cells);
|
||||
irs_idx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
gicv5_fdt_add_child(dev, child, NULL, addr_cells, size_cells);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
gicv5_fdt_attach(device_t dev)
|
||||
{
|
||||
char compat[16];
|
||||
struct gicv5_softc *sc;
|
||||
ssize_t rv;
|
||||
phandle_t child, node;
|
||||
bus_addr_t paddr;
|
||||
bus_size_t size;
|
||||
intptr_t xref;
|
||||
int error, i;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->gic_bus = GIC_BUS_FDT;
|
||||
|
||||
node = ofw_bus_get_node(dev);
|
||||
for (child = OF_child(node); child != 0; child = OF_peer(child)) {
|
||||
if (OF_getprop(child, "compatible", compat, sizeof(compat)) < 0)
|
||||
continue;
|
||||
|
||||
if (strcmp(compat, "arm,gic-v5-irs") != 0)
|
||||
continue;
|
||||
|
||||
sc->gic_nirs++;
|
||||
}
|
||||
if (sc->gic_nirs == 0)
|
||||
panic("%s: Invalid configuration, no IRS defined",
|
||||
device_get_nameunit(dev));
|
||||
sc->gic_irs = mallocarray(sc->gic_nirs, sizeof(sc->gic_irs[0]),
|
||||
M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
i = 0;
|
||||
for (child = OF_child(node); child != 0; child = OF_peer(child)) {
|
||||
cpuset_t cpuset;
|
||||
pcell_t *cpus;
|
||||
|
||||
if (OF_getprop(child, "compatible", compat, sizeof(compat)) < 0)
|
||||
continue;
|
||||
|
||||
if (strcmp(compat, "arm,gic-v5-irs") != 0)
|
||||
continue;
|
||||
|
||||
/* TODO: What to do with a standalone IRS? */
|
||||
rv = OF_getencprop_alloc(child, "cpus", (void **)&cpus);
|
||||
if (rv < 0)
|
||||
continue;
|
||||
|
||||
CPU_ZERO(&cpuset);
|
||||
for (u_int c = 0; c < rv / sizeof(pcell_t); c++) {
|
||||
struct pcpu *pcpu;
|
||||
device_t cpu;
|
||||
uintptr_t v;
|
||||
|
||||
cpu = OF_device_from_xref(cpus[c]);
|
||||
if (cpu == NULL) {
|
||||
device_printf(dev,
|
||||
"Unable to find device for CPU %u\n", c);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't use cpu_get_pcpu here as it expect the
|
||||
* passed in device to be a direct child of the cpu
|
||||
* device.
|
||||
*/
|
||||
if (BUS_READ_IVAR(cpu, dev, CPU_IVAR_PCPU, &v) != 0 ||
|
||||
v == 0) {
|
||||
/*
|
||||
* This can happen when not all CPUs in the
|
||||
* dtb are enabled, e.g. in the Arm FVP.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
pcpu = (struct pcpu *)v;
|
||||
|
||||
CPU_SET(pcpu->pc_cpuid, &cpuset);
|
||||
}
|
||||
|
||||
OF_prop_free(cpus);
|
||||
|
||||
gicv5_irs_init(dev, i, &cpuset);
|
||||
error = ofw_reg_to_paddr(child, 0, &paddr, &size, NULL);
|
||||
if (error != 0)
|
||||
panic("%s: Invalid configuration, no physical address "
|
||||
"or size found for child irs %u",
|
||||
device_get_nameunit(dev), i);
|
||||
|
||||
error = bus_set_resource(dev, SYS_RES_MEMORY, i, paddr, size);
|
||||
if (error != 0)
|
||||
panic("%s: Unable to set memory resource",
|
||||
device_get_nameunit(dev));
|
||||
i++;
|
||||
}
|
||||
|
||||
gicv5_attach(dev);
|
||||
|
||||
xref = OF_xref_from_node(node);
|
||||
sc->gic_pic = intr_pic_register(dev, xref);
|
||||
if (sc->gic_pic == NULL)
|
||||
panic("%s: Unable to register PIC", device_get_nameunit(dev));
|
||||
|
||||
/* Register xref */
|
||||
OF_device_register_xref(xref, dev);
|
||||
intr_ipi_pic_register(dev, 0);
|
||||
|
||||
error = intr_pic_claim_root(dev, xref, gicv5_intr, sc, INTR_ROOT_IRQ);
|
||||
if (error != 0)
|
||||
panic("%s: Unable to claim PIC root", device_get_nameunit(dev));
|
||||
|
||||
gicv5_fdt_add_children(dev);
|
||||
bus_attach_children(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct ofw_bus_devinfo *
|
||||
gicv5_fdt_get_devinfo(device_t dev __unused, device_t child)
|
||||
{
|
||||
struct gicv5_fdt_devinfo *di;
|
||||
|
||||
di = device_get_ivars(child);
|
||||
return (&di->di_dinfo);
|
||||
}
|
||||
@@ -0,0 +1,711 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Arm Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#ifndef _ARM64_GICV5REG_H_
|
||||
#define _ARM64_GICV5REG_H_
|
||||
|
||||
#include <machine/_armreg.h>
|
||||
|
||||
/*
|
||||
* GIC instructions in the SYS instruction space
|
||||
*/
|
||||
|
||||
/*
|
||||
* GIC CDAFF, <Xt>
|
||||
* Interrupt Set Target in the Current Interrupt Domain
|
||||
*/
|
||||
#define gic_cdaff(val) SYS_ARG(GIC_CDAFF, val)
|
||||
#define GIC_CDAFF_op0 1
|
||||
#define GIC_CDAFF_op1 0
|
||||
#define GIC_CDAFF_CRn 12
|
||||
#define GIC_CDAFF_CRm 1
|
||||
#define GIC_CDAFF_op2 3
|
||||
#define GIC_CDAFF_IAFFID_SHIFT 32
|
||||
#define GIC_CDAFF_IAFFID_MASK (0xfffful << GIC_CDAFF_IAFFID_SHIFT)
|
||||
#define GIC_CDAFF_IAFFID(x) \
|
||||
((uint64_t)(x) << GIC_CDAFF_IAFFID_SHIFT)
|
||||
#define GIC_CDAFF_TYPE_SHIFT 29
|
||||
#define GIC_CDAFF_TYPE_MASK (0x7ul << GIC_CDAFF_TYPE_SHIFT)
|
||||
#define GIC_CDAFF_TYPE_LPI (0x2ul << GIC_CDAFF_TYPE_SHIFT)
|
||||
#define GIC_CDAFF_TYPE_SPI (0x3ul << GIC_CDAFF_TYPE_SHIFT)
|
||||
#define GIC_CDAFF_IRM_SHIFT 28
|
||||
#define GIC_CDAFF_IRM_MASK (0x1ul << GIC_CDAFF_IRM_SHIFT)
|
||||
#define GIC_CDAFF_IRM_TARGETED (0x0ul << GIC_CDAFF_IRM_SHIFT)
|
||||
#define GIC_CDAFF_IRM_1ofN (0x1ul << GIC_CDAFF_IRM_SHIFT)
|
||||
#define GIC_CDAFF_ID_SHIFT 0
|
||||
#define GIC_CDAFF_ID_MASK (0xfffffful << GIC_CDAFF_ID_SHIFT)
|
||||
#define GIC_CDAFF_ID(x) ((uint64_t)(x) << GIC_CDAFF_ID_SHIFT)
|
||||
|
||||
/*
|
||||
* GIC CDDI, <Xt>
|
||||
* Interrupt Deactivate in the Current Interrupt Domain
|
||||
*/
|
||||
#define gic_cddi(val) SYS_ARG(GIC_CDDI, val)
|
||||
#define GIC_CDDI_op0 1
|
||||
#define GIC_CDDI_op1 0
|
||||
#define GIC_CDDI_CRn 12
|
||||
#define GIC_CDDI_CRm 2
|
||||
#define GIC_CDDI_op2 0
|
||||
#define GIC_CDDI_Type_SHIFT 29
|
||||
#define GIC_CDDI_Type_MASK (0x7ul << GIC_CDDI_Type_SHIFT)
|
||||
#define GIC_CDDI_Type_PPI (0x1ul << GIC_CDDI_Type_SHIFT)
|
||||
#define GIC_CDDI_Type_LPI (0x2ul << GIC_CDDI_Type_SHIFT)
|
||||
#define GIC_CDDI_Type_SPI (0x3ul << GIC_CDDI_Type_SHIFT)
|
||||
#define GIC_CDDI_ID_SHIFT 0
|
||||
#define GIC_CDDI_ID_MASK (0xfffffful << GIC_CDDI_ID_SHIFT)
|
||||
|
||||
/*
|
||||
* GIC CDDIS, <Xt>
|
||||
* Interrupt Disable in the Current Interrupt Domain
|
||||
*/
|
||||
#define gic_cddis(val) SYS_ARG(GIC_CDDIS, val)
|
||||
#define GIC_CDDIS_op0 1
|
||||
#define GIC_CDDIS_op1 0
|
||||
#define GIC_CDDIS_CRn 12
|
||||
#define GIC_CDDIS_CRm 1
|
||||
#define GIC_CDDIS_op2 0
|
||||
#define GIC_CDDIS_TYPE_SHIFT 29
|
||||
#define GIC_CDDIS_TYPE_WIDTH 3
|
||||
#define GIC_CDDIS_TYPE_MASK (UL(0x7) << GIC_CDDIS_TYPE_SHIFT)
|
||||
#define GIC_CDDIS_TYPE_LPI (UL(0x2) << GIC_CDDIS_TYPE_SHIFT)
|
||||
#define GIC_CDDIS_TYPE_SPI (UL(0x3) << GIC_CDDIS_TYPE_SHIFT)
|
||||
#define GIC_CDDIS_ID_SHIFT 0
|
||||
#define GIC_CDDIS_ID_WIDTH 24
|
||||
#define GIC_CDDIS_ID_MASK (UL(0xffffff) << GIC_CDDIS_ID_SHIFT)
|
||||
|
||||
/*
|
||||
* GIC CDEN, <Xt>
|
||||
* Interrupt Enable in the Current Interrupt Domain
|
||||
*/
|
||||
#define gic_cden(val) SYS_ARG(GIC_CDEN, val)
|
||||
#define GIC_CDEN_op0 1
|
||||
#define GIC_CDEN_op1 0
|
||||
#define GIC_CDEN_CRn 12
|
||||
#define GIC_CDEN_CRm 1
|
||||
#define GIC_CDEN_op2 1
|
||||
#define GIC_CDEN_TYPE_SHIFT 29
|
||||
#define GIC_CDEN_TYPE_WIDTH 3
|
||||
#define GIC_CDEN_TYPE_MASK (UL(0x7) << GIC_CDEN_TYPE_SHIFT)
|
||||
#define GIC_CDEN_TYPE_LPI (UL(0x2) << GIC_CDEN_TYPE_SHIFT)
|
||||
#define GIC_CDEN_TYPE_SPI (UL(0x3) << GIC_CDEN_TYPE_SHIFT)
|
||||
#define GIC_CDEN_ID_SHIFT 0
|
||||
#define GIC_CDEN_ID_WIDTH 24
|
||||
#define GIC_CDEN_ID_MASK (UL(0xffffff) << GIC_CDEN_ID_SHIFT)
|
||||
|
||||
/*
|
||||
* GIC CDEOI, <Xt>
|
||||
* Priority Drop in the Current Interrupt Domain
|
||||
*/
|
||||
#define gic_cdeoi() SYS(GIC_CDEOI)
|
||||
#define GIC_CDEOI_op0 1
|
||||
#define GIC_CDEOI_op1 0
|
||||
#define GIC_CDEOI_CRn 12
|
||||
#define GIC_CDEOI_CRm 1
|
||||
#define GIC_CDEOI_op2 7
|
||||
|
||||
/*
|
||||
* GIC CDHM, <Xt>
|
||||
* Interrupt Handling mode state in the Current Interrupt Domain
|
||||
*/
|
||||
#define gic_cdhm(val) SYS_ARG(GIC_CDHM, val)
|
||||
#define GIC_CDHM_op0 1
|
||||
#define GIC_CDHM_op1 0
|
||||
#define GIC_CDHM_CRn 12
|
||||
#define GIC_CDHM_CRm 2
|
||||
#define GIC_CDHM_op2 1
|
||||
#define GIC_CDHM_HM_MASK (0x1ul << 32)
|
||||
#define GIC_CDHM_HM_EDGE (0x0ul << 32)
|
||||
#define GIC_CDHM_HM_LEVEL (0x1ul << 32)
|
||||
#define GIC_CDHM_TYPE_SHIFT 29
|
||||
#define GIC_CDHM_TYPE_MASK (0x7ul << GIC_CDHM_TYPE_SHIFT)
|
||||
#define GIC_CDHM_TYPE_PPI (0x1ul << GIC_CDHM_TYPE_SHIFT)
|
||||
#define GIC_CDHM_TYPE_LPI (0x2ul << GIC_CDHM_TYPE_SHIFT)
|
||||
#define GIC_CDHM_TYPE_SPI (0x3ul << GIC_CDHM_TYPE_SHIFT)
|
||||
#define GIC_CDHM_ID_SHIFT 0
|
||||
#define GIC_CDHM_ID_MASK (0xfffffful << GIC_CDHM_ID_SHIFT)
|
||||
|
||||
/*
|
||||
* GIC CDPEND, <Xt>
|
||||
* Interrupt Set/Clear Pending state in the Current Interrupt Domain
|
||||
*/
|
||||
#define gic_cdpend(val) SYS_ARG(GIC_CDPEND, val);
|
||||
#define GIC_CDPEND_op0 1
|
||||
#define GIC_CDPEND_op1 0
|
||||
#define GIC_CDPEND_CRn 12
|
||||
#define GIC_CDPEND_CRm 1
|
||||
#define GIC_CDPEND_op2 4
|
||||
#define GIC_CDPEND_PENDING_SHIFT 32
|
||||
#define GIC_CDPEND_PENDING_MASK (0x1ul << GIC_CDPEND_PENDING_SHIFT)
|
||||
#define GIC_CDPEND_PENDING_CLEAR (0x0ul << GIC_CDPEND_PENDING_SHIFT)
|
||||
#define GIC_CDPEND_PENDING_SET (0x1ul << GIC_CDPEND_PENDING_SHIFT)
|
||||
#define GIC_CDPEND_TYPE_SHIFT 29
|
||||
#define GIC_CDPEND_TYPE_MASK (0x7ul << GIC_CDPEND_TYPE_SHIFT)
|
||||
#define GIC_CDPEND_TYPE_LPI (0x2ul << GIC_CDPEND_TYPE_SHIFT)
|
||||
#define GIC_CDPEND_TYPE_SPI (0x2ul << GIC_CDPEND_TYPE_SHIFT)
|
||||
#define GIC_CDPEND_ID_SHIFT 0
|
||||
#define GIC_CDPEND_ID_MASK (0xfffffful << GIC_CDPEND_ID_SHIFT)
|
||||
#define GIC_CDPEND_ID(x) ((uint64_t)(x) << GIC_CDPEND_ID_SHIFT)
|
||||
|
||||
/*
|
||||
* GIC CDPRI, <Xt>
|
||||
* Interrupt Set priority in the Current Interrupt Domain
|
||||
*/
|
||||
#define gic_cdpri(val) SYS_ARG(GIC_CDPRI, val)
|
||||
#define GIC_CDPRI_op0 1
|
||||
#define GIC_CDPRI_op1 0
|
||||
#define GIC_CDPRI_CRn 12
|
||||
#define GIC_CDPRI_CRm 1
|
||||
#define GIC_CDPRI_op2 2
|
||||
#define GIC_CDPRI_PRORITY_SHIFT 35
|
||||
#define GIC_CDPRI_PRORITY_MASK (0x1ful << GIC_CDPRI_PRORITY_SHIFT)
|
||||
#define GIC_CDPRI_PRORITY(x) \
|
||||
((uint64_t)(x) << GIC_CDPRI_PRORITY_SHIFT)
|
||||
#define GIC_CDPRI_TYPE_SHIFT 29
|
||||
#define GIC_CDPRI_TYPE_MASK (0x7ul << GIC_CDPRI_TYPE_SHIFT)
|
||||
#define GIC_CDPRI_TYPE_LPI (0x2ul << GIC_CDPRI_TYPE_SHIFT)
|
||||
#define GIC_CDPRI_TYPE_SPI (0x3ul << GIC_CDPRI_TYPE_SHIFT)
|
||||
#define GIC_CDPRI_ID_SHIFT 0
|
||||
#define GIC_CDPRI_ID_MASK (0xfffffful << GIC_CDPRI_ID_SHIFT)
|
||||
#define GIC_CDPRI_ID(x) ((uint64_t)(x) << GIC_CDPRI_ID_SHIFT)
|
||||
|
||||
/*
|
||||
* GIC CDRCFG, <Xt>
|
||||
* Interrupt Set priority in the Current Interrupt Domain
|
||||
*/
|
||||
#define gic_cdrcfg(val) SYS_ARG(GIC_CDRCFG, val)
|
||||
#define GIC_CDRCFG_op0 1
|
||||
#define GIC_CDRCFG_op1 0
|
||||
#define GIC_CDRCFG_CRn 12
|
||||
#define GIC_CDRCFG_CRm 1
|
||||
#define GIC_CDRCFG_op2 5
|
||||
|
||||
/*
|
||||
* GICR <Xt>, CDIA
|
||||
* Interrupt Acknowledge in the Current Interrupt Domain
|
||||
*/
|
||||
#define gicr_cdia() SYSL(GICR_CDIA)
|
||||
#define GICR_CDIA_op0 1
|
||||
#define GICR_CDIA_op1 0
|
||||
#define GICR_CDIA_CRn 12
|
||||
#define GICR_CDIA_CRm 3
|
||||
#define GICR_CDIA_op2 0
|
||||
|
||||
|
||||
/*
|
||||
* GICR <Xt>, CDNMIA
|
||||
* Non-maskable Interrupt Acknowledge in the Current Interrupt Domain
|
||||
*/
|
||||
#define gicr_cdnmia() SYSL(GICR_CDNMIA)
|
||||
#define GICR_CDNMIA_op0 1
|
||||
#define GICR_CDNMIA_op1 0
|
||||
#define GICR_CDNMIA_CRn 12
|
||||
#define GICR_CDNMIA_CRm 3
|
||||
#define GICR_CDNMIA_op2 1
|
||||
|
||||
/*
|
||||
* GSB ACK
|
||||
* GIC Synchronization Barrier Interrupt Acknowledge
|
||||
*/
|
||||
#define gsb_ack() SYS(GSB_ACK)
|
||||
#define GSB_ACK_op0 1
|
||||
#define GSB_ACK_op1 0
|
||||
#define GSB_ACK_CRn 12
|
||||
#define GSB_ACK_CRm 0
|
||||
#define GSB_ACK_op2 1
|
||||
|
||||
/*
|
||||
* GSB SYS
|
||||
* GIC Synchronization Barrier System
|
||||
*/
|
||||
#define gsb_sys() SYS(GSB_SYS)
|
||||
#define GSB_SYS_op0 1
|
||||
#define GSB_SYS_op1 0
|
||||
#define GSB_SYS_CRn 12
|
||||
#define GSB_SYS_CRm 0
|
||||
#define GSB_SYS_op2 0
|
||||
|
||||
|
||||
/*
|
||||
* CPU interface registers
|
||||
*/
|
||||
|
||||
/*
|
||||
* ICC_APR_EL1
|
||||
* Interrupt Controller Physical Active Priorities Register
|
||||
*/
|
||||
#define ICC_APR_EL1 MRS_REG_ALT_NAME(ICC_APR_EL1)
|
||||
#define ICC_APR_EL1_op0 3
|
||||
#define ICC_APR_EL1_op1 1
|
||||
#define ICC_APR_EL1_CRn 12
|
||||
#define ICC_APR_EL1_CRm 0
|
||||
#define ICC_APR_EL1_op2 0
|
||||
#define ICC_APR_P(x) (1ul << (x))
|
||||
|
||||
/*
|
||||
* ICC_CR0_EL1
|
||||
* Interrupt Controller EL1 Physical Control Register
|
||||
*/
|
||||
#define ICC_CR0_EL1 MRS_REG_ALT_NAME(ICC_CR0_EL1)
|
||||
#define ICC_CR0_EL1_op0 3
|
||||
#define ICC_CR0_EL1_op1 1
|
||||
#define ICC_CR0_EL1_CRn 12
|
||||
#define ICC_CR0_EL1_CRm 0
|
||||
#define ICC_CR0_EL1_op2 1
|
||||
#define ICC_CR0_PID (0x1ul << 38)
|
||||
#define ICC_CR0_IPPT_SHIFT 32
|
||||
#define ICC_CR0_IPPT_MASK (0x1ful << ICC_CR0_IPPT_SHIFT)
|
||||
#define ICC_CR0_EN (0x1ul << 0)
|
||||
|
||||
/*
|
||||
* ICC_HAPR_EL1
|
||||
* Interrupt Controller Physical Highest Active Priority Register
|
||||
*/
|
||||
#define ICC_HAPR_EL1 MRS_REG_ALT_NAME(ICC_HAPR_EL1)
|
||||
#define ICC_HAPR_EL1_op0 3
|
||||
#define ICC_HAPR_EL1_op1 1
|
||||
#define ICC_HAPR_EL1_CRn 12
|
||||
#define ICC_HAPR_EL1_CRm 0
|
||||
#define ICC_HAPR_EL1_op2 3
|
||||
#define ICC_HAPR_PRIORITY_SHIFT 0
|
||||
#define ICC_HAPR_PRIORITY_MASK (0xfful << ICC_HAPR_PRIORITY_SHIFT)
|
||||
|
||||
/*
|
||||
* ICC_HPPIR_EL1
|
||||
* Interrupt Controller Physical Highest Priority Pending Interrupt Register
|
||||
*/
|
||||
#define ICC_HPPIR_EL1 MRS_REG_ALT_NAME(ICC_HPPIR_EL1)
|
||||
#define ICC_HPPIR_EL1_op0 3
|
||||
#define ICC_HPPIR_EL1_op1 0
|
||||
#define ICC_HPPIR_EL1_CRn 12
|
||||
#define ICC_HPPIR_EL1_CRm 10
|
||||
#define ICC_HPPIR_EL1_op2 3
|
||||
#define ICC_HPPIR_HPPIV (0x1ul << 32)
|
||||
#define ICC_HPPIR_TYPE_SHIFT 29
|
||||
#define ICC_HPPIR_TYPE_MASK (0x7ul << ICC_HPPIR_TYPE_SHIFT)
|
||||
#define ICC_HPPIR_TYPE_PPI (0x1ul << ICC_HPPIR_TYPE_SHIFT)
|
||||
#define ICC_HPPIR_TYPE_LPI (0x2ul << ICC_HPPIR_TYPE_SHIFT)
|
||||
#define ICC_HPPIR_TYPE_SPI (0x3ul << ICC_HPPIR_TYPE_SHIFT)
|
||||
#define ICC_HPPIR_ID_SHIFT 0
|
||||
#define ICC_HPPIR_ID_MASK (0xfffffful << ICC_HPPIR_ID_SHIFT)
|
||||
|
||||
/*
|
||||
* ICC_IAFFID_EL1
|
||||
* Interrupt Controller PE Interrupt Affinity ID Register
|
||||
*/
|
||||
#define ICC_IAFFIDR_EL1 MRS_REG_ALT_NAME(ICC_IAFFIDR_EL1)
|
||||
#define ICC_IAFFIDR_EL1_op0 3
|
||||
#define ICC_IAFFIDR_EL1_op1 0
|
||||
#define ICC_IAFFIDR_EL1_CRn 12
|
||||
#define ICC_IAFFIDR_EL1_CRm 10
|
||||
#define ICC_IAFFIDR_EL1_op2 5
|
||||
#define ICC_IAFFIDR_IAFFID_SHIFT 0
|
||||
#define ICC_IAFFIDR_IAFFID_MASK (0xfffful << ICC_IAFFIDR_IAFFID_SHIFT)
|
||||
#define ICC_IAFFIDR_IAFFID_VAL(x) \
|
||||
(((x) & ICC_IAFFIDR_IAFFID_MASK) >> ICC_IAFFIDR_IAFFID_SHIFT)
|
||||
|
||||
/*
|
||||
* ICC_ICSR_EL1
|
||||
* Interrupt Controller Interrupt Configuration and State Register
|
||||
*/
|
||||
#define ICC_ICSR_EL1 MRS_REG_ALT_NAME(ICC_ICSR_EL1)
|
||||
#define ICC_ICSR_EL1_op0 3
|
||||
#define ICC_ICSR_EL1_op1 0
|
||||
#define ICC_ICSR_EL1_CRn 12
|
||||
#define ICC_ICSR_EL1_CRm 10
|
||||
#define ICC_ICSR_EL1_op2 4
|
||||
#define ICC_ICSR_IAFFID_SHIFT 32
|
||||
#define ICC_ICSR_IAFFID_MASK (0xfffful << ICC_ICSR_IAFFID_SHIFT)
|
||||
#define ICC_ICSR_Priority_SHIFT 11
|
||||
#define ICC_ICSR_Priority_MASK (0x1ful << ICC_ICSR_Priority_SHIFT)
|
||||
#define ICC_ICSR_HM (0x1ul << 5)
|
||||
#define ICC_ICSR_Active (0x1ul << 4)
|
||||
#define ICC_ICSR_IRM (0x1ul << 3)
|
||||
#define ICC_ICSR_Pending (0x1ul << 2)
|
||||
#define ICC_ICSR_Enabled (0x1ul << 1)
|
||||
#define ICC_ICSR_F (0x1ul << 0)
|
||||
|
||||
/*
|
||||
* ICC_IDR0_EL1
|
||||
* Interrupt Controller ID Register 0
|
||||
*/
|
||||
#define ICC_IDR0_EL1 MRS_REG_ALT_NAME(ICC_IDR0_EL1)
|
||||
#define ICC_IDR0_EL1_op0 3
|
||||
#define ICC_IDR0_EL1_op1 0
|
||||
#define ICC_IDR0_EL1_CRn 12
|
||||
#define ICC_IDR0_EL1_CRm 10
|
||||
#define ICC_IDR0_EL1_op2 2
|
||||
#define ICC_IDR0_GCIE_LEGACY_SHIFT 8
|
||||
#define ICC_IDR0_GCIE_LEGACY_MASK (0xful << ICC_IDR0_GCIE_LEGACY_SHIFT)
|
||||
#define ICC_IDR0_PRI_BITS_SHIFT 4
|
||||
#define ICC_IDR0_PRI_BITS_MASK (0xful << ICC_IDR0_PRI_BITS_SHIFT)
|
||||
#define ICC_IDR0_PRI_BITS_4 (0x3ul << ICC_IDR0_PRI_BITS_SHIFT)
|
||||
#define ICC_IDR0_PRI_BITS_5 (0x4ul << ICC_IDR0_PRI_BITS_SHIFT)
|
||||
#define ICC_IDR0_ID_BITS_SHIFT 0
|
||||
#define ICC_IDR0_ID_BITS_MASK (0xful << ICC_IDR0_ID_BITS_SHIFT)
|
||||
#define ICC_IDR0_ID_BITS_16 (0x0ul << ICC_IDR0_ID_BITS_SHIFT)
|
||||
#define ICC_IDR0_ID_BITS_24 (0x1ul << ICC_IDR0_ID_BITS_SHIFT)
|
||||
|
||||
/*
|
||||
* ICC_PCR_EL1
|
||||
* Interrupt Controller Physical Interrupt Priority Control Register
|
||||
* This register is self-synchronizing
|
||||
*/
|
||||
#define ICC_PCR_EL1 MRS_REG_ALT_NAME(ICC_PCR_EL1)
|
||||
#define ICC_PCR_EL1_op0 3
|
||||
#define ICC_PCR_EL1_op1 1
|
||||
#define ICC_PCR_EL1_CRn 12
|
||||
#define ICC_PCR_EL1_CRm 0
|
||||
#define ICC_PCR_EL1_op2 2
|
||||
#define ICC_PCR_PRIORITY_SHIFT 0
|
||||
#define ICC_PCR_PRIORITY_MASK (0x1ful << ICC_PCR_PRIORITY_SHIFT)
|
||||
#define ICC_PCR_PRIORITY_LOWEST (0x1ful << ICC_PCR_PRIORITY_SHIFT)
|
||||
|
||||
/*
|
||||
* PPI registers
|
||||
*/
|
||||
|
||||
/*
|
||||
* ICC_PPI_CACTIVER<n>_EL1
|
||||
* Interrupt Controller Physical PPI Clear Active Register
|
||||
*/
|
||||
#define ICC_PPI_CACTIVER0_EL1 MRS_REG_ALT_NAME(ICC_PPI_CACTIVER0_EL1)
|
||||
#define ICC_PPI_CACTIVER0_EL1_op0 3
|
||||
#define ICC_PPI_CACTIVER0_EL1_op1 0
|
||||
#define ICC_PPI_CACTIVER0_EL1_CRn 12
|
||||
#define ICC_PPI_CACTIVER0_EL1_CRm 13
|
||||
#define ICC_PPI_CACTIVER0_EL1_op2 0
|
||||
|
||||
#define ICC_PPI_CACTIVER1_EL1 MRS_REG_ALT_NAME(ICC_PPI_CACTIVER1_EL1)
|
||||
#define ICC_PPI_CACTIVER1_EL1_op0 3
|
||||
#define ICC_PPI_CACTIVER1_EL1_op1 0
|
||||
#define ICC_PPI_CACTIVER1_EL1_CRn 12
|
||||
#define ICC_PPI_CACTIVER1_EL1_CRm 13
|
||||
#define ICC_PPI_CACTIVER1_EL1_op2 1
|
||||
|
||||
/*
|
||||
* ICC_PPI_CPENDR<n>_EL1
|
||||
* Interrupt Controller Physical PPI Clear Pending State Registers
|
||||
*/
|
||||
#define ICC_PPI_CPENDR0_EL1 MRS_REG_ALT_NAME(ICC_PPI_CPENDR0_EL1)
|
||||
#define ICC_PPI_CPENDR0_EL1_op0 3
|
||||
#define ICC_PPI_CPENDR0_EL1_op1 0
|
||||
#define ICC_PPI_CPENDR0_EL1_CRn 12
|
||||
#define ICC_PPI_CPENDR0_EL1_CRm 13
|
||||
#define ICC_PPI_CPENDR0_EL1_op2 4
|
||||
|
||||
#define ICC_PPI_CPENDR1_EL1 MRS_REG_ALT_NAME(ICC_PPI_CPENDR1_EL1)
|
||||
#define ICC_PPI_CPENDR1_EL1_op0 3
|
||||
#define ICC_PPI_CPENDR1_EL1_op1 0
|
||||
#define ICC_PPI_CPENDR1_EL1_CRn 12
|
||||
#define ICC_PPI_CPENDR1_EL1_CRm 13
|
||||
#define ICC_PPI_CPENDR1_EL1_op2 5
|
||||
|
||||
/*
|
||||
* ICC_PPI_ENABLER<n>_EL1
|
||||
* Interrupt Controller Physical PPI Enable Registers
|
||||
*/
|
||||
#define ICC_PPI_ENABLER0_EL1 MRS_REG_ALT_NAME(ICC_PPI_ENABLER0_EL1)
|
||||
#define ICC_PPI_ENABLER0_EL1_op0 3
|
||||
#define ICC_PPI_ENABLER0_EL1_op1 0
|
||||
#define ICC_PPI_ENABLER0_EL1_CRn 12
|
||||
#define ICC_PPI_ENABLER0_EL1_CRm 10
|
||||
#define ICC_PPI_ENABLER0_EL1_op2 6
|
||||
|
||||
#define ICC_PPI_ENABLER1_EL1 MRS_REG_ALT_NAME(ICC_PPI_ENABLER1_EL1)
|
||||
#define ICC_PPI_ENABLER1_EL1_op0 3
|
||||
#define ICC_PPI_ENABLER1_EL1_op1 0
|
||||
#define ICC_PPI_ENABLER1_EL1_CRn 12
|
||||
#define ICC_PPI_ENABLER1_EL1_CRm 10
|
||||
#define ICC_PPI_ENABLER1_EL1_op2 7
|
||||
|
||||
#define ICC_PPI_ENABLER_MASK(x) (UL(1) << ((x) & 0x3f))
|
||||
#define ICC_PPI_ENABLER_DIS(x) (UL(0) << ((x) & 0x3f))
|
||||
#define ICC_PPI_ENABLER_EN(x) (UL(1) << ((x) & 0x3f))
|
||||
#define ICC_PPI_ENABLER_NONE UL(0)
|
||||
|
||||
/*
|
||||
* ICC_PPI_HMR<n>_EL1
|
||||
* Interrupt Controller Physical PPI Handling mode Register
|
||||
*/
|
||||
#define ICC_PPI_HMR0_EL1 MRS_REG_ALT_NAME(ICC_PPI_HMR0_EL1)
|
||||
#define ICC_PPI_HMR0_EL1_op0 3
|
||||
#define ICC_PPI_HMR0_EL1_op1 0
|
||||
#define ICC_PPI_HMR0_EL1_CRn 12
|
||||
#define ICC_PPI_HMR0_EL1_CRm 10
|
||||
#define ICC_PPI_HMR0_EL1_op2 0
|
||||
|
||||
#define ICC_PPI_HMR1_EL1 MRS_REG_ALT_NAME(ICC_PPI_HMR1_EL1)
|
||||
#define ICC_PPI_HMR1_EL1_op0 3
|
||||
#define ICC_PPI_HMR1_EL1_op1 0
|
||||
#define ICC_PPI_HMR1_EL1_CRn 12
|
||||
#define ICC_PPI_HMR1_EL1_CRm 10
|
||||
#define ICC_PPI_HMR1_EL1_op2 1
|
||||
|
||||
#define ICC_PPI_HMR_MASK(x) (UL(1) << ((x) & 0x3f))
|
||||
#define ICC_PPI_HMR_EDGE(x) (UL(0) << ((x) & 0x3f))
|
||||
#define ICC_PPI_HMR_LEVEL(x) (UL(1) << ((x) & 0x3f))
|
||||
|
||||
/*
|
||||
* ICC_PPI_PRIORITYR<n>_EL1
|
||||
* Interrupt Controller Physical PPI Priority Registers
|
||||
*/
|
||||
#define ICC_PPI_PRIORITYR0_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 14, 0)
|
||||
#define ICC_PPI_PRIORITYR1_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 14, 1)
|
||||
#define ICC_PPI_PRIORITYR2_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 14, 2)
|
||||
#define ICC_PPI_PRIORITYR3_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 14, 3)
|
||||
#define ICC_PPI_PRIORITYR4_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 14, 4)
|
||||
#define ICC_PPI_PRIORITYR5_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 14, 5)
|
||||
#define ICC_PPI_PRIORITYR6_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 14, 6)
|
||||
#define ICC_PPI_PRIORITYR7_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 14, 7)
|
||||
#define ICC_PPI_PRIORITYR8_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 15, 0)
|
||||
#define ICC_PPI_PRIORITYR9_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 15, 1)
|
||||
#define ICC_PPI_PRIORITYR10_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 15, 2)
|
||||
#define ICC_PPI_PRIORITYR11_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 15, 3)
|
||||
#define ICC_PPI_PRIORITYR12_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 15, 4)
|
||||
#define ICC_PPI_PRIORITYR13_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 15, 5)
|
||||
#define ICC_PPI_PRIORITYR14_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 15, 6)
|
||||
#define ICC_PPI_PRIORITYR15_EL1 __MRS_REG_ALT_NAME(3, 0, 12, 15, 7)
|
||||
#define ICC_PPI_PRIORITYR_PRIORITY_SHIFT(n) ((n) * 8)
|
||||
#define ICC_PPI_PRIORITYR_PRIORITY(n, x) \
|
||||
((uint64_t)(x) << ICC_PPI_PRIORITYR_PRIORITY_SHIFT(n))
|
||||
#define ICC_PPI_PRIORITYR_PRIORITY_ALL(x) \
|
||||
(ICC_PPI_PRIORITYR_PRIORITY(0, x) | ICC_PPI_PRIORITYR_PRIORITY(1, x) | \
|
||||
ICC_PPI_PRIORITYR_PRIORITY(2, x) | ICC_PPI_PRIORITYR_PRIORITY(3, x) | \
|
||||
ICC_PPI_PRIORITYR_PRIORITY(4, x) | ICC_PPI_PRIORITYR_PRIORITY(5, x) | \
|
||||
ICC_PPI_PRIORITYR_PRIORITY(6, x) | ICC_PPI_PRIORITYR_PRIORITY(7, x))
|
||||
|
||||
/*
|
||||
* ICC_PPI_SACTIVER<n>_EL1
|
||||
* Interrupt Controller Physical PPI Set Active Register
|
||||
*/
|
||||
#define ICC_PPI_SACTIVER0_EL1 MRS_REG_ALT_NAME(ICC_PPI_SACTIVER0_EL1)
|
||||
#define ICC_PPI_SACTIVER0_EL1_op0 3
|
||||
#define ICC_PPI_SACTIVER0_EL1_op1 0
|
||||
#define ICC_PPI_SACTIVER0_EL1_CRn 12
|
||||
#define ICC_PPI_SACTIVER0_EL1_CRm 13
|
||||
#define ICC_PPI_SACTIVER0_EL1_op2 2
|
||||
|
||||
#define ICC_PPI_SACTIVER1_EL1 MRS_REG_ALT_NAME(ICC_PPI_SACTIVER1_EL1)
|
||||
#define ICC_PPI_SACTIVER1_EL1_op0 3
|
||||
#define ICC_PPI_SACTIVER1_EL1_op1 0
|
||||
#define ICC_PPI_SACTIVER1_EL1_CRn 12
|
||||
#define ICC_PPI_SACTIVER1_EL1_CRm 13
|
||||
#define ICC_PPI_SACTIVER1_EL1_op2 3
|
||||
|
||||
/*
|
||||
* ICC_PPI_SPENDR<n>_EL1
|
||||
* Interrupt Controller Physical PPI Set Pending State Registers
|
||||
*/
|
||||
#define ICC_PPI_SPENDR0_EL1 MRS_REG_ALT_NAME(ICC_PPI_SPENDR0_EL1)
|
||||
#define ICC_PPI_SPENDR0_EL1_op0 3
|
||||
#define ICC_PPI_SPENDR0_EL1_op1 0
|
||||
#define ICC_PPI_SPENDR0_EL1_CRn 12
|
||||
#define ICC_PPI_SPENDR0_EL1_CRm 13
|
||||
#define ICC_PPI_SPENDR0_EL1_op2 6
|
||||
|
||||
#define ICC_PPI_SPENDR1_EL1 MRS_REG_ALT_NAME(ICC_PPI_SPENDR1_EL1)
|
||||
#define ICC_PPI_SPENDR1_EL1_op0 3
|
||||
#define ICC_PPI_SPENDR1_EL1_op1 0
|
||||
#define ICC_PPI_SPENDR1_EL1_CRn 12
|
||||
#define ICC_PPI_SPENDR1_EL1_CRm 13
|
||||
#define ICC_PPI_SPENDR1_EL1_op2 7
|
||||
|
||||
/*
|
||||
* IRS Config Frame registers
|
||||
*/
|
||||
#define IRS_IDR0 0x0000
|
||||
#define IRS_IDR0_PA_RANGE_SHIFT 2
|
||||
#define IRS_IDR0_PA_RANGE_MASK (0xfu << IRS_IDR0_PA_RANGE_SHIFT)
|
||||
#define IRS_IDR0_PA_RANGE_4G (0x0u << IRS_IDR0_PA_RANGE_SHIFT)
|
||||
#define IRS_IDR0_PA_RANGE_64G (0x1u << IRS_IDR0_PA_RANGE_SHIFT)
|
||||
#define IRS_IDR0_PA_RANGE_1T (0x2u << IRS_IDR0_PA_RANGE_SHIFT)
|
||||
#define IRS_IDR0_PA_RANGE_4T (0x3u << IRS_IDR0_PA_RANGE_SHIFT)
|
||||
#define IRS_IDR0_PA_RANGE_16T (0x4u << IRS_IDR0_PA_RANGE_SHIFT)
|
||||
#define IRS_IDR0_PA_RANGE_256T (0x5u << IRS_IDR0_PA_RANGE_SHIFT)
|
||||
#define IRS_IDR0_PA_RANGE_4P (0x6u << IRS_IDR0_PA_RANGE_SHIFT)
|
||||
#define IRS_IDR0_PA_RANGE_64P (0x7u << IRS_IDR0_PA_RANGE_SHIFT)
|
||||
#define IRS_IDR1 0x0004
|
||||
#define IRS_IDR2 0x0008
|
||||
#define IRS_IDR2_ISTMD_SZ_SHIFT 15
|
||||
#define IRS_IDR2_ISTMD_SZ_MASK (0x1ful << IRS_IDR2_ISTMD_SZ_SHIFT)
|
||||
#define IRS_IRD2_ISTMD (0x1u << 14)
|
||||
#define IRS_IDR2_IST_L2SZ_64K (0x1u << 13)
|
||||
#define IRS_IDR2_IST_L2SZ_16K (0x1u << 12)
|
||||
#define IRS_IDR2_IST_L2SZ_4K (0x1u << 11)
|
||||
#define IRS_IDR2_IST_LEVELS (0x1u << 10)
|
||||
#define IRS_IDR2_MIN_LPI_ID_BITS_SHIFT 6
|
||||
#define IRS_IDR2_MIN_LPI_ID_BITS_MASK (0xful << IRS_IDR2_MIN_LPI_ID_BITS_SHIFT)
|
||||
#define IRS_IDR2_MIN_LPI_ID_BITS(x) \
|
||||
(((x) & IRS_IDR2_MIN_LPI_ID_BITS_MASK) >> IRS_IDR2_MIN_LPI_ID_BITS_SHIFT)
|
||||
#define IRS_IDR2_LPI (0x1ul << 5)
|
||||
#define IRS_IDR2_ID_BITS_SHIFT 0
|
||||
#define IRS_IDR2_ID_BITS_MASK (0x1ful << IRS_IDR2_ID_BITS_SHIFT)
|
||||
#define IRS_IDR2_ID_BITS(x) \
|
||||
(((x) & IRS_IDR2_ID_BITS_MASK) >> IRS_IDR2_ID_BITS_SHIFT)
|
||||
#define IRS_IDR3 0x000c
|
||||
#define IRS_IDR4 0x0010
|
||||
#define IRS_IDR5 0x0014
|
||||
#define IRS_IDR5_SPI_RANGE 0x01ffffff
|
||||
#define IRS_IDR6 0x0018
|
||||
#define IRS_IDR6_SPI_IRS_RANGE 0x00ffffff
|
||||
#define IRS_IDR7 0x001c
|
||||
#define IRS_IDR7_SPI_BASE 0x00ffffff
|
||||
#define IRS_IIDR 0x0040
|
||||
#define IRS_AIDR 0x0044
|
||||
#define IRS_CR0 0x0080
|
||||
#define IRS_CR0_IDLE (0x1u << 1)
|
||||
#define IRS_CR0_IRSEN (0x1u << 0)
|
||||
#define IRS_CR1 0x0084
|
||||
#define IRS_CR1_VPED_NO_WA (0x0u << 15)
|
||||
#define IRS_CR1_VPED_WA (0x1u << 15)
|
||||
#define IRS_CR1_VPED_NO_RA (0x0u << 14)
|
||||
#define IRS_CR1_VPED_RA (0x1u << 14)
|
||||
#define IRS_CR1_VMD_NO_WA (0x0u << 13)
|
||||
#define IRS_CR1_VMD_WA (0x1u << 13)
|
||||
#define IRS_CR1_VMD_NO_RA (0x0u << 12)
|
||||
#define IRS_CR1_VMD_RA (0x1u << 12)
|
||||
#define IRS_CR1_VPET_NO_WA (0x0u << 11)
|
||||
#define IRS_CR1_VPET_WA (0x1u << 11)
|
||||
#define IRS_CR1_VPET_NO_RA (0x0u << 10)
|
||||
#define IRS_CR1_VPET_RA (0x1u << 10)
|
||||
#define IRS_CR1_VMT_NO_WA (0x0u << 9)
|
||||
#define IRS_CR1_VMT_WA (0x1u << 9)
|
||||
#define IRS_CR1_VMT_NO_RA (0x0u << 8)
|
||||
#define IRS_CR1_VMT_RA (0x1u << 8)
|
||||
#define IRS_CR1_IST_NO_WA (0x0u << 7)
|
||||
#define IRS_CR1_IST_WA (0x1u << 7)
|
||||
#define IRS_CR1_IST_NO_RA (0x0u << 6)
|
||||
#define IRS_CR1_IST_RA (0x1u << 6)
|
||||
#define IRS_CR1_IC_SHIFT 4
|
||||
#define IRS_CR1_IC_MASK (0x3u << IRS_CR1_IC_SHIFT)
|
||||
#define IRS_CR1_IC_NC (0x0u << IRS_CR1_IC_SHIFT)
|
||||
#define IRS_CR1_IC_WB (0x1u << IRS_CR1_IC_SHIFT)
|
||||
#define IRS_CR1_IC_WT (0x2u << IRS_CR1_IC_SHIFT)
|
||||
#define IRS_CR1_OC_SHIFT 2
|
||||
#define IRS_CR1_OC_MASK (0x3u << IRS_CR1_OC_SHIFT)
|
||||
#define IRS_CR1_OC_MASK (0x3u << IRS_CR1_OC_SHIFT)
|
||||
#define IRS_CR1_OC_NC (0x0u << IRS_CR1_OC_SHIFT)
|
||||
#define IRS_CR1_OC_WB (0x1u << IRS_CR1_OC_SHIFT)
|
||||
#define IRS_CR1_OC_WT (0x2u << IRS_CR1_OC_SHIFT)
|
||||
#define IRS_CR1_SH_SHIFT 0
|
||||
#define IRS_CR1_SH_MASK (0x3u << IRS_CR1_SH_SHIFT)
|
||||
#define IRS_CR1_SH_MASK (0x3u << IRS_CR1_SH_SHIFT)
|
||||
#define IRS_CR1_SH_NS (0x0u << IRS_CR1_SH_SHIFT)
|
||||
#define IRS_CR1_SH_OS (0x2u << IRS_CR1_SH_SHIFT)
|
||||
#define IRS_CR1_SH_IS (0x3u << IRS_CR1_SH_SHIFT)
|
||||
#define IRS_SYNCR 0x00c0
|
||||
#define IRS_SYNC_STATUSR 0x00c4
|
||||
#define IRS_SPI_VMR 0x0100
|
||||
#define IRS_SPI_SELR 0x0108
|
||||
#define IRS_SPI_DOMAINR 0x010c
|
||||
#define IRS_SPI_RESAMPLER 0x0110
|
||||
#define IRS_SPI_CFGR 0x0114
|
||||
#define IRS_SPI_CFGR_TM_EDGE (0x0u << 0)
|
||||
#define IRS_SPI_CFGR_TM_LEVEL (0x1u << 0)
|
||||
#define IRS_SPI_STATUSR 0x0118
|
||||
#define IRS_SPI_STATUSR_V (0x1u << 1)
|
||||
#define IRS_SPI_STATUSR_IDLE (0x1u << 0)
|
||||
#define IRS_PE_SELR 0x0140
|
||||
#define IRS_PE_STATUSR 0x0144
|
||||
#define IRS_PE_CR0 0x0148
|
||||
#define IRS_IST_BASER 0x0180
|
||||
#define IRS_IST_BASER_ADDR_LIMIT 0x0100000000000000ul
|
||||
#define IRS_IST_BASER_ADDR_MASK 0x00ffffffffffffc0ul
|
||||
#define IRS_IST_BASER_VALID (0x1ul << 0)
|
||||
#define IRS_IST_CFGR 0x0190
|
||||
#define IRS_IST_CFGR_STRUCTURE_LINEAR (0x0 << 16)
|
||||
#define IRS_IST_CFGR_STRUCTURE_2LVL (0x1 << 16)
|
||||
#define IRS_IST_CFGR_ISTSZ_SHIFT 7
|
||||
#define IRS_IST_CFGR_ISTSZ_MASK (0x3 << IRS_IST_CFGR_ISTSZ_SHIFT)
|
||||
#define IRS_IST_CFGR_ISTSZ_VAL(x) \
|
||||
(((x) & IRS_IST_CFGR_ISTSZ_MASK) >> IRS_IST_CFGR_ISTSZ_SHIFT)
|
||||
#define IRS_IST_CFGR_ISTSZ_4_VAL 0x0
|
||||
#define IRS_IST_CFGR_ISTSZ_4 (0x0 << IRS_IST_CFGR_ISTSZ_SHIFT)
|
||||
#define IRS_IST_CFGR_ISTSZ_8_VAL 0x1
|
||||
#define IRS_IST_CFGR_ISTSZ_8 (0x1 << IRS_IST_CFGR_ISTSZ_SHIFT)
|
||||
#define IRS_IST_CFGR_ISTSZ_16_VAL 0x2
|
||||
#define IRS_IST_CFGR_ISTSZ_16 (0x2 << IRS_IST_CFGR_ISTSZ_SHIFT)
|
||||
#define IRS_IST_CFGR_L2SZ_SHIFT 5
|
||||
#define IRS_IST_CFGR_L2SZ_MASK (0x3 << IRS_IST_CFGR_L2SZ_SHIFT)
|
||||
#define IRS_IST_CFGR_L2SZ_VAL(x) \
|
||||
(((x) & IRS_IST_CFGR_L2SZ_MASK) >> IRS_IST_CFGR_L2SZ_SHIFT)
|
||||
#define IRS_IST_CFGR_L2SZ_4K_VAL 0x0
|
||||
#define IRS_IST_CFGR_L2SZ_4K (0x0 << IRS_IST_CFGR_L2SZ_SHIFT)
|
||||
#define IRS_IST_CFGR_L2SZ_16K_VAL 0x1
|
||||
#define IRS_IST_CFGR_L2SZ_16K (0x1 << IRS_IST_CFGR_L2SZ_SHIFT)
|
||||
#define IRS_IST_CFGR_L2SZ_64K_VAL 0x2
|
||||
#define IRS_IST_CFGR_L2SZ_64K (0x2 << IRS_IST_CFGR_L2SZ_SHIFT)
|
||||
#define IRS_IST_CFGR_LPI_ID_BITS_SHIFT 0
|
||||
#define IRS_IST_CFGR_LPI_ID_BITS_MASK (0x1f << IRS_IST_CFGR_LPI_ID_BITS_SHIFT)
|
||||
#define IRS_IST_CFGR_LPI_ID_BITS_VAL(x) \
|
||||
(((x) & IRS_IST_CFGR_LPI_ID_BITS_MASK) >> IRS_IST_CFGR_LPI_ID_BITS_SHIFT)
|
||||
#define IRS_IST_CFGR_
|
||||
#define IRS_IST_STATUSR 0x0194
|
||||
#define IRS_IST_STATUSR_IDLE (0x1u << 0)
|
||||
#define IRS_MAP_L2_ISTR 0x01c0
|
||||
#define IRS_VMT_BASER 0x0200
|
||||
#define IRS_VMT_CFGR 0x0210
|
||||
#define IRS_VMT_STATUSR 0x0214
|
||||
#define IRS_VPE_SELR 0x0240
|
||||
#define IRS_VPE_DBR 0x0248
|
||||
#define IRS_VPE_HPPIR 0x0250
|
||||
#define IRS_VPE_CR0 0x0258
|
||||
#define IRS_VPE_STATUSR 0x025c
|
||||
#define IRS_VM_DBR 0x0280
|
||||
#define IRS_VM_SELR 0x0288
|
||||
#define IRS_VM_STATUSR 0x028c
|
||||
#define IRS_VMAP_L2_VMTR 0x02c0
|
||||
#define IRS_VMAP_VMR 0x02c8
|
||||
#define IRS_VMAP_VISTR 0x02d0
|
||||
#define IRS_VMAP_L2_VISTR 0x02d8
|
||||
#define IRS_VMAP_VPER 0x02e0
|
||||
#define IRS_SAVE_VMR 0x0300
|
||||
#define IRS_SAVE_VM_STATUSR 0x0308
|
||||
#define IRS_MEC_IDR 0x0340
|
||||
#define IRS_MEC_MECID_R 0x0344
|
||||
#define IRS_MPAM_IDR 0x0380
|
||||
#define IRS_MPAM_PARTID_R 0x0384
|
||||
#define IRS_SWERR_STATUSR 0x03c0
|
||||
#define IRS_SWERR_SYNDROMER0 0x03c8
|
||||
#define IRS_SWERR_SYNDROMER1 0x03d0
|
||||
|
||||
/*
|
||||
* IRS Data Structures
|
||||
*/
|
||||
|
||||
/* L1_ISTE - Level 1 interrupt state table entry */
|
||||
#define L1_ISTE_SIZE 8
|
||||
#define L1_ISTE_L2_ADDR 0xfffffffffff000ul
|
||||
#define L1_ISTE_VALID (0x1ul << 0)
|
||||
|
||||
/* L2_ISTE - Level 2 interrupt state table entry */
|
||||
#define L2_ISTE_IAFFID_SHIFT 16
|
||||
#define L2_ISTE_IAFFID_MASK (0xffffu << L2_ISTE_IAFFID_SHIFT)
|
||||
#define L2_ISTE_Priority_SHIFT 11
|
||||
#define L2_ISTE_Priority (0x1fu << L2_ISTE_Priority_SHIFT)
|
||||
#define L2_ISTE_HWU_SHIFT 9
|
||||
#define L2_ISTE_HWU (0x3u << L2_ISTE_HWU_SHIFT)
|
||||
#define L2_ISTE_IRM (0x1u << 4)
|
||||
#define L2_ISTE_Enable (0x1u << 3)
|
||||
#define L2_ISTE_HM (0x1u << 2)
|
||||
#define L2_ISTE_Active (0x1u << 1)
|
||||
#define L2_ISTE_Pending (0x1u << 0)
|
||||
|
||||
/* log2(number of entries in l2 table */
|
||||
#define L2_ISTE_LOG2_ENTRIES(istsz, l2sz) (10 - (istsz) + 2 * (l2sz))
|
||||
#define L2_ISTE_LOG2_SIZE(l2sz) (11 + 2 * (l2sz) + 1)
|
||||
|
||||
/*
|
||||
* Misc
|
||||
*/
|
||||
|
||||
/*
|
||||
* RXBQTT: In the GIC prioritization scheme, lower numbers have higher priority.
|
||||
*/
|
||||
#define GICV5_PRI_HIGHEST 0x0
|
||||
#define GICV5_PRI_LOWEST 0x1f
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Arm Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#ifndef _ARM64_GICV5VAR_H_
|
||||
#define _ARM64_GICV5VAR_H_
|
||||
|
||||
DECLARE_CLASS(gicv5_driver);
|
||||
|
||||
struct gicv5_irqsrc;
|
||||
struct gicv5_irs_irqspec;
|
||||
|
||||
enum gicv5_irq_space {
|
||||
GICv5_INVALID,
|
||||
/* GICv5 interrupt types so they are the same values as in the spec */
|
||||
GICv5_PPI,
|
||||
GICv5_LPI,
|
||||
GICv5_SPI,
|
||||
};
|
||||
|
||||
/*
|
||||
* Shared between the IRS and ITS
|
||||
*/
|
||||
struct gicv5_base_irqsrc {
|
||||
struct intr_irqsrc gbi_isrc;
|
||||
enum gicv5_irq_space gbi_space;
|
||||
bool gbi_ipi;
|
||||
uint32_t gbi_irq;
|
||||
};
|
||||
|
||||
struct gicv5_irs;
|
||||
|
||||
struct gicv5_softc {
|
||||
device_t gic_dev;
|
||||
struct intr_pic *gic_pic;
|
||||
|
||||
struct gicv5_irqsrc *gic_ppi_irqs;
|
||||
struct gicv5_irqsrc *gic_irs_irqs;
|
||||
struct gicv5_irqsrc *gic_ipi_irqs;
|
||||
struct gicv5_irs **gic_irs;
|
||||
|
||||
device_t *gic_children;
|
||||
|
||||
u_int gic_bus;
|
||||
bool gic_coherent;
|
||||
u_int gic_nirs;
|
||||
u_int gic_spi_count;
|
||||
u_int gic_nchildren;
|
||||
/* Number of LPIs, including IPIs */
|
||||
u_int gic_nlpis;
|
||||
};
|
||||
|
||||
struct gicv5_devinfo {
|
||||
struct resource_list di_rl;
|
||||
struct gicv5_irs *di_irs;
|
||||
};
|
||||
|
||||
#define GICV5_IVAR_LPI_START 5000
|
||||
|
||||
__BUS_ACCESSOR(gicv5, lpi_start, GICV5, LPI_START, u_int);
|
||||
|
||||
void gicv5_attach(device_t);
|
||||
bool gicv5_add_child(device_t, struct gicv5_devinfo *);
|
||||
int gicv5_intr(void *);
|
||||
|
||||
void gicv5_irs_init(device_t, u_int, cpuset_t *);
|
||||
void gicv5_irs_extend_ist(device_t, device_t, u_int);
|
||||
|
||||
#endif /* _ARM64_GICV5VAR_H_ */
|
||||
@@ -59,6 +59,8 @@ arm64/arm64/gicv3_its.c optional intrng fdt
|
||||
arm64/arm64/gic_v3.c standard
|
||||
arm64/arm64/gic_v3_acpi.c optional acpi
|
||||
arm64/arm64/gic_v3_fdt.c optional fdt
|
||||
arm64/arm64/gicv5.c standard
|
||||
arm64/arm64/gicv5_fdt.c optional fdt
|
||||
arm64/arm64/hyp_stub.S standard
|
||||
arm64/arm64/identcpu.c standard
|
||||
arm64/arm64/kexec_support.c standard
|
||||
|
||||
Reference in new issue
Block a user