diff options
author | dp-arm <dimitris.papastamos@arm.com> | 2017-05-23 09:32:49 +0100 |
---|---|---|
committer | Dimitris Papastamos <dimitris.papastamos@arm.com> | 2017-06-22 10:33:19 +0100 |
commit | d832aee900a92d14a08a6a2a552894188404b6a4 (patch) | |
tree | f1e12914f0bc1f687509f1b7fbbaf172a335acfd /plat/arm | |
parent | 18f2efd67d881fe0a9a535ce9e801e60d746e024 (diff) |
aarch64: Enable Statistical Profiling Extensions for lower ELs
SPE is only supported in non-secure state. Accesses to SPE specific
registers from SEL1 will trap to EL3. During a world switch, before
`TTBR` is modified the SPE profiling buffers are drained. This is to
avoid a potential invalid memory access in SEL1.
SPE is architecturally specified only for AArch64.
Change-Id: I04a96427d9f9d586c331913d815fdc726855f6b0
Signed-off-by: dp-arm <dimitris.papastamos@arm.com>
Diffstat (limited to 'plat/arm')
-rw-r--r-- | plat/arm/board/fvp/fvp_pm.c | 8 | ||||
-rw-r--r-- | plat/arm/common/aarch64/arm_helpers.S | 29 |
2 files changed, 37 insertions, 0 deletions
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c index f4df658a..e39a4d50 100644 --- a/plat/arm/board/fvp/fvp_pm.c +++ b/plat/arm/board/fvp/fvp_pm.c @@ -48,6 +48,14 @@ static void fvp_cluster_pwrdwn_common(void) { uint64_t mpidr = read_mpidr_el1(); +#if ENABLE_SPE_FOR_LOWER_ELS + /* + * On power down we need to disable statistical profiling extensions + * before exiting coherency. + */ + arm_disable_spe(); +#endif + /* Disable coherency if this cluster is to be turned off */ fvp_interconnect_disable(); diff --git a/plat/arm/common/aarch64/arm_helpers.S b/plat/arm/common/aarch64/arm_helpers.S index 1f20cb50..86565f57 100644 --- a/plat/arm/common/aarch64/arm_helpers.S +++ b/plat/arm/common/aarch64/arm_helpers.S @@ -12,6 +12,7 @@ .globl plat_crash_console_putc .globl plat_crash_console_flush .globl platform_mem_init + .globl arm_disable_spe /* ----------------------------------------------------- @@ -86,3 +87,31 @@ endfunc plat_crash_console_flush func platform_mem_init ret endfunc platform_mem_init + + /* ----------------------------------------------------- + * void arm_disable_spe (void); + * ----------------------------------------------------- + */ +#if ENABLE_SPE_FOR_LOWER_ELS +func arm_disable_spe + /* Detect if SPE is implemented */ + mrs x0, id_aa64dfr0_el1 + ubfx x0, x0, #ID_AA64DFR0_PMS_SHIFT, #ID_AA64DFR0_PMS_LENGTH + cmp x0, #0x1 + b.ne 1f + + /* Drain buffered data */ + .arch armv8.2-a+profile + psb csync + dsb nsh + + /* Disable Profiling Buffer */ + mrs x0, pmblimitr_el1 + bic x0, x0, #1 + msr pmblimitr_el1, x0 + isb + .arch armv8-a +1: + ret +endfunc arm_disable_spe +#endif |