diff options
author | Soby Mathew <soby.mathew@arm.com> | 2018-10-12 16:26:20 +0100 |
---|---|---|
committer | Soby Mathew <soby.mathew@arm.com> | 2018-10-29 09:54:31 +0000 |
commit | 6a7b30057806c3573ee0194b7aa583bd60c89371 (patch) | |
tree | 33e09ffc84f804cdb24ecabe112538df09a0868a /plat | |
parent | 9aabd11a424770e11dd89251960678d3e3332df6 (diff) | |
download | platform_external_arm-trusted-firmware-6a7b30057806c3573ee0194b7aa583bd60c89371.tar.gz platform_external_arm-trusted-firmware-6a7b30057806c3573ee0194b7aa583bd60c89371.tar.bz2 platform_external_arm-trusted-firmware-6a7b30057806c3573ee0194b7aa583bd60c89371.zip |
Add helper to return reference to a symbol
This patch adds a utility function to return
the address of a symbol. By default, the compiler
generates adr/adrp instruction pair to return
the reference and this utility is used to override
this compiler generated to code and use `ldr`
instruction.
This is needed for Position Independent Executable
when it needs to reference a symbol which is constant
and does not depend on the execute address of the
binary.
For example, on the FVP, the GICv3 register context is
stored in a secure carveout (arm_el3_tzc_dram) within
DDR and does not relocate with the BL image. Now if
BL31 is executing at a different address other than
the compiled address, using adrp/adr instructions to
reference this memory will not work as they generate an
address that is PC relative. The way to get around this
problem is to reference it as non-PC relative (i.e
non-relocatable location) via `ldr` instruction.
Change-Id: I5008a951b007144258121690afb68dc8e12ee6f7
Signed-off-by: Soby Mathew <soby.mathew@arm.com>
Diffstat (limited to 'plat')
-rw-r--r-- | plat/arm/common/arm_gicv3.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c index e9e8a74d9..a43bff3d4 100644 --- a/plat/arm/common/arm_gicv3.c +++ b/plat/arm/common/arm_gicv3.c @@ -10,6 +10,7 @@ #include <plat_arm.h> #include <platform.h> #include <platform_def.h> +#include <utils.h> /****************************************************************************** * The following functions are defined as weak to allow a platform to override @@ -33,10 +34,16 @@ static const interrupt_prop_t arm_interrupt_props[] = { /* * We save and restore the GICv3 context on system suspend. Allocate the - * data in the designated EL3 Secure carve-out memory + * data in the designated EL3 Secure carve-out memory. The `volatile` + * is used to prevent the compiler from removing the gicv3 contexts even + * though the DEFINE_LOAD_SYM_ADDR creates a dummy reference to it. */ -static gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram"); -static gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram"); +static volatile gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram"); +static volatile gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram"); + +/* Define accessor function to get reference to the GICv3 context */ +DEFINE_LOAD_SYM_ADDR(rdist_ctx) +DEFINE_LOAD_SYM_ADDR(dist_ctx) /* * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register @@ -134,6 +141,10 @@ void plat_arm_gic_redistif_off(void) *****************************************************************************/ void plat_arm_gic_save(void) { + gicv3_redist_ctx_t * const rdist_context = + (gicv3_redist_ctx_t *)LOAD_ADDR_OF(rdist_ctx); + gicv3_dist_ctx_t * const dist_context = + (gicv3_dist_ctx_t *)LOAD_ADDR_OF(dist_ctx); /* * If an ITS is available, save its context before @@ -149,10 +160,10 @@ void plat_arm_gic_save(void) * we only need to save the context of the CPU that is issuing * the SYSTEM SUSPEND call, i.e. the current CPU. */ - gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx); + gicv3_rdistif_save(plat_my_core_pos(), rdist_context); /* Save the GIC Distributor context */ - gicv3_distif_save(&dist_ctx); + gicv3_distif_save(dist_context); /* * From here, all the components of the GIC can be safely powered down @@ -163,8 +174,13 @@ void plat_arm_gic_save(void) void plat_arm_gic_resume(void) { + const gicv3_redist_ctx_t *rdist_context = + (gicv3_redist_ctx_t *)LOAD_ADDR_OF(rdist_ctx); + const gicv3_dist_ctx_t *dist_context = + (gicv3_dist_ctx_t *)LOAD_ADDR_OF(dist_ctx); + /* Restore the GIC Distributor context */ - gicv3_distif_init_restore(&dist_ctx); + gicv3_distif_init_restore(dist_context); /* * Restore the GIC Redistributor and ITS contexts after the @@ -172,7 +188,7 @@ void plat_arm_gic_resume(void) * we only need to restore the context of the CPU that issued * the SYSTEM SUSPEND call. */ - gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx); + gicv3_rdistif_init_restore(plat_my_core_pos(), rdist_context); /* * If an ITS is available, restore its context after |