From 744ad97445ce7aa65adaef376d0b5bafc12a90d3 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Fri, 28 Jan 2022 17:06:20 -0600 Subject: [PATCH] feat(brbe): add BRBE support for NS world This patch enables access to the branch record buffer control registers in non-secure EL2 and EL1 using the new build option ENABLE_BRBE_FOR_NS. It is disabled for all secure world, and cannot be used with ENABLE_RME. This option is disabled by default, however, the FVP platform makefile enables it for FVP builds. Signed-off-by: John Powell Change-Id: I576a49d446a8a73286ea6417c16bd0b8de71fca0 --- Makefile | 16 +++++++++++- bl31/bl31.mk | 4 +++ docs/getting_started/build-options.rst | 5 ++++ include/arch/aarch64/arch.h | 7 ++++++ include/lib/extensions/brbe.h | 12 +++++++++ lib/el3_runtime/aarch64/context_mgmt.c | 5 ++++ lib/extensions/brbe/brbe.c | 35 ++++++++++++++++++++++++++ make_helpers/defaults.mk | 5 ++++ plat/arm/board/fvp/platform.mk | 9 +++++++ 9 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 include/lib/extensions/brbe.h create mode 100644 lib/extensions/brbe/brbe.c diff --git a/Makefile b/Makefile index a6cb0134a..90fb28bf7 100644 --- a/Makefile +++ b/Makefile @@ -135,6 +135,10 @@ ifeq (${ENABLE_RME},1) ifneq (${ENABLE_PIE},0) $(error ENABLE_RME does not support PIE) endif +# RME doesn't support BRBE +ifneq (${ENABLE_BRBE_FOR_NS},0) + $(error ENABLE_RME does not support BRBE.) +endif # RME requires AARCH64 ifneq (${ARCH},aarch64) $(error ENABLE_RME requires AArch64) @@ -777,8 +781,10 @@ ifneq (${DECRYPTION_SUPPORT},none) endif endif -# SME/SVE only supported on AArch64 +# Ensure that no Aarch64-only features are enabled in Aarch32 build ifeq (${ARCH},aarch32) + + # SME/SVE only supported on AArch64 ifeq (${ENABLE_SME_FOR_NS},1) $(error "ENABLE_SME_FOR_NS cannot be used with ARCH=aarch32") endif @@ -786,6 +792,12 @@ ifeq (${ARCH},aarch32) # Warning instead of error due to CI dependency on this $(error "ENABLE_SVE_FOR_NS cannot be used with ARCH=aarch32") endif + + # BRBE is not supported in Aarch32 + ifeq (${ENABLE_BRBE_FOR_NS},1) + $(error "ENABLE_BRBE_FOR_NS cannot be used with ARCH=aarch32") + endif + endif # Ensure ENABLE_RME is not used with SME @@ -1032,6 +1044,7 @@ $(eval $(call assert_booleans,\ COT_DESC_IN_DTB \ USE_SP804_TIMER \ PSA_FWU_SUPPORT \ + ENABLE_BRBE_FOR_NS \ ENABLE_TRBE_FOR_NS \ ENABLE_SYS_REG_TRACE_FOR_NS \ ENABLE_MPMM \ @@ -1172,6 +1185,7 @@ $(eval $(call add_defines,\ NR_OF_FW_BANKS \ NR_OF_IMAGES_IN_FW_BANK \ PSA_FWU_SUPPORT \ + ENABLE_BRBE_FOR_NS \ ENABLE_TRBE_FOR_NS \ ENABLE_SYS_REG_TRACE_FOR_NS \ ENABLE_TRF_FOR_NS \ diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 214cf2f66..3964469eb 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -115,6 +115,10 @@ ifeq (${ENABLE_TRBE_FOR_NS},1) BL31_SOURCES += lib/extensions/trbe/trbe.c endif +ifeq (${ENABLE_BRBE_FOR_NS},1) +BL31_SOURCES += lib/extensions/brbe/brbe.c +endif + ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1) BL31_SOURCES += lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c endif diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 585b2a11a..d2cda4dcc 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -973,6 +973,11 @@ Common build options functions that wait for an arbitrary time length (udelay and mdelay). The default value is 0. +- ``ENABLE_BRBE_FOR_NS``: This flag enables access to the branch record buffer + registers from NS ELs when FEAT_BRBE is implemented. BRBE is an optional + architectural feature for AArch64. The default is 0 and it is automatically + disabled when the target architecture is AArch32. + - ``ENABLE_TRBE_FOR_NS``: This flag is used to enable access of trace buffer control registers from NS ELs, NS-EL2 or NS-EL1(when NS-EL2 is implemented but unused) when FEAT_TRBE is implemented. TRBE is an optional architectural diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index b4608ae41..bbbc77adb 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -234,6 +234,11 @@ #define ID_AA64DFR0_MTPMU_MASK ULL(0xf) #define ID_AA64DFR0_MTPMU_SUPPORTED ULL(1) +/* ID_AA64DFR0_EL1.BRBE definitions */ +#define ID_AA64DFR0_BRBE_SHIFT U(52) +#define ID_AA64DFR0_BRBE_MASK ULL(0xf) +#define ID_AA64DFR0_BRBE_SUPPORTED ULL(1) + /* ID_AA64ISAR0_EL1 definitions */ #define ID_AA64ISAR0_RNDR_SHIFT U(60) #define ID_AA64ISAR0_RNDR_MASK ULL(0xf) @@ -512,6 +517,8 @@ #define MDCR_EnPMSN_BIT (ULL(1) << 36) #define MDCR_MPMX_BIT (ULL(1) << 35) #define MDCR_MCCD_BIT (ULL(1) << 34) +#define MDCR_SBRBE_SHIFT U(32) +#define MDCR_SBRBE_MASK ULL(0x3) #define MDCR_NSTB(x) ((x) << 24) #define MDCR_NSTB_EL1 ULL(0x3) #define MDCR_NSTBE (ULL(1) << 26) diff --git a/include/lib/extensions/brbe.h b/include/lib/extensions/brbe.h new file mode 100644 index 000000000..aac1ace59 --- /dev/null +++ b/include/lib/extensions/brbe.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef BRBE_H +#define BRBE_H + +void brbe_enable(void); + +#endif /* BRBE_H */ diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 47e7d8c31..449f120a5 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -469,6 +470,10 @@ static void manage_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx) trbe_enable(); #endif /* ENABLE_TRBE_FOR_NS */ +#if ENABLE_BRBE_FOR_NS + brbe_enable(); +#endif /* ENABLE_BRBE_FOR_NS */ + #if ENABLE_SYS_REG_TRACE_FOR_NS sys_reg_trace_enable(ctx); #endif /* ENABLE_SYS_REG_TRACE_FOR_NS */ diff --git a/lib/extensions/brbe/brbe.c b/lib/extensions/brbe/brbe.c new file mode 100644 index 000000000..6975b049c --- /dev/null +++ b/lib/extensions/brbe/brbe.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +static bool brbe_supported(void) +{ + uint64_t features; + + features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_BRBE_SHIFT; + return ((features & ID_AA64DFR0_BRBE_MASK) == + ID_AA64DFR0_BRBE_SUPPORTED); +} + +void brbe_enable(void) +{ + uint64_t val; + + if (brbe_supported()) { + /* + * MDCR_EL3.SBRBE = 0b01 + * + * Allows BRBE usage in non-secure world and prohibited in + * secure world. + */ + val = read_mdcr_el3(); + val &= ~(MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT); + val |= (0x1UL << MDCR_SBRBE_SHIFT); + write_mdcr_el3(val); + } +} diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 7f9264007..6e572377b 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -440,6 +440,11 @@ else override ENABLE_TRBE_FOR_NS := 0 endif +# By default, disable access to branch record buffer control registers from NS +# lower ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused +# if FEAT_BRBE is implemented. +ENABLE_BRBE_FOR_NS := 0 + # By default, disable access of trace system registers from NS lower # ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if # system register trace is implemented. diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 19f913e24..d89e91f71 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -389,6 +389,15 @@ endif # enable trace buffer control registers access to NS by default ENABLE_TRBE_FOR_NS := 1 +# enable branch record buffer control registers access in NS by default +# only enable for aarch64 +# do not enable when ENABLE_RME=1 +ifeq (${ARCH}, aarch64) +ifeq (${ENABLE_RME},0) + ENABLE_BRBE_FOR_NS := 1 +endif +endif + # enable trace system registers access to NS by default ENABLE_SYS_REG_TRACE_FOR_NS := 1