feat(trbe): enable access to trace buffer control registers from lower NS EL

Introduced a build flag 'ENABLE_TRBE_FOR_NS' to enable trace buffer
control registers access in NS-EL2, or NS-EL1 (when NS-EL2 is
implemented but unused).

Change-Id: I285a672ccd395eebd377714c992bb21062a729cc
Signed-off-by: Manish V Badarkhe <Manish.Badarkhe@arm.com>
This commit is contained in:
Manish V Badarkhe 2021-07-02 09:10:56 +01:00
parent 40ff907470
commit 813524ea9d
8 changed files with 109 additions and 0 deletions

View File

@ -964,6 +964,7 @@ $(eval $(call assert_booleans,\
ENABLE_FEAT_RNG \
ENABLE_FEAT_SB \
PSA_FWU_SUPPORT \
ENABLE_TRBE_FOR_NS \
)))
$(eval $(call assert_numerics,\
@ -1064,6 +1065,7 @@ $(eval $(call add_defines,\
NR_OF_FW_BANKS \
NR_OF_IMAGES_IN_FW_BANK \
PSA_FWU_SUPPORT \
ENABLE_TRBE_FOR_NS \
)))
ifeq (${SANITIZE_UB},trap)

View File

@ -90,6 +90,10 @@ ifeq (${ENABLE_MPAM_FOR_LOWER_ELS},1)
BL31_SOURCES += lib/extensions/mpam/mpam.c
endif
ifeq (${ENABLE_TRBE_FOR_NS},1)
BL31_SOURCES += lib/extensions/trbe/trbe.c
endif
ifeq (${WORKAROUND_CVE_2017_5715},1)
BL31_SOURCES += lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S \
lib/cpus/aarch64/wa_cve_2017_5715_mmu.S

View File

@ -775,6 +775,12 @@ Common build options
functions that wait for an arbitrary time length (udelay and mdelay). The
default value is 0.
- ``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
feature for AArch64. The default is 0 and it is automatically disabled when
the target architecture is AArch32.
GICv3 driver options
--------------------

View File

@ -192,6 +192,11 @@
#define ID_AA64DFR0_PMS_SHIFT U(32)
#define ID_AA64DFR0_PMS_MASK ULL(0xf)
/* ID_AA64DFR0_EL1.TraceBuffer definitions */
#define ID_AA64DFR0_TRACEBUFFER_SHIFT U(44)
#define ID_AA64DFR0_TRACEBUFFER_MASK ULL(0xf)
#define ID_AA64DFR0_TRACEBUFFER_SUPPORTED ULL(1)
/* ID_AA64DFR0_EL1.MTPMU definitions (for ARMv8.6+) */
#define ID_AA64DFR0_MTPMU_SHIFT U(48)
#define ID_AA64DFR0_MTPMU_MASK ULL(0xf)

View File

@ -0,0 +1,12 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef TRBE_H
#define TRBE_H
void trbe_enable(void);
#endif /* TRBE_H */

View File

@ -22,6 +22,7 @@
#include <lib/extensions/mpam.h>
#include <lib/extensions/spe.h>
#include <lib/extensions/sve.h>
#include <lib/extensions/trbe.h>
#include <lib/extensions/twed.h>
#include <lib/utils.h>
@ -348,6 +349,11 @@ static void enable_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx)
#if ENABLE_MPAM_FOR_LOWER_ELS
mpam_enable(el2_unused);
#endif
#if ENABLE_TRBE_FOR_NS
trbe_enable();
#endif /* ENABLE_TRBE_FOR_NS */
#endif
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
#include <lib/el3_runtime/pubsub.h>
#include <lib/extensions/trbe.h>
static void tsb_csync(void)
{
/*
* The assembler does not yet understand the tsb csync mnemonic
* so use the equivalent hint instruction.
*/
__asm__ volatile("hint #18");
}
static bool trbe_supported(void)
{
uint64_t features;
features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEBUFFER_SHIFT;
return ((features & ID_AA64DFR0_TRACEBUFFER_MASK) ==
ID_AA64DFR0_TRACEBUFFER_SUPPORTED);
}
void trbe_enable(void)
{
uint64_t val;
if (trbe_supported()) {
/*
* MDCR_EL3.NSTB = 0b11
* Allow access of trace buffer control registers from NS-EL1
* and NS-EL2, tracing is prohibited in Secure and Realm state
* (if implemented).
*/
val = read_mdcr_el3();
val |= MDCR_NSTB(MDCR_NSTB_EL1);
write_mdcr_el3(val);
}
}
static void *trbe_drain_trace_buffers_hook(const void *arg __unused)
{
if (trbe_supported()) {
/*
* Before switching from normal world to secure world
* the trace buffers need to be drained out to memory. This is
* required to avoid an invalid memory access when TTBR is switched
* for entry to S-EL1.
*/
tsb_csync();
dsbnsh();
}
return (void *)0;
}
SUBSCRIBE_TO_EVENT(cm_entering_secure_world, trbe_drain_trace_buffers_hook);

View File

@ -355,3 +355,14 @@ NR_OF_IMAGES_IN_FW_BANK := 1
# Disable Firmware update support by default
PSA_FWU_SUPPORT := 0
# By default, disable access of trace buffer control registers from NS
# lower ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
# if FEAT_TRBE is implemented.
# Note FEAT_TRBE is only supported on AArch64 - therefore do not enable in
# AArch32.
ifneq (${ARCH},aarch32)
ENABLE_TRBE_FOR_NS := 0
else
override ENABLE_TRBE_FOR_NS := 0
endif