Refactor AMU support for Cortex A75
authorDimitris Papastamos <dimitris.papastamos@arm.com>
Wed, 14 Feb 2018 10:28:36 +0000 (10:28 +0000)
committerDimitris Papastamos <dimitris.papastamos@arm.com>
Tue, 27 Feb 2018 13:28:41 +0000 (13:28 +0000)
This patch also fixes the assumption that the counters are disabled on
the resume path.  This is incorrect as the AMU counters are enabled
early in the CPU reset function before `cpuamu_context_restore()`
runs.

Change-Id: I38a94eb166a523f00de18e86860434ffccff2131
Signed-off-by: Dimitris Papastamos <dimitris.papastamos@arm.com>
include/lib/cpus/aarch64/cortex_a75.h
include/lib/cpus/aarch64/cpuamu.h
lib/cpus/aarch64/cortex_a75.S
lib/cpus/aarch64/cortex_a75_pubsub.c
lib/cpus/aarch64/cpuamu.c [new file with mode: 0644]
plat/arm/board/fvp/platform.mk

index 940125dafd1aa1e10e065ea7e35cdffcb646ca37..a54e0852ae515ebe9f660f3bdd33dde0023783f6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /* Definitions of register field mask in CORTEX_A75_CPUPWRCTLR_EL1 */
 #define CORTEX_A75_CORE_PWRDN_EN_MASK  0x1
 
-/*******************************************************************************
- * CPU Activity Monitor Unit register specific definitions.
- ******************************************************************************/
-#define CPUAMCNTENCLR_EL0      S3_3_C15_C9_7
-#define CPUAMCNTENSET_EL0      S3_3_C15_C9_6
-#define CPUAMCFGR_EL0          S3_3_C15_C10_6
-#define CPUAMUSERENR_EL0       S3_3_C15_C10_7
-
-/* Activity Monitor Event Counter Registers */
-#define CPUAMEVCNTR0_EL0       S3_3_C15_C9_0
-#define CPUAMEVCNTR1_EL0       S3_3_C15_C9_1
-#define CPUAMEVCNTR2_EL0       S3_3_C15_C9_2
-#define CPUAMEVCNTR3_EL0       S3_3_C15_C9_3
-#define CPUAMEVCNTR4_EL0       S3_3_C15_C9_4
-
-/* Activity Monitor Event Type Registers */
-#define CPUAMEVTYPER0_EL0      S3_3_C15_C10_0
-#define CPUAMEVTYPER1_EL0      S3_3_C15_C10_1
-#define CPUAMEVTYPER2_EL0      S3_3_C15_C10_2
-#define CPUAMEVTYPER3_EL0      S3_3_C15_C10_3
-#define CPUAMEVTYPER4_EL0      S3_3_C15_C10_4
-
 #define CORTEX_A75_ACTLR_AMEN_BIT      (U(1) << 4)
 
 /*
index 3d52f1480b4deb93384d87fa4f6acc48c9e92dd5..960a524847e04dc5fb5ade0bacb1dfe6f1f5b6f2 100644 (file)
@@ -38,6 +38,11 @@ unsigned int cpuamu_read_cpuamcntenset_el0(void);
 unsigned int cpuamu_read_cpuamcntenclr_el0(void);
 void cpuamu_write_cpuamcntenset_el0(unsigned int mask);
 void cpuamu_write_cpuamcntenclr_el0(unsigned int mask);
+
+int midr_match(unsigned int cpu_midr);
+void cpuamu_context_save(unsigned int nr_counters);
+void cpuamu_context_restore(unsigned int nr_counters);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __CPUAMU_H__ */
index 946f988434a462ee91675d649fbe272154c2e846..12ea304d00bc95b5f55cd923e2eb7f7b3cabe27f 100644 (file)
@@ -6,108 +6,9 @@
 
 #include <arch.h>
 #include <asm_macros.S>
-#include <bl_common.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
 #include <cortex_a75.h>
