summaryrefslogtreecommitdiff
path: root/plat/arm
diff options
context:
space:
mode:
authordp-arm <dimitris.papastamos@arm.com>2017-05-23 09:32:49 +0100
committerDimitris Papastamos <dimitris.papastamos@arm.com>2017-06-22 10:33:19 +0100
commitd832aee900a92d14a08a6a2a552894188404b6a4 (patch)
treef1e12914f0bc1f687509f1b7fbbaf172a335acfd /plat/arm
parent18f2efd67d881fe0a9a535ce9e801e60d746e024 (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.c8
-rw-r--r--plat/arm/common/aarch64/arm_helpers.S29
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