From 380559c1c3ac80c0d2581a931c80323d1fefbfd6 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 12 Oct 2017 13:02:29 +0100 Subject: [PATCH] AMU: Implement support for aarch64 The `ENABLE_AMU` build option can be used to enable the architecturally defined AMU counters. At present, there is no support for the auxiliary counter group. Change-Id: I7ea0c0a00327f463199d1b0a481f01dadb09d312 Signed-off-by: Dimitris Papastamos --- bl31/bl31.mk | 4 +++ docs/user-guide.rst | 5 ++-- include/lib/aarch64/arch.h | 29 +++++++++++++++++++ include/lib/aarch64/arch_helpers.h | 5 ++++ include/lib/extensions/amu.h | 15 ++++++++++ lib/el3_runtime/aarch64/context_mgmt.c | 5 ++++ lib/extensions/amu/aarch64/amu.c | 40 ++++++++++++++++++++++++++ 7 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 include/lib/extensions/amu.h create mode 100644 lib/extensions/amu/aarch64/amu.c diff --git a/bl31/bl31.mk b/bl31/bl31.mk index fccdc8a0a..ebd0e71a9 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -50,6 +50,10 @@ ifeq (${ENABLE_SPE_FOR_LOWER_ELS},1) BL31_SOURCES += lib/extensions/spe/spe.c endif +ifeq (${ENABLE_AMU},1) +BL31_SOURCES += lib/extensions/amu/aarch64/amu.c +endif + BL31_LINKERFILE := bl31/bl31.ld.S # Flag used to indicate if Crash reporting via console should be included diff --git a/docs/user-guide.rst b/docs/user-guide.rst index 1b90f299b..79d660d02 100644 --- a/docs/user-guide.rst +++ b/docs/user-guide.rst @@ -322,8 +322,9 @@ Common build options details. - ``ENABLE_AMU``: Boolean option to enable Activity Monitor Unit extensions. - Currently this option only applies for platforms that include a v8.2 processor - with AMU implemented. Default is 0. + This is an optional architectural feature available on v8.4 onwards. Some + v8.2 implementations also implement an AMU and this option can be used to + enable this feature on those systems as well. Default is 0. - ``ENABLE_ASSERTIONS``: This option controls whether or not calls to ``assert()`` are compiled out. For debug builds, this option defaults to 1, and calls to diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h index 4b31f1689..65e9fc1be 100644 --- a/include/lib/aarch64/arch.h +++ b/include/lib/aarch64/arch.h @@ -110,6 +110,9 @@ #define ID_AA64PFR0_EL1_SHIFT U(4) #define ID_AA64PFR0_EL2_SHIFT U(8) #define ID_AA64PFR0_EL3_SHIFT U(12) +#define ID_AA64PFR0_AMU_SHIFT U(44) +#define ID_AA64PFR0_AMU_LENGTH U(4) +#define ID_AA64PFR0_AMU_MASK U(0xf) #define ID_AA64PFR0_ELX_MASK U(0xf) /* ID_AA64DFR0_EL1.PMS definitions (for ARMv8.2+) */ @@ -295,6 +298,7 @@ /* CPTR_EL3 definitions */ #define TCPAC_BIT (U(1) << 31) +#define TAM_BIT (U(1) << 30) #define TTA_BIT (U(1) << 20) #define TFP_BIT (U(1) << 10) #define CPTR_EL3_RESET_VAL U(0x0) @@ -302,6 +306,7 @@ /* CPTR_EL2 definitions */ #define CPTR_EL2_RES1 ((U(1) << 13) | (U(1) << 12) | (U(0x3ff))) #define CPTR_EL2_TCPAC_BIT (U(1) << 31) +#define CPTR_EL2_TAM_BIT (U(1) << 30) #define CPTR_EL2_TTA_BIT (U(1) << 20) #define CPTR_EL2_TFP_BIT (U(1) << 10) #define CPTR_EL2_RESET_VAL CPTR_EL2_RES1 @@ -610,4 +615,28 @@ ******************************************************************************/ #define PMBLIMITR_EL1 S3_0_C9_C10_0 +/******************************************************************************* + * Definitions for system register interface to AMU for ARMv8.4 onwards + ******************************************************************************/ +#define AMCR_EL0 S3_3_C13_C2_0 +#define AMCFGR_EL0 S3_3_C13_C2_1 +#define AMCGCR_EL0 S3_3_C13_C2_2 +#define AMUSERENR_EL0 S3_3_C13_C2_3 +#define AMCNTENCLR0_EL0 S3_3_C13_C2_4 +#define AMCNTENSET0_EL0 S3_3_C13_C2_5 +#define AMCNTENCLR1_EL0 S3_3_C13_C3_0 +#define AMCNTENSET1_EL0 S3_3_C13_C3_1 + +/* Activity Monitor Group 0 Event Counter Registers */ +#define AMEVCNTR00_EL0 S3_3_C13_C4_0 +#define AMEVCNTR01_EL0 S3_3_C13_C4_1 +#define AMEVCNTR02_EL0 S3_3_C13_C4_2 +#define AMEVCNTR03_EL0 S3_3_C13_C4_3 + +/* Activity Monitor Group 0 Event Type Registers */ +#define AMEVTYPER00_EL0 S3_3_C13_C6_0 +#define AMEVTYPER01_EL0 S3_3_C13_C6_1 +#define AMEVTYPER02_EL0 S3_3_C13_C6_2 +#define AMEVTYPER03_EL0 S3_3_C13_C6_3 + #endif /* __ARCH_H__ */ diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h index 46d9a1c0c..b6be16759 100644 --- a/include/lib/aarch64/arch_helpers.h +++ b/include/lib/aarch64/arch_helpers.h @@ -322,6 +322,11 @@ DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir0_el1, ICC_EOIR0_EL1) DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir1_el1, ICC_EOIR1_EL1) DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_sgi0r_el1, ICC_SGI0R_EL1) +DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr0_el0, AMCNTENCLR0_EL0) +DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset0_el0, AMCNTENSET0_EL0) +DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr1_el0, AMCNTENCLR1_EL0) +DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset1_el0, AMCNTENSET1_EL0) + DEFINE_RENAME_SYSREG_RW_FUNCS(pmblimitr_el1, PMBLIMITR_EL1) #define IS_IN_EL(x) \ diff --git a/include/lib/extensions/amu.h b/include/lib/extensions/amu.h new file mode 100644 index 000000000..bbefe8ff6 --- /dev/null +++ b/include/lib/extensions/amu.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __AMU_H__ +#define __AMU_H__ + +/* Enable all group 0 counters */ +#define AMU_GROUP0_COUNTERS_MASK 0xf + +void amu_enable(int el2_unused); + +#endif /* __AMU_H__ */ diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 8f1523f0d..b892729ef 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include #include @@ -220,6 +221,10 @@ static void enable_extensions_nonsecure(int el2_unused) #if ENABLE_SPE_FOR_LOWER_ELS spe_enable(el2_unused); #endif + +#if ENABLE_AMU + amu_enable(el2_unused); +#endif #endif } diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c new file mode 100644 index 000000000..007b3494f --- /dev/null +++ b/lib/extensions/amu/aarch64/amu.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +void amu_enable(int el2_unused) +{ + uint64_t features; + + features = read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT; + if ((features & ID_AA64PFR0_AMU_MASK) == 1) { + uint64_t v; + + if (el2_unused) { + /* + * CPTR_EL2.TAM: Set to zero so any accesses to + * the Activity Monitor registers do not trap to EL2. + */ + v = read_cptr_el2(); + v &= ~CPTR_EL2_TAM_BIT; + write_cptr_el2(v); + } + + /* + * CPTR_EL3.TAM: Set to zero so that any accesses to + * the Activity Monitor registers do not trap to EL3. + */ + v = read_cptr_el3(); + v &= ~TAM_BIT; + write_cptr_el3(v); + + /* Enable group 0 counters */ + write_amcntenset0_el0(AMU_GROUP0_COUNTERS_MASK); + } +}