-
-       .globl  cortex_a75_amu_cnt_read
-       .globl  cortex_a75_amu_cnt_write
-       .globl  cortex_a75_amu_read_cpuamcntenset_el0
-       .globl  cortex_a75_amu_read_cpuamcntenclr_el0
-       .globl  cortex_a75_amu_write_cpuamcntenset_el0
-       .globl  cortex_a75_amu_write_cpuamcntenclr_el0
-
-/*
- * uint64_t cortex_a75_amu_cnt_read(int idx);
- *
- * Given `idx`, read the corresponding AMU counter
- * and return it in `x0`.
- */
-func cortex_a75_amu_cnt_read
-       adr     x1, 1f
-       lsl     x0, x0, #3
-       add     x1, x1, x0
-       br      x1
-
-1:
-       mrs     x0, CPUAMEVCNTR0_EL0
-       ret
-       mrs     x0, CPUAMEVCNTR1_EL0
-       ret
-       mrs     x0, CPUAMEVCNTR2_EL0
-       ret
-       mrs     x0, CPUAMEVCNTR3_EL0
-       ret
-       mrs     x0, CPUAMEVCNTR4_EL0
-       ret
-endfunc cortex_a75_amu_cnt_read
-
-/*
- * void cortex_a75_amu_cnt_write(int idx, uint64_t val);
- *
- * Given `idx`, write `val` to the corresponding AMU counter.
- */
-func cortex_a75_amu_cnt_write
-       adr     x2, 1f
-       lsl     x0, x0, #3
-       add     x2, x2, x0
-       br      x2
-
-1:
-       msr     CPUAMEVCNTR0_EL0, x0
-       ret
-       msr     CPUAMEVCNTR1_EL0, x0
-       ret
-       msr     CPUAMEVCNTR2_EL0, x0
-       ret
-       msr     CPUAMEVCNTR3_EL0, x0
-       ret
-       msr     CPUAMEVCNTR4_EL0, x0
-       ret
-endfunc cortex_a75_amu_cnt_write
-
-/*
- * unsigned int cortex_a75_amu_read_cpuamcntenset_el0(void);
- *
- * Read the `CPUAMCNTENSET_EL0` CPU register and return
- * it in `x0`.
- */
-func cortex_a75_amu_read_cpuamcntenset_el0
-       mrs     x0, CPUAMCNTENSET_EL0
-       ret
-endfunc cortex_a75_amu_read_cpuamcntenset_el0
-
-/*
- * unsigned int cortex_a75_amu_read_cpuamcntenclr_el0(void);
- *
- * Read the `CPUAMCNTENCLR_EL0` CPU register and return
- * it in `x0`.
- */
-func cortex_a75_amu_read_cpuamcntenclr_el0
-       mrs     x0, CPUAMCNTENCLR_EL0
-       ret
-endfunc cortex_a75_amu_read_cpuamcntenclr_el0
-
-/*
- * void cortex_a75_amu_write_cpuamcntenset_el0(unsigned int mask);
- *
- * Write `mask` to the `CPUAMCNTENSET_EL0` CPU register.
- */
-func cortex_a75_amu_write_cpuamcntenset_el0
-       msr     CPUAMCNTENSET_EL0, x0
-       ret
-endfunc cortex_a75_amu_write_cpuamcntenset_el0
-
-/*
- * void cortex_a75_amu_write_cpuamcntenclr_el0(unsigned int mask);
- *
- * Write `mask` to the `CPUAMCNTENCLR_EL0` CPU register.
- */
-func cortex_a75_amu_write_cpuamcntenclr_el0
-       mrs     x0, CPUAMCNTENCLR_EL0
-       ret
-endfunc cortex_a75_amu_write_cpuamcntenclr_el0
+#include <cpuamu.h>
+#include <cpu_macros.S>
 
 func cortex_a75_reset_func
 #if IMAGE_BL31 && WORKAROUND_CVE_2017_5715
index a1ffcb0410026bc0fc0f4056ec37426e1d368c41..87beca273369447b0c9182bfba63cb623d7dc187 100644 (file)
@@ -1,73 +1,24 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <cortex_a75.h>
-#include <platform.h>
+#include <cpuamu.h>
 #include <pubsub_events.h>
 
