* [BOOTWRAPPER PATCH v2 0/2] Support GICv5
@ 2026-03-24 12:59 Vladimir Murzin
2026-03-24 12:59 ` [BOOTWRAPPER PATCH v2 1/2] Introduce --with-gic option Vladimir Murzin
2026-03-24 12:59 ` [BOOTWRAPPER PATCH v2 2/2] Add support for GICv5 Vladimir Murzin
0 siblings, 2 replies; 7+ messages in thread
From: Vladimir Murzin @ 2026-03-24 12:59 UTC (permalink / raw)
To: linux-arm-kernel
Cc: vladimir.murzin, mark.rutland, maz, joey.gouly, Sascha.Bischoff
Small series adding GICv5 to the list of supported GIC
versions. Minimal implementation, just enough for Fast Models.
Thanks!
Changelog:
v1 -> v2
- Assign SW_PPI to NS domain (per Sascha)
Vladimir Murzin (2):
Introduce --with-gic option
Add support for GICv5
Makefile.am | 15 +++-
arch/aarch64/include/asm/cpu.h | 11 +++
common/{gic.c => gic-v2.c} | 0
common/gic-v5.c | 134 +++++++++++++++++++++++++++++++++
configure.ac | 24 ++++--
scripts/FDT.pm | 16 ++++
scripts/findbase-by-regname.pl | 44 +++++++++++
7 files changed, 234 insertions(+), 10 deletions(-)
rename common/{gic.c => gic-v2.c} (100%)
create mode 100644 common/gic-v5.c
create mode 100755 scripts/findbase-by-regname.pl
--
2.34.1
^ permalink raw reply [flat|nested] 7+ messages in thread* [BOOTWRAPPER PATCH v2 1/2] Introduce --with-gic option 2026-03-24 12:59 [BOOTWRAPPER PATCH v2 0/2] Support GICv5 Vladimir Murzin @ 2026-03-24 12:59 ` Vladimir Murzin 2026-05-28 15:06 ` Sascha Bischoff 2026-03-24 12:59 ` [BOOTWRAPPER PATCH v2 2/2] Add support for GICv5 Vladimir Murzin 1 sibling, 1 reply; 7+ messages in thread From: Vladimir Murzin @ 2026-03-24 12:59 UTC (permalink / raw) To: linux-arm-kernel Cc: vladimir.murzin, mark.rutland, maz, joey.gouly, Sascha.Bischoff We are about adding support for another GIC version, so introduce a new --with-gic option to select the desired GIC version at configure time. The default remains v2, preserving existing behavior. Howevere, for GICv3, we replace the previous --enable-gicv3 option with --with-gic=v3 which is backward-incompatible change (yet I hope we can live with that). Signed-off-by: Vladimir Murzin <vladimir.murzin@arm•com> --- Makefile.am | 8 +++++--- common/{gic.c => gic-v2.c} | 0 configure.ac | 23 ++++++++++++++++------- 3 files changed, 21 insertions(+), 10 deletions(-) rename common/{gic.c => gic-v2.c} (100%) diff --git a/Makefile.am b/Makefile.am index 0178e5d..2710494 100644 --- a/Makefile.am +++ b/Makefile.am @@ -87,15 +87,17 @@ GIC_DIST_BASE := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNE GIC_RDIST_BASE := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 1 'arm,gic-v3') DEFINES += -DGIC_DIST_BASE=$(GIC_DIST_BASE) DEFINES += -DGIC_RDIST_BASE=$(GIC_RDIST_BASE) -COMMON_OBJ += gic-v3.o -else +endif + +if GICV2 GIC_DIST_BASE := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,cortex-a15-gic') GIC_CPU_BASE := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 1 'arm,cortex-a15-gic') DEFINES += -DGIC_CPU_BASE=$(GIC_CPU_BASE) DEFINES += -DGIC_DIST_BASE=$(GIC_DIST_BASE) -COMMON_OBJ += gic.o endif +COMMON_OBJ += gic-$(GIC_VERSION).o + if KERNEL_32 MBOX_OFFSET := 0x7ff8 TEXT_LIMIT := 0x3000 diff --git a/common/gic.c b/common/gic-v2.c similarity index 100% rename from common/gic.c rename to common/gic-v2.c diff --git a/configure.ac b/configure.ac index 42858df..6f486c4 100644 --- a/configure.ac +++ b/configure.ac @@ -139,12 +139,21 @@ AC_ARG_WITH([xen-cmdline], [X_CMDLINE=$withval]) AC_SUBST([XEN_CMDLINE], [$X_CMDLINE]) -# Allow a user to pass --enable-gicv3 -AC_ARG_ENABLE([gicv3], - AS_HELP_STRING([--enable-gicv3], [enable GICv3 instead of GICv2]), - [USE_GICV3=$enableval]) -AM_CONDITIONAL([GICV3], [test "x$USE_GICV3" = "xyes"]) -AS_IF([test "x$USE_GICV3" = "xyes"], [], [USE_GICV3=no]) + +AC_ARG_WITH([gic], + AS_HELP_STRING([--with-gic={v2|v3}], [select GIC version]), + [GIC_VERSION=$withval], + [GIC_VERSION=v2]) + +AS_CASE([$GIC_VERSION], + [v2|v3], [], + [AC_MSG_ERROR([Invalid GIC version: $GIC_VERSION (use v2 or v3)])]) + +AC_SUBST([GIC_VERSION], [$GIC_VERSION]) + +AM_CONDITIONAL([GICV2], [test "x$GIC_VERSION" = "xv2"]) +AM_CONDITIONAL([GICV3], [test "x$GIC_VERSION" = "xv3"]) + # Ensure that we have all the needed programs AC_PROG_CC @@ -174,7 +183,7 @@ echo " Device tree compiler: ${DTC}" echo " Linux kernel command line: ${CMDLINE}" echo " Embedded initrd: ${FILESYSTEM:-NONE}" echo " Use PSCI? ${USE_PSCI}" -echo " Use GICv3? ${USE_GICV3}" +echo " GIC version: ${GIC_VERSION}" echo " Boot-wrapper execution state: AArch${BOOTWRAPPER_ES}" echo " Kernel execution state: AArch${KERNEL_ES}" echo " Xen image ${XEN_IMAGE:-NONE}" -- 2.34.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [BOOTWRAPPER PATCH v2 1/2] Introduce --with-gic option 2026-03-24 12:59 ` [BOOTWRAPPER PATCH v2 1/2] Introduce --with-gic option Vladimir Murzin @ 2026-05-28 15:06 ` Sascha Bischoff 2026-05-29 9:47 ` Vladimir Murzin 0 siblings, 1 reply; 7+ messages in thread From: Sascha Bischoff @ 2026-05-28 15:06 UTC (permalink / raw) To: linux-arm-kernel@lists•infradead.org, Vladimir Murzin Cc: maz@kernel•org, Joey Gouly, Mark Rutland, nd Hi Vladimir, Sorry for taking so long to get to this! On Tue, 2026-03-24 at 12:59 +0000, Vladimir Murzin wrote: > We are about adding support for another GIC version, so introduce a nit: We are about to add support > new --with-gic option to select the desired GIC version at configure > time. The default remains v2, preserving existing behavior. > Howevere, nit: However Aside from these nits, this looks good to me, so: Reviewed-by: Sascha Bischoff <sascha.bischoff@arm•com> Thanks, Sascha > for GICv3, we replace the previous --enable-gicv3 option with > --with-gic=v3 which is backward-incompatible change (yet I hope we > can > live with that). > > Signed-off-by: Vladimir Murzin <vladimir.murzin@arm•com> > --- > Makefile.am | 8 +++++--- > common/{gic.c => gic-v2.c} | 0 > configure.ac | 23 ++++++++++++++++------- > 3 files changed, 21 insertions(+), 10 deletions(-) > rename common/{gic.c => gic-v2.c} (100%) > > diff --git a/Makefile.am b/Makefile.am > index 0178e5d..2710494 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -87,15 +87,17 @@ GIC_DIST_BASE := $(shell perl -I > $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNE > GIC_RDIST_BASE := $(shell perl -I $(SCRIPT_DIR) > $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 1 'arm,gic-v3') > DEFINES += -DGIC_DIST_BASE=$(GIC_DIST_BASE) > DEFINES += -DGIC_RDIST_BASE=$(GIC_RDIST_BASE) > -COMMON_OBJ += gic-v3.o > -else > +endif > + > +if GICV2 > GIC_DIST_BASE := $(shell perl -I $(SCRIPT_DIR) > $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,cortex-a15-gic') > GIC_CPU_BASE := $(shell perl -I $(SCRIPT_DIR) > $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 1 'arm,cortex-a15-gic') > DEFINES += -DGIC_CPU_BASE=$(GIC_CPU_BASE) > DEFINES += -DGIC_DIST_BASE=$(GIC_DIST_BASE) > -COMMON_OBJ += gic.o > endif > > +COMMON_OBJ += gic-$(GIC_VERSION).o > + > if KERNEL_32 > MBOX_OFFSET := 0x7ff8 > TEXT_LIMIT := 0x3000 > diff --git a/common/gic.c b/common/gic-v2.c > similarity index 100% > rename from common/gic.c > rename to common/gic-v2.c > diff --git a/configure.ac b/configure.ac > index 42858df..6f486c4 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -139,12 +139,21 @@ AC_ARG_WITH([xen-cmdline], > [X_CMDLINE=$withval]) > AC_SUBST([XEN_CMDLINE], [$X_CMDLINE]) > > -# Allow a user to pass --enable-gicv3 > -AC_ARG_ENABLE([gicv3], > - AS_HELP_STRING([--enable-gicv3], [enable GICv3 instead of > GICv2]), > - [USE_GICV3=$enableval]) > -AM_CONDITIONAL([GICV3], [test "x$USE_GICV3" = "xyes"]) > -AS_IF([test "x$USE_GICV3" = "xyes"], [], [USE_GICV3=no]) > + > +AC_ARG_WITH([gic], > + AS_HELP_STRING([--with-gic={v2|v3}], [select GIC version]), > + [GIC_VERSION=$withval], > + [GIC_VERSION=v2]) > + > +AS_CASE([$GIC_VERSION], > + [v2|v3], [], > + [AC_MSG_ERROR([Invalid GIC version: $GIC_VERSION (use v2 or > v3)])]) > + > +AC_SUBST([GIC_VERSION], [$GIC_VERSION]) > + > +AM_CONDITIONAL([GICV2], [test "x$GIC_VERSION" = "xv2"]) > +AM_CONDITIONAL([GICV3], [test "x$GIC_VERSION" = "xv3"]) > + > > # Ensure that we have all the needed programs > AC_PROG_CC > @@ -174,7 +183,7 @@ echo " Device tree compiler: > ${DTC}" > echo " Linux kernel command line: ${CMDLINE}" > echo " Embedded initrd: ${FILESYSTEM:-NONE}" > echo " Use PSCI? ${USE_PSCI}" > -echo " Use GICv3? ${USE_GICV3}" > +echo " GIC version: ${GIC_VERSION}" > echo " Boot-wrapper execution state: AArch${BOOTWRAPPER_ES}" > echo " Kernel execution state: AArch${KERNEL_ES}" > echo " Xen image ${XEN_IMAGE:-NONE}" ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [BOOTWRAPPER PATCH v2 1/2] Introduce --with-gic option 2026-05-28 15:06 ` Sascha Bischoff @ 2026-05-29 9:47 ` Vladimir Murzin 0 siblings, 0 replies; 7+ messages in thread From: Vladimir Murzin @ 2026-05-29 9:47 UTC (permalink / raw) To: Sascha Bischoff, linux-arm-kernel@lists•infradead.org Cc: maz@kernel•org, Joey Gouly, Mark Rutland, nd On 5/28/26 16:06, Sascha Bischoff wrote: > Hi Vladimir, > > Sorry for taking so long to get to this! > > On Tue, 2026-03-24 at 12:59 +0000, Vladimir Murzin wrote: >> We are about adding support for another GIC version, so introduce a > nit: We are about to add support > >> new --with-gic option to select the desired GIC version at configure >> time. The default remains v2, preserving existing behavior. >> Howevere, > nit: However > > Aside from these nits, this looks good to me, so: > Reviewed-by: Sascha Bischoff <sascha.bischoff@arm•com> > > Thanks, > Sascha Thanks Sascha, all fixed locally. Cheers Vladimir ^ permalink raw reply [flat|nested] 7+ messages in thread
* [BOOTWRAPPER PATCH v2 2/2] Add support for GICv5 2026-03-24 12:59 [BOOTWRAPPER PATCH v2 0/2] Support GICv5 Vladimir Murzin 2026-03-24 12:59 ` [BOOTWRAPPER PATCH v2 1/2] Introduce --with-gic option Vladimir Murzin @ 2026-03-24 12:59 ` Vladimir Murzin 2026-05-28 15:10 ` Sascha Bischoff 1 sibling, 1 reply; 7+ messages in thread From: Vladimir Murzin @ 2026-03-24 12:59 UTC (permalink / raw) To: linux-arm-kernel Cc: vladimir.murzin, mark.rutland, maz, joey.gouly, Sascha.Bischoff Performs the minimal initialization required for GICv5 support. GICv5 support can be requested with --with-gic=v5. Signed-off-by: Vladimir Murzin <vladimir.murzin@arm•com> --- Makefile.am | 7 ++ arch/aarch64/include/asm/cpu.h | 11 +++ common/gic-v5.c | 134 +++++++++++++++++++++++++++++++++ configure.ac | 7 +- scripts/FDT.pm | 16 ++++ scripts/findbase-by-regname.pl | 44 +++++++++++ 6 files changed, 216 insertions(+), 3 deletions(-) create mode 100644 common/gic-v5.c create mode 100755 scripts/findbase-by-regname.pl diff --git a/Makefile.am b/Makefile.am index 2710494..aacd639 100644 --- a/Makefile.am +++ b/Makefile.am @@ -82,6 +82,13 @@ PSCI_NODE := CPU_NODES := endif +if GICV5 +GIC_IRS_BASE := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase-by-regname.pl $(KERNEL_DTB) "el3-config" 'arm,gic-v5-irs') +GIC_IWB_BASE := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,gic-v5-iwb') +DEFINES += -DGIC_IRS_BASE=$(GIC_IRS_BASE) +DEFINES += -DGIC_IWB_BASE=$(GIC_IWB_BASE) +endif + if GICV3 GIC_DIST_BASE := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,gic-v3') GIC_RDIST_BASE := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 1 'arm,gic-v3') diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h index ac50474..af4191c 100644 --- a/arch/aarch64/include/asm/cpu.h +++ b/arch/aarch64/include/asm/cpu.h @@ -128,6 +128,7 @@ #define ID_AA64PFR1_EL1_THE BITS(51, 48) #define ID_AA64PFR2_EL1 s3_0_c0_c4_2 +#define ID_AA64PFR2_EL1_GCIE BITS(15, 12) #define ID_AA64PFR2_EL1_FPMR BITS(35, 32) #define ID_AA64SMFR0_EL1 s3_0_c0_c4_5 @@ -169,6 +170,11 @@ #define ICC_CTLR_EL3 S3_6_C12_C12_4 #define ICC_PMR_EL1 S3_0_C4_C6_0 +#define ICC_PPI_DOMAINR0_EL3 S3_6_C12_C8_4 +#define ICC_PPI_DOMAINR1_EL3 S3_6_C12_C8_5 +#define ICC_PPI_DOMAINR2_EL3 S3_6_C12_C8_6 +#define ICC_PPI_DOMAINR3_EL3 S3_6_C12_C8_7 + #define VSTCR_EL2 s3_4_c2_c6_2 #define VSCTLR_EL2 s3_4_c2_c0_0 @@ -245,6 +251,11 @@ static inline int has_gicv3_sysreg(void) return !!mrs_field(ID_AA64PFR0_EL1, GIC); } +static inline int has_gicv5_sysreg(void) +{ + return !!mrs_field(ID_AA64PFR2_EL1, GCIE); +} + #endif /* !__ASSEMBLY__ */ #endif diff --git a/common/gic-v5.c b/common/gic-v5.c new file mode 100644 index 0000000..cef2ece --- /dev/null +++ b/common/gic-v5.c @@ -0,0 +1,134 @@ +/* + * gic-v5.c + * + * Copyright (C) 2025 ARM Limited. All rights reserved. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE.txt file. + */ + +#include <stdint.h> + +#include <cpu.h> +#include <gic.h> +#include <asm/io.h> + +#define IWB_IDR0 0x0 +#define IWB_IDR0_IW_RANGE_SHIFT 0x0 +#define IWB_IDR0_IW_RANGE_MASK 0x7ff + +#define IWB_CR0 0x80 +#define IWB_CR0_IWBEN (1 << 0) +#define IWB_CR0_IDLE (1 << 1) + +#define IWB_WENABLE_STATUSR 0xc0 +#define IWB_WENABLE_STATUSR_IDLE (1 << 0) + +#define IWB_WDOMAIN_STATUSR 0xc4 +#define IWB_WDOMAIN_STATUSR_IDLE (1 << 0) + +#define IWB_WENABLER 0x2000 +#define IWB_WDOMAINR 0x8000 + +#define IRS_IDR6 0x0018 +#define IRS_IDR6_SPI_IRS_RANGE_MASK 0x1ffffff + +#define IRS_IDR7 0x001c +#define IRS_IDR7_SPI_BASE_MASK 0xffffff + +#define IRS_SPI_SELR 0x108 +#define IRS_SPI_DOMAINR 0x10c + +#define IRS_SPI_STATUSR 0x0118 +#define IRS_SPI_STATUSR_IDLE (1 << 0) + + +static void gic_iwb_init(void) { + void *iwb_ptr = (void *)GIC_IWB_BASE; + unsigned int num; + unsigned int i; + + /* Get number of implemented wires */ + num = ((raw_readl(iwb_ptr + IWB_IDR0) >> IWB_IDR0_IW_RANGE_SHIFT) & IWB_IDR0_IW_RANGE_MASK) + 1; + + /* Disable all wires */ + for (i = 0; i < num; i++) + raw_writel(0, iwb_ptr + IWB_WENABLER + i * 4); + + + while (!(raw_readl(iwb_ptr + IWB_WENABLE_STATUSR) & IWB_WENABLE_STATUSR_IDLE)); + + /* Asign all wires to Non-Secure domain */ + for (i = 0; i < num * 2; i++) + raw_writel(0x55555555, iwb_ptr + IWB_WDOMAINR + i * 4); + + while (!(raw_readl(iwb_ptr + IWB_WDOMAIN_STATUSR) & IWB_WDOMAIN_STATUSR_IDLE)); + + /* Enable IWB */ + raw_writel(IWB_CR0_IWBEN, iwb_ptr + IWB_CR0); + + while (!(raw_readl(iwb_ptr + IWB_CR0) & IWB_CR0_IDLE)); +} + +static void gic_irs_init(void) { + void *irs_ptr = (void *)GIC_IRS_BASE; + unsigned int range; + unsigned int base; + unsigned int i; + + /* Get the range of implemented SPI's ids */ + base = raw_readl(irs_ptr + IRS_IDR7) & IRS_IDR7_SPI_BASE_MASK; + range = raw_readl(irs_ptr + IRS_IDR6) & IRS_IDR6_SPI_IRS_RANGE_MASK; + + for (i = base; i < base + range; i++) { + /* Select SPI */ + raw_writel(i, irs_ptr + IRS_SPI_SELR); + while (!(raw_readl(irs_ptr + IRS_SPI_STATUSR) & IRS_SPI_STATUSR_IDLE)); + + /* Asign SPI to Non-Secure domain */ + raw_writel(1, irs_ptr + IRS_SPI_DOMAINR); + while (!(raw_readl(irs_ptr + IRS_SPI_STATUSR) & IRS_SPI_STATUSR_IDLE)); + } +} + +static void gic_ppi_init(void) { + uint64_t val = 0; + + val |= 1UL << (2 * 31); // Trace Buffer Unit + val |= 1UL << (2 * 30); // EL1 Physical Timer + val |= 1UL << (2 * 28); // Non-secure EL2 Virtual Timer + val |= 1UL << (2 * 27); // EL1 Virtual Timer + val |= 1UL << (2 * 26); // Non-secure EL2 Physical Timer + val |= 1UL << (2 * 25); // GIC maintenance interrupt + val |= 1UL << (2 * 24); // Generic CTI interrupt trigger event + val |= 1UL << (2 * 23); // PMU overflow interrupt request + val |= 1UL << (2 * 22); // Debug communication channel + val |= 1UL << (2 * 21); // Profiling Buffer management interrupt request + val |= 1UL << (2 * 15); // Hardware accelerator for cleaning Dirty state interrupt + val |= 1UL << (2 * 3); // Reserved for software usage + + /* Asign PPI to Non-Secure domain */ + msr(ICC_PPI_DOMAINR0_EL3, val); + isb(); +} + +void gic_secure_init(void) +{ + /* + * If GICv5 is not available, skip initialisation. The OS will probably + * fail with a warning, but this should be easier to debug than a + * failure within the boot wrapper. + */ + if (!has_gicv5_sysreg()) + return; + + if (this_cpu_logical_id() == 0) { + gic_iwb_init(); + gic_irs_init(); + } + + gic_ppi_init(); + + return; +} + diff --git a/configure.ac b/configure.ac index 6f486c4..f4faff7 100644 --- a/configure.ac +++ b/configure.ac @@ -141,18 +141,19 @@ AC_SUBST([XEN_CMDLINE], [$X_CMDLINE]) AC_ARG_WITH([gic], - AS_HELP_STRING([--with-gic={v2|v3}], [select GIC version]), + AS_HELP_STRING([--with-gic={v2|v3|v5}], [select GIC version]), [GIC_VERSION=$withval], [GIC_VERSION=v2]) AS_CASE([$GIC_VERSION], - [v2|v3], [], - [AC_MSG_ERROR([Invalid GIC version: $GIC_VERSION (use v2 or v3)])]) + [v2|v3|v5], [], + [AC_MSG_ERROR([Invalid GIC version: $GIC_VERSION (use v2, v3, or v5)])]) AC_SUBST([GIC_VERSION], [$GIC_VERSION]) AM_CONDITIONAL([GICV2], [test "x$GIC_VERSION" = "xv2"]) AM_CONDITIONAL([GICV3], [test "x$GIC_VERSION" = "xv3"]) +AM_CONDITIONAL([GICV5], [test "x$GIC_VERSION" = "xv5"]) # Ensure that we have all the needed programs diff --git a/scripts/FDT.pm b/scripts/FDT.pm index 9adf70b..3f49ba6 100755 --- a/scripts/FDT.pm +++ b/scripts/FDT.pm @@ -322,6 +322,22 @@ sub get_num_reg_cells return ($ac, $sc); } +sub get_regname_idx +{ + my $self = shift; + my $regname = shift; + + my $prop = $self->get_property("reg-names"); + + return undef if (not defined($prop)); + + my @names = $prop->read_strings(); + + my ($idx) = grep { $names[$_] eq $regname } 0 .. $#names; + + return $idx; +} + sub translate_address { my $self = shift; diff --git a/scripts/findbase-by-regname.pl b/scripts/findbase-by-regname.pl new file mode 100755 index 0000000..49cd0ce --- /dev/null +++ b/scripts/findbase-by-regname.pl @@ -0,0 +1,44 @@ +#!/usr/bin/perl -w +# Find device register base addresses. +# +# Usage: ./$0 <DTB> <regname> <compatible ...> +# +# Copyright (C) 2026 ARM Limited. All rights reserved. +# +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE.txt file. + +use warnings; +use strict; + +use FDT; + +my $filename = shift; +die("No filename provided") unless defined($filename); + +my $regname = shift; +die("no reg regname provided") unless defined($regname); + +my @compats = shift; + +open (my $fh, "<:raw", $filename) or die("Unable to open file '$filename'"); + +my $fdt = FDT->parse($fh) or die("Unable to parse DTB"); + +my $root = $fdt->get_root(); + +my @devs = (); +for my $compat (@compats) { + push @devs, $root->find_compatible($compat); +} + +# We only care about finding the first matching device +my $dev = shift @devs; +die("No matching devices found") if (not defined($dev)); + +my $idx = $dev->get_regname_idx($regname); +die("Cannot find reg name $regname") if (not defined($idx)); +my ($addr, $size) = $dev->get_translated_reg($idx); +die("Cannot find reg entry $idx") if (not defined($addr) or not defined($size)); + +printf("0x%016x\n", $addr); -- 2.34.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [BOOTWRAPPER PATCH v2 2/2] Add support for GICv5 2026-03-24 12:59 ` [BOOTWRAPPER PATCH v2 2/2] Add support for GICv5 Vladimir Murzin @ 2026-05-28 15:10 ` Sascha Bischoff 2026-05-29 9:48 ` Vladimir Murzin 0 siblings, 1 reply; 7+ messages in thread From: Sascha Bischoff @ 2026-05-28 15:10 UTC (permalink / raw) To: linux-arm-kernel@lists•infradead.org, Vladimir Murzin Cc: maz@kernel•org, Joey Gouly, Mark Rutland, nd Hi Vladimir, This looks good overall. There are a few nits around comments and one incorrect comment, but the code itself looks good to me and matches the spec as far as I can tell. I've gone and tested this, and it works as advertised to boot Linux (and run KVM) on a GICv5-enabled FVP. Hence: Tested-by: Sascha Bischoff <sascha.bischoff@arm•com> On Tue, 2026-03-24 at 12:59 +0000, Vladimir Murzin wrote: > Performs the minimal initialization required for GICv5 support. GICv5 > support can be requested with --with-gic=v5. > > Signed-off-by: Vladimir Murzin <vladimir.murzin@arm•com> > --- > Makefile.am | 7 ++ > arch/aarch64/include/asm/cpu.h | 11 +++ > common/gic-v5.c | 134 > +++++++++++++++++++++++++++++++++ > configure.ac | 7 +- > scripts/FDT.pm | 16 ++++ > scripts/findbase-by-regname.pl | 44 +++++++++++ > 6 files changed, 216 insertions(+), 3 deletions(-) > create mode 100644 common/gic-v5.c > create mode 100755 scripts/findbase-by-regname.pl > > diff --git a/Makefile.am b/Makefile.am > index 2710494..aacd639 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -82,6 +82,13 @@ PSCI_NODE := > CPU_NODES := > endif > > +if GICV5 > +GIC_IRS_BASE := $(shell perl -I $(SCRIPT_DIR) > $(SCRIPT_DIR)/findbase-by-regname.pl $(KERNEL_DTB) "el3-config" > 'arm,gic-v5-irs') > +GIC_IWB_BASE := $(shell perl -I $(SCRIPT_DIR) > $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,gic-v5-iwb') > +DEFINES += -DGIC_IRS_BASE=$(GIC_IRS_BASE) > +DEFINES += -DGIC_IWB_BASE=$(GIC_IWB_BASE) > +endif > + > if GICV3 > GIC_DIST_BASE := $(shell perl -I $(SCRIPT_DIR) > $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,gic-v3') > GIC_RDIST_BASE := $(shell perl -I $(SCRIPT_DIR) > $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 1 'arm,gic-v3') > diff --git a/arch/aarch64/include/asm/cpu.h > b/arch/aarch64/include/asm/cpu.h > index ac50474..af4191c 100644 > --- a/arch/aarch64/include/asm/cpu.h > +++ b/arch/aarch64/include/asm/cpu.h > @@ -128,6 +128,7 @@ > #define ID_AA64PFR1_EL1_THE BITS(51, 48) > > #define ID_AA64PFR2_EL1 s3_0_c0_c4_2 > +#define ID_AA64PFR2_EL1_GCIE BITS(15, 12) > #define ID_AA64PFR2_EL1_FPMR BITS(35, 32) > > #define ID_AA64SMFR0_EL1 s3_0_c0_c4_5 > @@ -169,6 +170,11 @@ > #define ICC_CTLR_EL3 S3_6_C12_C12_4 > #define ICC_PMR_EL1 S3_0_C4_C6_0 > > +#define ICC_PPI_DOMAINR0_EL3 S3_6_C12_C8_4 > +#define ICC_PPI_DOMAINR1_EL3 S3_6_C12_C8_5 > +#define ICC_PPI_DOMAINR2_EL3 S3_6_C12_C8_6 > +#define ICC_PPI_DOMAINR3_EL3 S3_6_C12_C8_7 > + > #define VSTCR_EL2 s3_4_c2_c6_2 > #define VSCTLR_EL2 s3_4_c2_c0_0 > > @@ -245,6 +251,11 @@ static inline int has_gicv3_sysreg(void) > return !!mrs_field(ID_AA64PFR0_EL1, GIC); > } > > +static inline int has_gicv5_sysreg(void) > +{ > + return !!mrs_field(ID_AA64PFR2_EL1, GCIE); > +} > + > #endif /* !__ASSEMBLY__ */ > > #endif > diff --git a/common/gic-v5.c b/common/gic-v5.c > new file mode 100644 > index 0000000..cef2ece > --- /dev/null > +++ b/common/gic-v5.c > @@ -0,0 +1,134 @@ > +/* > + * gic-v5.c > + * > + * Copyright (C) 2025 ARM Limited. All rights reserved. > + * > + * Use of this source code is governed by a BSD-style license that > can be > + * found in the LICENSE.txt file. > + */ > + > +#include <stdint.h> > + > +#include <cpu.h> > +#include <gic.h> > +#include <asm/io.h> > + > +#define IWB_IDR0 0x0 > +#define IWB_IDR0_IW_RANGE_SHIFT 0x0 > +#define IWB_IDR0_IW_RANGE_MASK 0x7ff > + > +#define IWB_CR0 0x80 > +#define IWB_CR0_IWBEN (1 << 0) > +#define IWB_CR0_IDLE (1 << 1) > + > +#define IWB_WENABLE_STATUSR 0xc0 > +#define IWB_WENABLE_STATUSR_IDLE (1 << 0) > + > +#define IWB_WDOMAIN_STATUSR 0xc4 > +#define IWB_WDOMAIN_STATUSR_IDLE (1 << 0) > + > +#define IWB_WENABLER 0x2000 > +#define IWB_WDOMAINR 0x8000 > + > +#define IRS_IDR6 0x0018 > +#define IRS_IDR6_SPI_IRS_RANGE_MASK 0x1ffffff > + > +#define IRS_IDR7 0x001c > +#define IRS_IDR7_SPI_BASE_MASK 0xffffff > + > +#define IRS_SPI_SELR 0x108 > +#define IRS_SPI_DOMAINR 0x10c > + > +#define IRS_SPI_STATUSR 0x0118 > +#define IRS_SPI_STATUSR_IDLE (1 << 0) > + > + nit: extra newline > +static void gic_iwb_init(void) { > + void *iwb_ptr = (void *)GIC_IWB_BASE; > + unsigned int num; > + unsigned int i; > + > + /* Get number of implemented wires */ This comment is wrong. This isn't getting the number of wires. It is getting the number of wire control registers, which is number_of_wires/32. > + num = ((raw_readl(iwb_ptr + IWB_IDR0) >> > IWB_IDR0_IW_RANGE_SHIFT) & IWB_IDR0_IW_RANGE_MASK) + 1; > + > + /* Disable all wires */ > + for (i = 0; i < num; i++) > + raw_writel(0, iwb_ptr + IWB_WENABLER + i * 4); > + > + Extra newline > + while (!(raw_readl(iwb_ptr + IWB_WENABLE_STATUSR) & > IWB_WENABLE_STATUSR_IDLE)); > + > + /* Asign all wires to Non-Secure domain */ nit: Assign > + for (i = 0; i < num * 2; i++) > + raw_writel(0x55555555, iwb_ptr + IWB_WDOMAINR + i * > 4); > + > + while (!(raw_readl(iwb_ptr + IWB_WDOMAIN_STATUSR) & > IWB_WDOMAIN_STATUSR_IDLE)); > + > + /* Enable IWB */ > + raw_writel(IWB_CR0_IWBEN, iwb_ptr + IWB_CR0); > + > + while (!(raw_readl(iwb_ptr + IWB_CR0) & IWB_CR0_IDLE)); > +} > + > +static void gic_irs_init(void) { > + void *irs_ptr = (void *)GIC_IRS_BASE; > + unsigned int range; > + unsigned int base; > + unsigned int i; > + > + /* Get the range of implemented SPI's ids */ nit: SPI IDs (or just SPIs) > + base = raw_readl(irs_ptr + IRS_IDR7) & > IRS_IDR7_SPI_BASE_MASK; > + range = raw_readl(irs_ptr + IRS_IDR6) & > IRS_IDR6_SPI_IRS_RANGE_MASK; > + > + for (i = base; i < base + range; i++) { > + /* Select SPI */ > + raw_writel(i, irs_ptr + IRS_SPI_SELR); > + while (!(raw_readl(irs_ptr + IRS_SPI_STATUSR) & > IRS_SPI_STATUSR_IDLE)); > + > + /* Asign SPI to Non-Secure domain */ > + raw_writel(1, irs_ptr + IRS_SPI_DOMAINR); > + while (!(raw_readl(irs_ptr + IRS_SPI_STATUSR) & > IRS_SPI_STATUSR_IDLE)); > + } > +} > + > +static void gic_ppi_init(void) { > + uint64_t val = 0; > + > + val |= 1UL << (2 * 31); // Trace Buffer Unit > + val |= 1UL << (2 * 30); // EL1 Physical Timer > + val |= 1UL << (2 * 28); // Non-secure EL2 Virtual Timer > + val |= 1UL << (2 * 27); // EL1 Virtual Timer > + val |= 1UL << (2 * 26); // Non-secure EL2 Physical Timer > + val |= 1UL << (2 * 25); // GIC maintenance interrupt > + val |= 1UL << (2 * 24); // Generic CTI interrupt trigger > event > + val |= 1UL << (2 * 23); // PMU overflow interrupt request > + val |= 1UL << (2 * 22); // Debug communication channel > + val |= 1UL << (2 * 21); // Profiling Buffer management > interrupt request > + val |= 1UL << (2 * 15); // Hardware accelerator for cleaning > Dirty state interrupt > + val |= 1UL << (2 * 3); // Reserved for software usage > + > + /* Asign PPI to Non-Secure domain */ nit: Assign PPIs > + msr(ICC_PPI_DOMAINR0_EL3, val); > + isb(); > +} > + > +void gic_secure_init(void) > +{ > + /* > + * If GICv5 is not available, skip initialisation. The OS > will probably > + * fail with a warning, but this should be easier to debug > than a > + * failure within the boot wrapper. > + */ > + if (!has_gicv5_sysreg()) > + return; > + > + if (this_cpu_logical_id() == 0) { > + gic_iwb_init(); > + gic_irs_init(); > + } > + > + gic_ppi_init(); > + > + return; > +} > + > diff --git a/configure.ac b/configure.ac > index 6f486c4..f4faff7 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -141,18 +141,19 @@ AC_SUBST([XEN_CMDLINE], [$X_CMDLINE]) > > > AC_ARG_WITH([gic], > - AS_HELP_STRING([--with-gic={v2|v3}], [select GIC version]), > + AS_HELP_STRING([--with-gic={v2|v3|v5}], [select GIC version]), > [GIC_VERSION=$withval], > [GIC_VERSION=v2]) > > AS_CASE([$GIC_VERSION], > - [v2|v3], [], > - [AC_MSG_ERROR([Invalid GIC version: $GIC_VERSION (use v2 or > v3)])]) > + [v2|v3|v5], [], > + [AC_MSG_ERROR([Invalid GIC version: $GIC_VERSION (use v2, v3, or > v5)])]) > > AC_SUBST([GIC_VERSION], [$GIC_VERSION]) > > AM_CONDITIONAL([GICV2], [test "x$GIC_VERSION" = "xv2"]) > AM_CONDITIONAL([GICV3], [test "x$GIC_VERSION" = "xv3"]) > +AM_CONDITIONAL([GICV5], [test "x$GIC_VERSION" = "xv5"]) > > > # Ensure that we have all the needed programs > diff --git a/scripts/FDT.pm b/scripts/FDT.pm > index 9adf70b..3f49ba6 100755 > --- a/scripts/FDT.pm > +++ b/scripts/FDT.pm > @@ -322,6 +322,22 @@ sub get_num_reg_cells > return ($ac, $sc); > } > > +sub get_regname_idx > +{ > + my $self = shift; > + my $regname = shift; > + > + my $prop = $self->get_property("reg-names"); > + > + return undef if (not defined($prop)); > + > + my @names = $prop->read_strings(); > + > + my ($idx) = grep { $names[$_] eq $regname } 0 .. $#names; > + > + return $idx; > +} > + > sub translate_address > { > my $self = shift; > diff --git a/scripts/findbase-by-regname.pl b/scripts/findbase-by- > regname.pl > new file mode 100755 > index 0000000..49cd0ce > --- /dev/null > +++ b/scripts/findbase-by-regname.pl > @@ -0,0 +1,44 @@ > +#!/usr/bin/perl -w > +# Find device register base addresses. > +# > +# Usage: ./$0 <DTB> <regname> <compatible ...> > +# > +# Copyright (C) 2026 ARM Limited. All rights reserved. > +# > +# Use of this source code is governed by a BSD-style license that > can be > +# found in the LICENSE.txt file. > + > +use warnings; > +use strict; > + > +use FDT; > + > +my $filename = shift; > +die("No filename provided") unless defined($filename); > + > +my $regname = shift; > +die("no reg regname provided") unless defined($regname); > + > +my @compats = shift; > + > +open (my $fh, "<:raw", $filename) or die("Unable to open file > '$filename'"); > + > +my $fdt = FDT->parse($fh) or die("Unable to parse DTB"); > + > +my $root = $fdt->get_root(); > + > +my @devs = (); > +for my $compat (@compats) { > + push @devs, $root->find_compatible($compat); > +} > + > +# We only care about finding the first matching device > +my $dev = shift @devs; > +die("No matching devices found") if (not defined($dev)); > + > +my $idx = $dev->get_regname_idx($regname); > +die("Cannot find reg name $regname") if (not defined($idx)); > +my ($addr, $size) = $dev->get_translated_reg($idx); > +die("Cannot find reg entry $idx") if (not defined($addr) or not > defined($size)); > + > +printf("0x%016x\n", $addr); Thanks, Sascha ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [BOOTWRAPPER PATCH v2 2/2] Add support for GICv5 2026-05-28 15:10 ` Sascha Bischoff @ 2026-05-29 9:48 ` Vladimir Murzin 0 siblings, 0 replies; 7+ messages in thread From: Vladimir Murzin @ 2026-05-29 9:48 UTC (permalink / raw) To: Sascha Bischoff, linux-arm-kernel@lists•infradead.org Cc: maz@kernel•org, Joey Gouly, Mark Rutland, nd Hi Sascha, On 5/28/26 16:10, Sascha Bischoff wrote: > Hi Vladimir, > > This looks good overall. There are a few nits around comments and one > incorrect comment, but the code itself looks good to me and matches the > spec as far as I can tell. > > I've gone and tested this, and it works as advertised to boot Linux > (and run KVM) on a GICv5-enabled FVP. Hence: > > Tested-by: Sascha Bischoff <sascha.bischoff@arm•com> > Happy to hear it works not only in my setup :) > On Tue, 2026-03-24 at 12:59 +0000, Vladimir Murzin wrote: >> Performs the minimal initialization required for GICv5 support. GICv5 >> support can be requested with --with-gic=v5. >> >> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm•com> >> --- >> Makefile.am | 7 ++ >> arch/aarch64/include/asm/cpu.h | 11 +++ >> common/gic-v5.c | 134 >> +++++++++++++++++++++++++++++++++ >> configure.ac | 7 +- >> scripts/FDT.pm | 16 ++++ >> scripts/findbase-by-regname.pl | 44 +++++++++++ >> 6 files changed, 216 insertions(+), 3 deletions(-) >> create mode 100644 common/gic-v5.c >> create mode 100755 scripts/findbase-by-regname.pl >> >> diff --git a/Makefile.am b/Makefile.am >> index 2710494..aacd639 100644 >> --- a/Makefile.am >> +++ b/Makefile.am >> @@ -82,6 +82,13 @@ PSCI_NODE := >> CPU_NODES := >> endif >> >> +if GICV5 >> +GIC_IRS_BASE := $(shell perl -I $(SCRIPT_DIR) >> $(SCRIPT_DIR)/findbase-by-regname.pl $(KERNEL_DTB) "el3-config" >> 'arm,gic-v5-irs') >> +GIC_IWB_BASE := $(shell perl -I $(SCRIPT_DIR) >> $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,gic-v5-iwb') >> +DEFINES += -DGIC_IRS_BASE=$(GIC_IRS_BASE) >> +DEFINES += -DGIC_IWB_BASE=$(GIC_IWB_BASE) >> +endif >> + >> if GICV3 >> GIC_DIST_BASE := $(shell perl -I $(SCRIPT_DIR) >> $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,gic-v3') >> GIC_RDIST_BASE := $(shell perl -I $(SCRIPT_DIR) >> $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 1 'arm,gic-v3') >> diff --git a/arch/aarch64/include/asm/cpu.h >> b/arch/aarch64/include/asm/cpu.h >> index ac50474..af4191c 100644 >> --- a/arch/aarch64/include/asm/cpu.h >> +++ b/arch/aarch64/include/asm/cpu.h >> @@ -128,6 +128,7 @@ >> #define ID_AA64PFR1_EL1_THE BITS(51, 48) >> >> #define ID_AA64PFR2_EL1 s3_0_c0_c4_2 >> +#define ID_AA64PFR2_EL1_GCIE BITS(15, 12) >> #define ID_AA64PFR2_EL1_FPMR BITS(35, 32) >> >> #define ID_AA64SMFR0_EL1 s3_0_c0_c4_5 >> @@ -169,6 +170,11 @@ >> #define ICC_CTLR_EL3 S3_6_C12_C12_4 >> #define ICC_PMR_EL1 S3_0_C4_C6_0 >> >> +#define ICC_PPI_DOMAINR0_EL3 S3_6_C12_C8_4 >> +#define ICC_PPI_DOMAINR1_EL3 S3_6_C12_C8_5 >> +#define ICC_PPI_DOMAINR2_EL3 S3_6_C12_C8_6 >> +#define ICC_PPI_DOMAINR3_EL3 S3_6_C12_C8_7 >> + >> #define VSTCR_EL2 s3_4_c2_c6_2 >> #define VSCTLR_EL2 s3_4_c2_c0_0 >> >> @@ -245,6 +251,11 @@ static inline int has_gicv3_sysreg(void) >> return !!mrs_field(ID_AA64PFR0_EL1, GIC); >> } >> >> +static inline int has_gicv5_sysreg(void) >> +{ >> + return !!mrs_field(ID_AA64PFR2_EL1, GCIE); >> +} >> + >> #endif /* !__ASSEMBLY__ */ >> >> #endif >> diff --git a/common/gic-v5.c b/common/gic-v5.c >> new file mode 100644 >> index 0000000..cef2ece >> --- /dev/null >> +++ b/common/gic-v5.c >> @@ -0,0 +1,134 @@ >> +/* >> + * gic-v5.c >> + * >> + * Copyright (C) 2025 ARM Limited. All rights reserved. >> + * >> + * Use of this source code is governed by a BSD-style license that >> can be >> + * found in the LICENSE.txt file. >> + */ >> + >> +#include <stdint.h> >> + >> +#include <cpu.h> >> +#include <gic.h> >> +#include <asm/io.h> >> + >> +#define IWB_IDR0 0x0 >> +#define IWB_IDR0_IW_RANGE_SHIFT 0x0 >> +#define IWB_IDR0_IW_RANGE_MASK 0x7ff >> + >> +#define IWB_CR0 0x80 >> +#define IWB_CR0_IWBEN (1 << 0) >> +#define IWB_CR0_IDLE (1 << 1) >> + >> +#define IWB_WENABLE_STATUSR 0xc0 >> +#define IWB_WENABLE_STATUSR_IDLE (1 << 0) >> + >> +#define IWB_WDOMAIN_STATUSR 0xc4 >> +#define IWB_WDOMAIN_STATUSR_IDLE (1 << 0) >> + >> +#define IWB_WENABLER 0x2000 >> +#define IWB_WDOMAINR 0x8000 >> + >> +#define IRS_IDR6 0x0018 >> +#define IRS_IDR6_SPI_IRS_RANGE_MASK 0x1ffffff >> + >> +#define IRS_IDR7 0x001c >> +#define IRS_IDR7_SPI_BASE_MASK 0xffffff >> + >> +#define IRS_SPI_SELR 0x108 >> +#define IRS_SPI_DOMAINR 0x10c >> + >> +#define IRS_SPI_STATUSR 0x0118 >> +#define IRS_SPI_STATUSR_IDLE (1 << 0) >> + >> + > nit: extra newline > >> +static void gic_iwb_init(void) { >> + void *iwb_ptr = (void *)GIC_IWB_BASE; >> + unsigned int num; >> + unsigned int i; >> + >> + /* Get number of implemented wires */ > This comment is wrong. This isn't getting the number of wires. It is > getting the number of wire control registers, which is > number_of_wires/32. > >> + num = ((raw_readl(iwb_ptr + IWB_IDR0) >> >> IWB_IDR0_IW_RANGE_SHIFT) & IWB_IDR0_IW_RANGE_MASK) + 1; >> + >> + /* Disable all wires */ >> + for (i = 0; i < num; i++) >> + raw_writel(0, iwb_ptr + IWB_WENABLER + i * 4); >> + >> + > Extra newline > >> + while (!(raw_readl(iwb_ptr + IWB_WENABLE_STATUSR) & >> IWB_WENABLE_STATUSR_IDLE)); >> + >> + /* Asign all wires to Non-Secure domain */ > nit: Assign > >> + for (i = 0; i < num * 2; i++) >> + raw_writel(0x55555555, iwb_ptr + IWB_WDOMAINR + i * >> 4); >> + >> + while (!(raw_readl(iwb_ptr + IWB_WDOMAIN_STATUSR) & >> IWB_WDOMAIN_STATUSR_IDLE)); >> + >> + /* Enable IWB */ >> + raw_writel(IWB_CR0_IWBEN, iwb_ptr + IWB_CR0); >> + >> + while (!(raw_readl(iwb_ptr + IWB_CR0) & IWB_CR0_IDLE)); >> +} >> + >> +static void gic_irs_init(void) { >> + void *irs_ptr = (void *)GIC_IRS_BASE; >> + unsigned int range; >> + unsigned int base; >> + unsigned int i; >> + >> + /* Get the range of implemented SPI's ids */ > nit: SPI IDs (or just SPIs) > >> + base = raw_readl(irs_ptr + IRS_IDR7) & >> IRS_IDR7_SPI_BASE_MASK; >> + range = raw_readl(irs_ptr + IRS_IDR6) & >> IRS_IDR6_SPI_IRS_RANGE_MASK; >> + >> + for (i = base; i < base + range; i++) { >> + /* Select SPI */ >> + raw_writel(i, irs_ptr + IRS_SPI_SELR); >> + while (!(raw_readl(irs_ptr + IRS_SPI_STATUSR) & >> IRS_SPI_STATUSR_IDLE)); >> + >> + /* Asign SPI to Non-Secure domain */ >> + raw_writel(1, irs_ptr + IRS_SPI_DOMAINR); >> + while (!(raw_readl(irs_ptr + IRS_SPI_STATUSR) & >> IRS_SPI_STATUSR_IDLE)); >> + } >> +} >> + >> +static void gic_ppi_init(void) { >> + uint64_t val = 0; >> + >> + val |= 1UL << (2 * 31); // Trace Buffer Unit >> + val |= 1UL << (2 * 30); // EL1 Physical Timer >> + val |= 1UL << (2 * 28); // Non-secure EL2 Virtual Timer >> + val |= 1UL << (2 * 27); // EL1 Virtual Timer >> + val |= 1UL << (2 * 26); // Non-secure EL2 Physical Timer >> + val |= 1UL << (2 * 25); // GIC maintenance interrupt >> + val |= 1UL << (2 * 24); // Generic CTI interrupt trigger >> event >> + val |= 1UL << (2 * 23); // PMU overflow interrupt request >> + val |= 1UL << (2 * 22); // Debug communication channel >> + val |= 1UL << (2 * 21); // Profiling Buffer management >> interrupt request >> + val |= 1UL << (2 * 15); // Hardware accelerator for cleaning >> Dirty state interrupt >> + val |= 1UL << (2 * 3); // Reserved for software usage >> + >> + /* Asign PPI to Non-Secure domain */ > nit: Assign PPIs > >> + msr(ICC_PPI_DOMAINR0_EL3, val); >> + isb(); >> +} >> + >> +void gic_secure_init(void) >> +{ >> + /* >> + * If GICv5 is not available, skip initialisation. The OS >> will probably >> + * fail with a warning, but this should be easier to debug >> than a >> + * failure within the boot wrapper. >> + */ >> + if (!has_gicv5_sysreg()) >> + return; >> + >> + if (this_cpu_logical_id() == 0) { >> + gic_iwb_init(); >> + gic_irs_init(); >> + } >> + >> + gic_ppi_init(); >> + >> + return; >> +} >> + >> diff --git a/configure.ac b/configure.ac >> index 6f486c4..f4faff7 100644 >> --- a/configure.ac >> +++ b/configure.ac >> @@ -141,18 +141,19 @@ AC_SUBST([XEN_CMDLINE], [$X_CMDLINE]) >> >> >> AC_ARG_WITH([gic], >> - AS_HELP_STRING([--with-gic={v2|v3}], [select GIC version]), >> + AS_HELP_STRING([--with-gic={v2|v3|v5}], [select GIC version]), >> [GIC_VERSION=$withval], >> [GIC_VERSION=v2]) >> >> AS_CASE([$GIC_VERSION], >> - [v2|v3], [], >> - [AC_MSG_ERROR([Invalid GIC version: $GIC_VERSION (use v2 or >> v3)])]) >> + [v2|v3|v5], [], >> + [AC_MSG_ERROR([Invalid GIC version: $GIC_VERSION (use v2, v3, or >> v5)])]) >> >> AC_SUBST([GIC_VERSION], [$GIC_VERSION]) >> >> AM_CONDITIONAL([GICV2], [test "x$GIC_VERSION" = "xv2"]) >> AM_CONDITIONAL([GICV3], [test "x$GIC_VERSION" = "xv3"]) >> +AM_CONDITIONAL([GICV5], [test "x$GIC_VERSION" = "xv5"]) >> >> >> # Ensure that we have all the needed programs >> diff --git a/scripts/FDT.pm b/scripts/FDT.pm >> index 9adf70b..3f49ba6 100755 >> --- a/scripts/FDT.pm >> +++ b/scripts/FDT.pm >> @@ -322,6 +322,22 @@ sub get_num_reg_cells >> return ($ac, $sc); >> } >> >> +sub get_regname_idx >> +{ >> + my $self = shift; >> + my $regname = shift; >> + >> + my $prop = $self->get_property("reg-names"); >> + >> + return undef if (not defined($prop)); >> + >> + my @names = $prop->read_strings(); >> + >> + my ($idx) = grep { $names[$_] eq $regname } 0 .. $#names; >> + >> + return $idx; >> +} >> + >> sub translate_address >> { >> my $self = shift; >> diff --git a/scripts/findbase-by-regname.pl b/scripts/findbase-by- >> regname.pl >> new file mode 100755 >> index 0000000..49cd0ce >> --- /dev/null >> +++ b/scripts/findbase-by-regname.pl >> @@ -0,0 +1,44 @@ >> +#!/usr/bin/perl -w >> +# Find device register base addresses. >> +# >> +# Usage: ./$0 <DTB> <regname> <compatible ...> >> +# >> +# Copyright (C) 2026 ARM Limited. All rights reserved. >> +# >> +# Use of this source code is governed by a BSD-style license that >> can be >> +# found in the LICENSE.txt file. >> + >> +use warnings; >> +use strict; >> + >> +use FDT; >> + >> +my $filename = shift; >> +die("No filename provided") unless defined($filename); >> + >> +my $regname = shift; >> +die("no reg regname provided") unless defined($regname); >> + >> +my @compats = shift; >> + >> +open (my $fh, "<:raw", $filename) or die("Unable to open file >> '$filename'"); >> + >> +my $fdt = FDT->parse($fh) or die("Unable to parse DTB"); >> + >> +my $root = $fdt->get_root(); >> + >> +my @devs = (); >> +for my $compat (@compats) { >> + push @devs, $root->find_compatible($compat); >> +} >> + >> +# We only care about finding the first matching device >> +my $dev = shift @devs; >> +die("No matching devices found") if (not defined($dev)); >> + >> +my $idx = $dev->get_regname_idx($regname); >> +die("Cannot find reg name $regname") if (not defined($idx)); >> +my ($addr, $size) = $dev->get_translated_reg($idx); >> +die("Cannot find reg entry $idx") if (not defined($addr) or not >> defined($size)); >> + >> +printf("0x%016x\n", $addr); > Thanks, > Sascha > Thanks Sascha, all fixed locally. Cheers Vladimir ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-05-29 9:49 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-03-24 12:59 [BOOTWRAPPER PATCH v2 0/2] Support GICv5 Vladimir Murzin 2026-03-24 12:59 ` [BOOTWRAPPER PATCH v2 1/2] Introduce --with-gic option Vladimir Murzin 2026-05-28 15:06 ` Sascha Bischoff 2026-05-29 9:47 ` Vladimir Murzin 2026-03-24 12:59 ` [BOOTWRAPPER PATCH v2 2/2] Add support for GICv5 Vladimir Murzin 2026-05-28 15:10 ` Sascha Bischoff 2026-05-29 9:48 ` Vladimir Murzin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox