diff options
author | Vijayenthiran Subramaniam <vijayenthiran.subramaniam@arm.com> | 2019-10-11 14:01:25 +0530 |
---|---|---|
committer | Vijayenthiran Subramaniam <vijayenthiran.subramaniam@arm.com> | 2019-11-05 10:51:24 +0530 |
commit | 74c21244005f639812b0cc68f71e501f831d8f70 (patch) | |
tree | f99113ecca8fbcc48403eab42d7cff1366a5daae | |
parent | 1d2b41614c5675b144ae1f4517c1f8bf249a12d2 (diff) | |
download | platform_external_arm-trusted-firmware-74c21244005f639812b0cc68f71e501f831d8f70.tar.gz platform_external_arm-trusted-firmware-74c21244005f639812b0cc68f71e501f831d8f70.tar.bz2 platform_external_arm-trusted-firmware-74c21244005f639812b0cc68f71e501f831d8f70.zip |
plat/arm/gicv3: add support for probing multiple GIC Redistributor frames
ARM platform can have a non-contiguous GICR frames. For instance, a
multi socket platform can have two or more GIC Redistributor frames
which are 4TB apart. Hence it is necessary for the `gicv3_rdistif_probe`
function to probe all the GICR frames available in the platform.
Introduce `plat_arm_override_gicr_frames` function which platforms can
use to override the default gicr_frames which holds the GICR base
address of the primary cpu.
Change-Id: I1f537b0d871a679cb256092944737f2e55ab866e
Signed-off-by: Vijayenthiran Subramaniam <vijayenthiran.subramaniam@arm.com>
-rw-r--r-- | include/plat/arm/common/plat_arm.h | 5 | ||||
-rw-r--r-- | plat/arm/common/arm_gicv3.c | 38 |
2 files changed, 39 insertions, 4 deletions
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 07a46c518..c00a04126 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -254,6 +254,11 @@ void plat_arm_program_trusted_mailbox(uintptr_t address); int plat_arm_bl1_fwu_needed(void); __dead2 void plat_arm_error_handler(int err); +/* + * Optional function in ARM standard platforms + */ +void plat_arm_override_gicr_frames(const uintptr_t *plat_gicr_frames); + #if ARM_PLAT_MT unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr); #endif diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c index fef53761c..cfc535939 100644 --- a/plat/arm/common/arm_gicv3.c +++ b/plat/arm/common/arm_gicv3.c @@ -28,6 +28,15 @@ /* The GICv3 driver only needs to be initialized in EL3 */ static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; +/* Default GICR base address to be used for GICR probe. */ +static const uintptr_t gicr_base_addrs[2] = { + PLAT_ARM_GICR_BASE, /* GICR Base address of the primary CPU */ + 0U /* Zero Termination */ +}; + +/* List of zero terminated GICR frame addresses which CPUs will probe */ +static const uintptr_t *gicr_frames = gicr_base_addrs; + static const interrupt_prop_t arm_interrupt_props[] = { PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S), PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0) @@ -76,6 +85,18 @@ static const gicv3_driver_data_t arm_gic_data __unused = { .mpidr_to_core_pos = arm_gicv3_mpidr_hash }; +/* + * By default, gicr_frames will be pointing to gicr_base_addrs. If + * the platform supports a non-contiguous GICR frames (GICR frames located + * at uneven offset), plat_arm_override_gicr_frames function can be used by + * such platform to override the gicr_frames. + */ +void plat_arm_override_gicr_frames(const uintptr_t *plat_gicr_frames) +{ + assert(plat_gicr_frames != NULL); + gicr_frames = plat_gicr_frames; +} + void __init plat_arm_gic_driver_init(void) { /* @@ -88,7 +109,7 @@ void __init plat_arm_gic_driver_init(void) (defined(__aarch64__) && defined(IMAGE_BL31)) gicv3_driver_init(&arm_gic_data); - if (gicv3_rdistif_probe(PLAT_ARM_GICR_BASE) == -1) { + if (gicv3_rdistif_probe(gicr_base_addrs[0]) == -1) { ERROR("No GICR base frame found for Primary CPU\n"); panic(); } @@ -124,14 +145,23 @@ void plat_arm_gic_cpuif_disable(void) /****************************************************************************** * ARM common helper function to iterate over all GICR frames and discover the * corresponding per-cpu redistributor frame as well as initialize the - * corresponding interface in GICv3. At the moment, Arm platforms do not have - * non-contiguous GICR frames. + * corresponding interface in GICv3. *****************************************************************************/ void plat_arm_gic_pcpu_init(void) { int result; + const uintptr_t *plat_gicr_frames = gicr_frames; + + do { + result = gicv3_rdistif_probe(*plat_gicr_frames); + + /* If the probe is successful, no need to proceed further */ + if (result == 0) + break; + + plat_gicr_frames++; + } while (*plat_gicr_frames != 0U); - result = gicv3_rdistif_probe(PLAT_ARM_GICR_BASE); if (result == -1) { ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr()); panic(); |