-struct amu_ctx {
-       uint64_t cnts[CORTEX_A75_AMU_NR_COUNTERS];
-       uint16_t mask;
-};
-
-static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT];
-
 static void *cortex_a75_context_save(const void *arg)
 {
-       struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()];
-       unsigned int midr;
-       unsigned int midr_mask;
-       int i;
-
-       midr = read_midr();
-       midr_mask = (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) |
-               (MIDR_PN_MASK << MIDR_PN_SHIFT);
-       if ((midr & midr_mask) != (CORTEX_A75_MIDR & midr_mask))
-               return 0;
-
-       /* Save counter configuration */
-       ctx->mask = cortex_a75_amu_read_cpuamcntenset_el0();
-
-       /* Ensure counters are disabled */
-       cortex_a75_amu_write_cpuamcntenclr_el0(ctx->mask);
-       isb();
-
-       /* Save counters */
-       for (i = 0; i < CORTEX_A75_AMU_NR_COUNTERS; i++)
-               ctx->cnts[i] = cortex_a75_amu_cnt_read(i);
-
+       if (midr_match(CORTEX_A75_MIDR))
+               cpuamu_context_save(CORTEX_A75_AMU_NR_COUNTERS);
        return 0;
 }
 
 static void *cortex_a75_context_restore(const void *arg)
 {
-       struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()];
-       unsigned int midr;
-       unsigned int midr_mask;
-       int i;
-
-       midr = read_midr();
-       midr_mask = (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) |
-               (MIDR_PN_MASK << MIDR_PN_SHIFT);
-       if ((midr & midr_mask) != (CORTEX_A75_MIDR & midr_mask))
-               return 0;
-
-       ctx = &amu_ctxs[plat_my_core_pos()];
-
-       /* Counters were disabled in `cortex_a75_context_save()` */
-       assert(cortex_a75_amu_read_cpuamcntenset_el0() == 0);
-
-       /* Restore counters */
-       for (i = 0; i < CORTEX_A75_AMU_NR_COUNTERS; i++)
-               cortex_a75_amu_cnt_write(i, ctx->cnts[i]);
-       isb();
-
-       /* Restore counter configuration */
-       cortex_a75_amu_write_cpuamcntenset_el0(ctx->mask);
-
+       if (midr_match(CORTEX_A75_MIDR))
+               cpuamu_context_restore(CORTEX_A75_AMU_NR_COUNTERS);
        return 0;
 }
 
diff --git a/lib/cpus/aarch64/cpuamu.c b/lib/cpus/aarch64/cpuamu.c
new file mode 100644 (file)
index 0000000..38c093a
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cpuamu.h>
+#include <platform.h>
+#include <pubsub_events.h>
+
+#define CPUAMU_NR_COUNTERS     5
+
+struct amu_ctx {
+       uint64_t cnts[CPUAMU_NR_COUNTERS];
+       uint16_t mask;
+};
+
+static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT];
+
+int midr_match(unsigned int cpu_midr)
+{
+       unsigned int midr, midr_mask;
+
+       midr = read_midr();
+       midr_mask = (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) |
+               (MIDR_PN_MASK << MIDR_PN_SHIFT);
+       return ((midr & midr_mask) == (cpu_midr & midr_mask));
+}
+
+void cpuamu_context_save(unsigned int nr_counters)
+{
+       struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()];
+       int i;
+
+       assert(nr_counters <= CPUAMU_NR_COUNTERS);
+
+       /* Save counter configuration */
+       ctx->mask = cpuamu_read_cpuamcntenset_el0();
+
+       /* Disable counters */
+       cpuamu_write_cpuamcntenclr_el0(ctx->mask);
+       isb();
+
+       /* Save counters */
+       for (i = 0; i < nr_counters; i++)
+               ctx->cnts[i] = cpuamu_cnt_read(i);
+}
+
+void cpuamu_context_restore(unsigned int nr_counters)
+{
+       struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()];
+       int i;
+
+       assert(nr_counters <= CPUAMU_NR_COUNTERS);
+
+       /*
+        * Disable counters.  They were enabled early in the
+        * CPU reset function.
+        */
+       cpuamu_write_cpuamcntenclr_el0(ctx->mask);
+       isb();
+
+       /* Restore counters */
+       for (i = 0; i < nr_counters; i++)
+               cpuamu_cnt_write(i, ctx->cnts[i]);
+       isb();
+
+       /* Restore counter configuration */
+       cpuamu_write_cpuamcntenset_el0(ctx->mask);
+}
index 07c4842e5bb3f06880a1bbe1d8f2834203eba7db..34be2feaa1653bcb619e9cee6b7c37446aaa5dc7 100644 (file)
@@ -180,7 +180,8 @@ ENABLE_PLAT_COMPAT  :=      0
 ENABLE_AMU                     :=      1
 
 ifeq (${ENABLE_AMU},1)
-BL31_SOURCES           +=      lib/cpus/aarch64/cortex_a75_pubsub.c                    \
+BL31_SOURCES           +=      lib/cpus/aarch64/cortex_a75_pubsub.c    \
+                               lib/cpus/aarch64/cpuamu.c               \
                                lib/cpus/aarch64/cpuamu_helpers.S
 endif