aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Kay <chris.kay@arm.com>2021-05-25 12:33:18 +0100
committerChris Kay <chris.kay@arm.com>2021-10-26 12:14:32 +0100
commit81e2ff1f364fdf18e086f690eb3715bc89307592 (patch)
treeac803b34b22dc884050862404e467b6014079b3d
parent1fd685a74dd33c9c26a0ec0e82e7a5a378461362 (diff)
downloadarm-trusted-firmware-81e2ff1f364fdf18e086f690eb3715bc89307592.tar.gz
refactor(amu): detect architected counters at runtime
This change removes the `AMU_GROUP0_COUNTERS_MASK` and `AMU_GROUP0_MAX_COUNTERS` preprocessor definitions, instead retrieving the number of group 0 counters dynamically through `AMCGCR_EL0.CG0NC`. Change-Id: I70e39c30fbd5df89b214276fac79cc8758a89f72 Signed-off-by: Chris Kay <chris.kay@arm.com>
-rw-r--r--include/arch/aarch32/arch.h2
-rw-r--r--include/arch/aarch64/arch.h2
-rw-r--r--include/lib/extensions/amu_private.h8
-rw-r--r--lib/extensions/amu/aarch32/amu.c23
-rw-r--r--lib/extensions/amu/aarch64/amu.c27
5 files changed, 39 insertions, 23 deletions
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index 59680b7c6..a1bd94291 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.h
@@ -755,6 +755,8 @@
#define AMCFGR_N_MASK U(0xff)
/* AMCGCR definitions */
+#define AMCGCR_CG0NC_SHIFT U(0)
+#define AMCGCR_CG0NC_MASK U(0xff)
#define AMCGCR_CG1NC_SHIFT U(8)
#define AMCGCR_CG1NC_MASK U(0xff)
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index a72087e8f..8b362f1cc 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -1069,6 +1069,8 @@
#define AMCFGR_EL0_N_MASK U(0xff)
/* AMCGCR_EL0 definitions */
+#define AMCGCR_EL0_CG0NC_SHIFT U(0)
+#define AMCGCR_EL0_CG0NC_MASK U(0xff)
#define AMCGCR_EL0_CG1NC_SHIFT U(8)
#define AMCGCR_EL0_CG1NC_MASK U(0xff)
diff --git a/include/lib/extensions/amu_private.h b/include/lib/extensions/amu_private.h
index db44e6471..9b4c29c87 100644
--- a/include/lib/extensions/amu_private.h
+++ b/include/lib/extensions/amu_private.h
@@ -15,9 +15,7 @@
#include <platform_def.h>
-/* All group 0 counters */
-#define AMU_GROUP0_COUNTERS_MASK U(0xf)
-#define AMU_GROUP0_NR_COUNTERS U(4)
+#define AMU_GROUP0_MAX_COUNTERS U(16)
#if ENABLE_AMU_AUXILIARY_COUNTERS
#define AMU_GROUP1_COUNTERS_MASK U(0)
@@ -63,10 +61,10 @@ CASSERT(AMU_GROUP1_COUNTERS_MASK <= 0xffff, invalid_amu_group1_counters_mask);
#endif
struct amu_ctx {
- uint64_t group0_cnts[AMU_GROUP0_NR_COUNTERS];
+ uint64_t group0_cnts[AMU_GROUP0_MAX_COUNTERS];
#if __aarch64__
/* Architected event counter 1 does not have an offset register. */
- uint64_t group0_voffsets[AMU_GROUP0_NR_COUNTERS-1];
+ uint64_t group0_voffsets[AMU_GROUP0_MAX_COUNTERS-1];
#endif
#if ENABLE_AMU_AUXILIARY_COUNTERS
diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c
index d192a897d..47330863e 100644
--- a/lib/extensions/amu/aarch32/amu.c
+++ b/lib/extensions/amu/aarch32/amu.c
@@ -43,6 +43,12 @@ static inline __unused uint32_t read_amcfgr_ncg(void)
AMCFGR_NCG_MASK;
}
+static inline __unused uint32_t read_amcgcr_cg0nc(void)
+{
+ return (read_amcgcr() >> AMCGCR_CG0NC_SHIFT) &
+ AMCGCR_CG0NC_MASK;
+}
+
static inline __unused uint32_t read_amcgcr_cg1nc(void)
{
return (read_amcgcr() >> AMCGCR_CG1NC_SHIFT) &
@@ -163,7 +169,7 @@ void amu_enable(bool el2_unused)
}
/* Enable group 0 counters */
- write_amcntenset0_px(AMU_GROUP0_COUNTERS_MASK);
+ write_amcntenset0_px((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U);
#if ENABLE_AMU_AUXILIARY_COUNTERS
if (AMU_GROUP1_NR_COUNTERS > 0U) {
@@ -196,7 +202,7 @@ void amu_enable(bool el2_unused)
static uint64_t amu_group0_cnt_read(unsigned int idx)
{
assert(amu_supported());
- assert(idx < AMU_GROUP0_NR_COUNTERS);
+ assert(idx < read_amcgcr_cg0nc());
return amu_group0_cnt_read_internal(idx);
}
@@ -205,7 +211,7 @@ static uint64_t amu_group0_cnt_read(unsigned int idx)
static void amu_group0_cnt_write(unsigned int idx, uint64_t val)
{
assert(amu_supported());
- assert(idx < AMU_GROUP0_NR_COUNTERS);
+ assert(idx < read_amcgcr_cg0nc());
amu_group0_cnt_write_internal(idx, val);
isb();
@@ -252,7 +258,8 @@ static void *amu_context_save(const void *arg)
#endif
/* Assert that group 0/1 counter configuration is what we expect */
- assert(read_amcntenset0_px() == AMU_GROUP0_COUNTERS_MASK);
+ assert(read_amcntenset0_px() ==
+ ((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U));
#if ENABLE_AMU_AUXILIARY_COUNTERS
if (AMU_GROUP1_NR_COUNTERS > 0U) {
@@ -263,7 +270,7 @@ static void *amu_context_save(const void *arg)
* Disable group 0/1 counters to avoid other observers like SCP sampling
* counter values from the future via the memory mapped view.
*/
- write_amcntenclr0_px(AMU_GROUP0_COUNTERS_MASK);
+ write_amcntenclr0_px((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U);
#if ENABLE_AMU_AUXILIARY_COUNTERS
if (AMU_GROUP1_NR_COUNTERS > 0U) {
@@ -274,7 +281,7 @@ static void *amu_context_save(const void *arg)
isb();
/* Save all group 0 counters */
- for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) {
+ for (i = 0U; i < read_amcgcr_cg0nc(); i++) {
ctx->group0_cnts[i] = amu_group0_cnt_read(i);
}
@@ -319,12 +326,12 @@ static void *amu_context_restore(const void *arg)
#endif
/* Restore all group 0 counters */
- for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) {
+ for (i = 0U; i < read_amcgcr_cg0nc(); i++) {
amu_group0_cnt_write(i, ctx->group0_cnts[i]);
}
/* Restore group 0 counter configuration */
- write_amcntenset0_px(AMU_GROUP0_COUNTERS_MASK);
+ write_amcntenset0_px((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U);
#if ENABLE_AMU_AUXILIARY_COUNTERS
if (AMU_GROUP1_NR_COUNTERS > 0U) {
diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c
index b2a90ee8c..129616ea9 100644
--- a/lib/extensions/amu/aarch64/amu.c
+++ b/lib/extensions/amu/aarch64/amu.c
@@ -66,6 +66,12 @@ static inline __unused uint64_t read_amcfgr_el0_ncg(void)
AMCFGR_EL0_NCG_MASK;
}
+static inline uint64_t read_amcgcr_el0_cg0nc(void)
+{
+ return (read_amcgcr_el0() >> AMCGCR_EL0_CG0NC_SHIFT) &
+ AMCGCR_EL0_CG0NC_MASK;
+}
+
static inline __unused uint64_t read_amcg1idr_el0_voff(void)
{
return (read_amcg1idr_el0() >> AMCG1IDR_VOFF_SHIFT) &
@@ -197,7 +203,7 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx)
write_cptr_el3_tam(ctx, 0U);
/* Enable group 0 counters */
- write_amcntenset0_el0_px(AMU_GROUP0_COUNTERS_MASK);
+ write_amcntenset0_el0_px((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U);
#if ENABLE_AMU_AUXILIARY_COUNTERS
if (AMU_GROUP1_NR_COUNTERS > 0U) {
@@ -235,7 +241,7 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx)
static uint64_t amu_group0_cnt_read(unsigned int idx)
{
assert(amu_supported());
- assert(idx < AMU_GROUP0_NR_COUNTERS);
+ assert(idx < read_amcgcr_el0_cg0nc());
return amu_group0_cnt_read_internal(idx);
}
@@ -244,7 +250,7 @@ static uint64_t amu_group0_cnt_read(unsigned int idx)
static void amu_group0_cnt_write(unsigned int idx, uint64_t val)
{
assert(amu_supported());
- assert(idx < AMU_GROUP0_NR_COUNTERS);
+ assert(idx < read_amcgcr_el0_cg0nc());
amu_group0_cnt_write_internal(idx, val);
isb();
@@ -259,7 +265,7 @@ static void amu_group0_cnt_write(unsigned int idx, uint64_t val)
static uint64_t amu_group0_voffset_read(unsigned int idx)
{
assert(amu_v1p1_supported());
- assert(idx < AMU_GROUP0_NR_COUNTERS);
+ assert(idx < read_amcgcr_el0_cg0nc());
assert(idx != 1U);
return amu_group0_voffset_read_internal(idx);
@@ -274,7 +280,7 @@ static uint64_t amu_group0_voffset_read(unsigned int idx)
static void amu_group0_voffset_write(unsigned int idx, uint64_t val)
{
assert(amu_v1p1_supported());
- assert(idx < AMU_GROUP0_NR_COUNTERS);
+ assert(idx < read_amcgcr_el0_cg0nc());
assert(idx != 1U);
amu_group0_voffset_write_internal(idx, val);
@@ -353,7 +359,8 @@ static void *amu_context_save(const void *arg)
#endif
/* Assert that group 0/1 counter configuration is what we expect */
- assert(read_amcntenset0_el0_px() == AMU_GROUP0_COUNTERS_MASK);
+ assert(read_amcntenset0_el0_px() ==
+ ((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U));
#if ENABLE_AMU_AUXILIARY_COUNTERS
if (AMU_GROUP1_NR_COUNTERS > 0U) {
@@ -365,7 +372,7 @@ static void *amu_context_save(const void *arg)
* Disable group 0/1 counters to avoid other observers like SCP sampling
* counter values from the future via the memory mapped view.
*/
- write_amcntenclr0_el0_px(AMU_GROUP0_COUNTERS_MASK);
+ write_amcntenclr0_el0_px((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U);
#if ENABLE_AMU_AUXILIARY_COUNTERS
if (AMU_GROUP1_NR_COUNTERS > 0U) {
@@ -376,7 +383,7 @@ static void *amu_context_save(const void *arg)
isb();
/* Save all group 0 counters */
- for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) {
+ for (i = 0U; i < read_amcgcr_el0_cg0nc(); i++) {
ctx->group0_cnts[i] = amu_group0_cnt_read(i);
}
@@ -442,7 +449,7 @@ static void *amu_context_restore(const void *arg)
#endif
/* Restore all group 0 counters */
- for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) {
+ for (i = 0U; i < read_amcgcr_el0_cg0nc(); i++) {
amu_group0_cnt_write(i, ctx->group0_cnts[i]);
}
@@ -455,7 +462,7 @@ static void *amu_context_restore(const void *arg)
}
/* Restore group 0 counter configuration */
- write_amcntenset0_el0_px(AMU_GROUP0_COUNTERS_MASK);
+ write_amcntenset0_el0_px((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U);
#if ENABLE_AMU_AUXILIARY_COUNTERS
if (AMU_GROUP1_NR_COUNTERS > 0U) {