feat(gicv5): add support for building with gicv5
The Generic Interrupt Controller v5 (GICv5) is the next generation of
Arm interrupt controllers. It is a clean slate design and has native
support for the latest Armv9 features. As such it is entirely backwards
incompatible with GICv3/v4.
This patch adds the necessary boilerplate to select a build with GICv5.
The GIC has always had two parts. BL31 deals directly with the CPU
interface while platform code is responsible for managing the IRI. In v5
this split is formalised and the CPU interface, FEAT_GCIE, may be
implemented on its own. So reflect this split in our code with
ENABLE_FEAT_GCIE which only affects BL31 and the GICv5 IRI lies in the
generic GIC driver.
No actual functionality yet.
Change-Id: I97a0c3ba708877c213e50e7ef148e3412aa2af90
Co-developed-by: Achin Gupta <achin.gupta@arm.com>
Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
diff --git a/Makefile b/Makefile
index 75eeaee..cbf0a8a 100644
--- a/Makefile
+++ b/Makefile
@@ -1002,6 +1002,9 @@
ifneq (${ENABLE_FEAT_MOPS},0)
$(error "ENABLE_FEAT_MOPS cannot be used with ARCH=aarch32")
endif
+ ifneq (${ENABLE_FEAT_GCIE},0)
+ $(error "ENABLE_FEAT_GCIE cannot be used with ARCH=aarch32")
+ endif
endif #(ARCH=aarch32)
ifneq (${ENABLE_FEAT_FPMR},0)
@@ -1238,6 +1241,7 @@
ENABLE_RUNTIME_INSTRUMENTATION \
ENABLE_SME_FOR_SWD \
ENABLE_SVE_FOR_SWD \
+ ENABLE_FEAT_GCIE \
ENABLE_FEAT_RAS \
FFH_SUPPORT \
ERROR_DEPRECATED \
@@ -1525,6 +1529,7 @@
ENABLE_FEAT_D128 \
ENABLE_FEAT_GCS \
ENABLE_FEAT_MOPS \
+ ENABLE_FEAT_GCIE \
ENABLE_FEAT_MTE2 \
FEATURE_DETECTION \
TWED_DELAY \
diff --git a/changelog.yaml b/changelog.yaml
index 3da8af4..f2f821e 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -996,6 +996,9 @@
scope: gic
subsections:
+ - title: GICv5
+ scope: gicv5
+
- title: GICv3
scope: gicv3
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 2d80b42..fa817d9 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -279,6 +279,11 @@
return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_D128_SHIFT,
ID_AA64MMFR3_EL1_D128_MASK);
}
+static unsigned int read_feat_gcie_id_field(void)
+{
+ return ISOLATE_FIELD(read_id_aa64pfr2_el1(), ID_AA64PFR2_EL1_GCIE_SHIFT,
+ ID_AA64PFR2_EL1_GCIE_MASK);
+}
static unsigned int read_feat_fpmr_id_field(void)
{
@@ -425,6 +430,8 @@
/* v9.3 features */
check_feature(ENABLE_FEAT_D128, read_feat_d128_id_field(),
"D128", 1, 1);
+ check_feature(ENABLE_FEAT_GCIE, read_feat_gcie_id_field(),
+ "GCIE", 1, 1);
/* v9.4 features */
check_feature(ENABLE_FEAT_GCS, read_feat_gcs_id_field(), "GCS", 1, 1);
diff --git a/docs/about/features.rst b/docs/about/features.rst
index f15144a..78f5ff3 100644
--- a/docs/about/features.rst
+++ b/docs/about/features.rst
@@ -128,6 +128,7 @@
in a platform:
- RSE comms driver ``drivers/arm/rse``
+- GICv5 driver ``drivers/arm/gicv5`` via ``USE_GIC_DRIVER=5``
Still to come
-------------
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index c30caac..e80f3d1 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -481,6 +481,11 @@
the values 0 to 2, to align with the ``ENABLE_FEAT`` mechanism.
Default value is ``0``.
+ - ``ENABLE_FEAT_GCIE``: Boolean value to enable support for the GICv5 CPU
+ interface (see ``USE_GIC_DRIVER`` for the IRI). GICv5 and GICv3 are mutually
+ exclusive, so the ``ENABLE_FEAT`` mechanism is currently not supported.
+ Default value is ``0``.
+
- ``ENABLE_FEAT_THE``: Numeric value to enable support for FEAT_THE
(Translation Hardening Extension) at EL2 and below, setting the bit
SCR_EL3.RCWMASKEn in EL3 to allow access to RCWMASK_EL1 and RCWSMASK_EL1
@@ -1308,6 +1313,7 @@
- ``3``: use the GICv3 driver. See the next section on how to further configure
it. Use this option for GICv4 implementations.
+ - ``5``: use the EXPERIMENTAL GICv5 driver. Requires ``ENABLE_FEAT_GCIE=1``.
For GIC driver versions other than ``1``, deciding when to save and restore GIC
context on a power domain state transition, as well as any GIC actions outside
diff --git a/drivers/arm/gic/gic.mk b/drivers/arm/gic/gic.mk
index ad30984..8b28f21 100644
--- a/drivers/arm/gic/gic.mk
+++ b/drivers/arm/gic/gic.mk
@@ -4,7 +4,7 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-GIC_REVISIONS_ := 1 2 3
+GIC_REVISIONS_ := 1 2 3 5
ifeq ($(filter $(USE_GIC_DRIVER),$(GIC_REVISIONS_)),)
$(error USE_GIC_DRIVER can only be one of $(GIC_REVISIONS_))
endif
@@ -19,6 +19,18 @@
GIC_SOURCES := ${GICV3_SOURCES} \
drivers/arm/gic/v3/gicv3_base.c \
plat/common/plat_gicv3.c
+else ifeq (${USE_GIC_DRIVER},5)
+ifneq (${ENABLE_FEAT_GCIE},1)
+$(error USE_GIC_DRIVER=5 requires ENABLE_FEAT_GCIE=1)
+endif
+$(warning GICv5 support is experimental!)
+GIC_SOURCES := drivers/arm/gicv5/gicv5_iri.c \
+ plat/common/plat_gicv5.c
+endif
+
+ifneq (${ENABLE_FEAT_GCIE},0)
+GIC_SOURCES += drivers/arm/gicv5/gicv5_cpuif.c \
+ drivers/arm/gicv5/gicv5_main.c
endif
ifeq ($(ARCH),aarch64)
diff --git a/drivers/arm/gicv5/gicv5_cpuif.c b/drivers/arm/gicv5/gicv5_cpuif.c
new file mode 100644
index 0000000..e6727f8
--- /dev/null
+++ b/drivers/arm/gicv5/gicv5_cpuif.c
@@ -0,0 +1,5 @@
+/*
+ * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
diff --git a/drivers/arm/gicv5/gicv5_iri.c b/drivers/arm/gicv5/gicv5_iri.c
new file mode 100644
index 0000000..e6727f8
--- /dev/null
+++ b/drivers/arm/gicv5/gicv5_iri.c
@@ -0,0 +1,5 @@
+/*
+ * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
diff --git a/drivers/arm/gicv5/gicv5_main.c b/drivers/arm/gicv5/gicv5_main.c
new file mode 100644
index 0000000..e6727f8
--- /dev/null
+++ b/drivers/arm/gicv5/gicv5_main.c
@@ -0,0 +1,5 @@
+/*
+ * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index e8c4054..5475c7a 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -504,6 +504,11 @@
#define SME2_IMPLEMENTED ULL(0x2)
#define SME_NOT_IMPLEMENTED ULL(0x0)
+/* ID_AA64PFR2_EL1 definitions */
+#define ID_AA64PFR2_EL1 S3_0_C0_C4_2
+#define ID_AA64PFR2_EL1_GCIE_SHIFT 12
+#define ID_AA64PFR2_EL1_GCIE_MASK ULL(0xf)
+
/* ID_PFR1_EL1 definitions */
#define ID_PFR1_VIRTEXT_SHIFT U(12)
#define ID_PFR1_VIRTEXT_MASK U(0xf)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 757ce06..77355cd 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -520,4 +520,11 @@
CREATE_FEATURE_SUPPORTED(feat_mtpmu, is_feat_mtpmu_present, DISABLE_MTPMU)
+/*************************************************************************
+ * Function to identify the presence of FEAT_GCIE (GICv5 CPU interface
+ * extension).
+ ************************************************************************/
+CREATE_FEATURE_FUNCS(feat_gcie, id_aa64pfr2_el1, ID_AA64PFR2_EL1_GCIE_SHIFT,
+ ID_AA64PFR2_EL1_GCIE_MASK, 1U, ENABLE_FEAT_GCIE)
+
#endif /* ARCH_FEATURES_H */
diff --git a/include/drivers/arm/gicv5.h b/include/drivers/arm/gicv5.h
new file mode 100644
index 0000000..e167845
--- /dev/null
+++ b/include/drivers/arm/gicv5.h
@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GICV5_H
+#define GICV5_H
+#endif /* GICV5_H */
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 61bd08a..a6fd6be 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -428,6 +428,9 @@
# Flag to enable access to Arm v9.3 FEAT_D128 extension
ENABLE_FEAT_D128 ?= 0
+# Flag to enable access to GICv5 CPU interface extension (FEAT_GCIE)
+ENABLE_FEAT_GCIE ?= 0
+
#----
#9.4
#----
diff --git a/plat/common/plat_gicv5.c b/plat/common/plat_gicv5.c
new file mode 100644
index 0000000..266ea18
--- /dev/null
+++ b/plat/common/plat_gicv5.c
@@ -0,0 +1,5 @@
+/*
+ * Copyright (c) 2025, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */