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 <john.powell@arm.com>
Change-Id: I576a49d446a8a73286ea6417c16bd0b8de71fca0
This commit is contained in:
johpow01 2022-01-28 17:06:20 -06:00 committed by John Powell
parent 8d6502183d
commit 744ad97445
9 changed files with 97 additions and 1 deletions

View File

@ -135,6 +135,10 @@ ifeq (${ENABLE_RME},1)
ifneq (${ENABLE_PIE},0) ifneq (${ENABLE_PIE},0)
$(error ENABLE_RME does not support PIE) $(error ENABLE_RME does not support PIE)
endif endif
# RME doesn't support BRBE
ifneq (${ENABLE_BRBE_FOR_NS},0)
$(error ENABLE_RME does not support BRBE.)
endif
# RME requires AARCH64 # RME requires AARCH64
ifneq (${ARCH},aarch64) ifneq (${ARCH},aarch64)
$(error ENABLE_RME requires AArch64) $(error ENABLE_RME requires AArch64)
@ -777,8 +781,10 @@ ifneq (${DECRYPTION_SUPPORT},none)
endif endif
endif endif
# SME/SVE only supported on AArch64 # Ensure that no Aarch64-only features are enabled in Aarch32 build
ifeq (${ARCH},aarch32) ifeq (${ARCH},aarch32)
# SME/SVE only supported on AArch64
ifeq (${ENABLE_SME_FOR_NS},1) ifeq (${ENABLE_SME_FOR_NS},1)
$(error "ENABLE_SME_FOR_NS cannot be used with ARCH=aarch32") $(error "ENABLE_SME_FOR_NS cannot be used with ARCH=aarch32")
endif endif
@ -786,6 +792,12 @@ ifeq (${ARCH},aarch32)
# Warning instead of error due to CI dependency on this # Warning instead of error due to CI dependency on this
$(error "ENABLE_SVE_FOR_NS cannot be used with ARCH=aarch32") $(error "ENABLE_SVE_FOR_NS cannot be used with ARCH=aarch32")
endif 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 endif
# Ensure ENABLE_RME is not used with SME # Ensure ENABLE_RME is not used with SME
@ -1032,6 +1044,7 @@ $(eval $(call assert_booleans,\
COT_DESC_IN_DTB \ COT_DESC_IN_DTB \
USE_SP804_TIMER \ USE_SP804_TIMER \
PSA_FWU_SUPPORT \ PSA_FWU_SUPPORT \
ENABLE_BRBE_FOR_NS \
ENABLE_TRBE_FOR_NS \ ENABLE_TRBE_FOR_NS \
ENABLE_SYS_REG_TRACE_FOR_NS \ ENABLE_SYS_REG_TRACE_FOR_NS \
ENABLE_MPMM \ ENABLE_MPMM \
@ -1172,6 +1185,7 @@ $(eval $(call add_defines,\
NR_OF_FW_BANKS \ NR_OF_FW_BANKS \
NR_OF_IMAGES_IN_FW_BANK \ NR_OF_IMAGES_IN_FW_BANK \
PSA_FWU_SUPPORT \ PSA_FWU_SUPPORT \
ENABLE_BRBE_FOR_NS \
ENABLE_TRBE_FOR_NS \ ENABLE_TRBE_FOR_NS \
ENABLE_SYS_REG_TRACE_FOR_NS \ ENABLE_SYS_REG_TRACE_FOR_NS \
ENABLE_TRF_FOR_NS \ ENABLE_TRF_FOR_NS \

View File

@ -115,6 +115,10 @@ ifeq (${ENABLE_TRBE_FOR_NS},1)
BL31_SOURCES += lib/extensions/trbe/trbe.c BL31_SOURCES += lib/extensions/trbe/trbe.c
endif endif
ifeq (${ENABLE_BRBE_FOR_NS},1)
BL31_SOURCES += lib/extensions/brbe/brbe.c
endif
ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1) ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1)
BL31_SOURCES += lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c BL31_SOURCES += lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
endif endif

View File

@ -973,6 +973,11 @@ Common build options
functions that wait for an arbitrary time length (udelay and mdelay). The functions that wait for an arbitrary time length (udelay and mdelay). The
default value is 0. 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 - ``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 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 but unused) when FEAT_TRBE is implemented. TRBE is an optional architectural

View File

@ -234,6 +234,11 @@
#define ID_AA64DFR0_MTPMU_MASK ULL(0xf) #define ID_AA64DFR0_MTPMU_MASK ULL(0xf)
#define ID_AA64DFR0_MTPMU_SUPPORTED ULL(1) #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 */ /* ID_AA64ISAR0_EL1 definitions */
#define ID_AA64ISAR0_RNDR_SHIFT U(60) #define ID_AA64ISAR0_RNDR_SHIFT U(60)
#define ID_AA64ISAR0_RNDR_MASK ULL(0xf) #define ID_AA64ISAR0_RNDR_MASK ULL(0xf)
@ -512,6 +517,8 @@
#define MDCR_EnPMSN_BIT (ULL(1) << 36) #define MDCR_EnPMSN_BIT (ULL(1) << 36)
#define MDCR_MPMX_BIT (ULL(1) << 35) #define MDCR_MPMX_BIT (ULL(1) << 35)
#define MDCR_MCCD_BIT (ULL(1) << 34) #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(x) ((x) << 24)
#define MDCR_NSTB_EL1 ULL(0x3) #define MDCR_NSTB_EL1 ULL(0x3)
#define MDCR_NSTBE (ULL(1) << 26) #define MDCR_NSTBE (ULL(1) << 26)

View File

@ -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 */

View File

@ -20,6 +20,7 @@
#include <lib/el3_runtime/context_mgmt.h> #include <lib/el3_runtime/context_mgmt.h>
#include <lib/el3_runtime/pubsub_events.h> #include <lib/el3_runtime/pubsub_events.h>
#include <lib/extensions/amu.h> #include <lib/extensions/amu.h>
#include <lib/extensions/brbe.h>
#include <lib/extensions/mpam.h> #include <lib/extensions/mpam.h>
#include <lib/extensions/sme.h> #include <lib/extensions/sme.h>
#include <lib/extensions/spe.h> #include <lib/extensions/spe.h>
@ -469,6 +470,10 @@ static void manage_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx)
trbe_enable(); trbe_enable();
#endif /* ENABLE_TRBE_FOR_NS */ #endif /* ENABLE_TRBE_FOR_NS */
#if ENABLE_BRBE_FOR_NS
brbe_enable();
#endif /* ENABLE_BRBE_FOR_NS */
#if ENABLE_SYS_REG_TRACE_FOR_NS #if ENABLE_SYS_REG_TRACE_FOR_NS
sys_reg_trace_enable(ctx); sys_reg_trace_enable(ctx);
#endif /* ENABLE_SYS_REG_TRACE_FOR_NS */ #endif /* ENABLE_SYS_REG_TRACE_FOR_NS */

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
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);
}
}

View File

@ -440,6 +440,11 @@ else
override ENABLE_TRBE_FOR_NS := 0 override ENABLE_TRBE_FOR_NS := 0
endif 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 # 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 # ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if
# system register trace is implemented. # system register trace is implemented.

View File

@ -389,6 +389,15 @@ endif
# enable trace buffer control registers access to NS by default # enable trace buffer control registers access to NS by default
ENABLE_TRBE_FOR_NS := 1 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 trace system registers access to NS by default
ENABLE_SYS_REG_TRACE_FOR_NS := 1 ENABLE_SYS_REG_TRACE_FOR_NS := 1