aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManish Pandey <manish.pandey2@arm.com>2021-09-17 11:36:43 +0200
committerTrustedFirmware Code Review <review@review.trustedfirmware.org>2021-09-17 11:36:43 +0200
commitb3210f4ddb0e1db374632a51059c806f14514dde (patch)
tree055b948ea90542d2a228eba965f7086c8b46bdd9
parentd272611770ad11177b8c18f2a1502cd1309e2189 (diff)
parentcd3f0ae6f855b2998bc09e5c3a458528c92acb90 (diff)
downloadtrusted-firmware-a-b3210f4ddb0e1db374632a51059c806f14514dde.tar.gz
Merge changes from topic "TrcDbgExt" into integration
* changes: feat(plat/fvp): enable trace extension features by default feat(trf): enable trace filter control register access from lower NS EL feat(trf): initialize trap settings of trace filter control registers access feat(sys_reg_trace): enable trace system registers access from lower NS ELs feat(sys_reg_trace): initialize trap settings of trace system registers access feat(trbe): enable access to trace buffer control registers from lower NS EL feat(trbe): initialize trap settings of trace buffer control registers access
-rw-r--r--Makefile6
-rw-r--r--bl31/bl31.mk12
-rw-r--r--bl32/sp_min/sp_min.mk8
-rw-r--r--docs/getting_started/build-options.rst15
-rw-r--r--include/arch/aarch32/arch.h12
-rw-r--r--include/arch/aarch32/arch_helpers.h2
-rw-r--r--include/arch/aarch32/el3_common_macros.S27
-rw-r--r--include/arch/aarch64/arch.h20
-rw-r--r--include/arch/aarch64/el3_common_macros.S31
-rw-r--r--include/lib/extensions/sys_reg_trace.h18
-rw-r--r--include/lib/extensions/trbe.h12
-rw-r--r--include/lib/extensions/trf.h12
-rw-r--r--lib/el3_runtime/aarch32/context_mgmt.c10
-rw-r--r--lib/el3_runtime/aarch64/context_mgmt.c26
-rw-r--r--lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c36
-rw-r--r--lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c37
-rw-r--r--lib/extensions/trbe/trbe.c63
-rw-r--r--lib/extensions/trf/aarch32/trf.c35
-rw-r--r--lib/extensions/trf/aarch64/trf.c36
-rw-r--r--make_helpers/defaults.mk21
-rw-r--r--plat/arm/board/fvp/platform.mk9
21 files changed, 445 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 8411355541..9d1e945662 100644
--- a/Makefile
+++ b/Makefile
@@ -968,6 +968,9 @@ $(eval $(call assert_booleans,\
ENABLE_FEAT_RNG \
ENABLE_FEAT_SB \
PSA_FWU_SUPPORT \
+ ENABLE_TRBE_FOR_NS \
+ ENABLE_SYS_REG_TRACE_FOR_NS \
+ ENABLE_TRF_FOR_NS \
)))
$(eval $(call assert_numerics,\
@@ -1068,6 +1071,9 @@ $(eval $(call add_defines,\
NR_OF_FW_BANKS \
NR_OF_IMAGES_IN_FW_BANK \
PSA_FWU_SUPPORT \
+ ENABLE_TRBE_FOR_NS \
+ ENABLE_SYS_REG_TRACE_FOR_NS \
+ ENABLE_TRF_FOR_NS \
)))
ifeq (${SANITIZE_UB},trap)
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 1fdf545da6..7819141ef5 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -90,6 +90,18 @@ 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 (${ENABLE_SYS_REG_TRACE_FOR_NS},1)
+BL31_SOURCES += lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
+endif
+
+ifeq (${ENABLE_TRF_FOR_NS},1)
+BL31_SOURCES += lib/extensions/trf/aarch64/trf.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
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index 8b5eddd664..6339cf856a 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -42,6 +42,14 @@ BL32_SOURCES += services/std_svc/trng/trng_main.c \
services/std_svc/trng/trng_entropy_pool.c
endif
+ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1)
+BL32_SOURCES += lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c
+endif
+
+ifeq (${ENABLE_TRF_FOR_NS},1)
+BL32_SOURCES += lib/extensions/trf/aarch32/trf.c
+endif
+
BL32_LINKERFILE := bl32/sp_min/sp_min.ld.S
# Include the platform-specific SP_MIN Makefile
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index bac8847077..115b2b2289 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -775,6 +775,21 @@ 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.
+
+- ``ENABLE_SYS_REG_TRACE_FOR_NS``: Boolean option to enable trace system
+ registers access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented
+ but unused). This feature is available if trace unit such as ETMv4.x, and
+ ETE(extending ETM feature) is implemented. This flag is disabled by default.
+
+- ``ENABLE_TRF_FOR_NS``: Boolean option to enable trace filter control registers
+ access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented but unused),
+ if FEAT_TRF is implemented. This flag is disabled by default.
+
GICv3 driver options
--------------------
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index 54ec009534..7221b62732 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.h
@@ -102,6 +102,16 @@
/* CSSELR definitions */
#define LEVEL_SHIFT U(1)
+/* ID_DFR0_EL1 definitions */
+#define ID_DFR0_COPTRC_SHIFT U(12)
+#define ID_DFR0_COPTRC_MASK U(0xf)
+#define ID_DFR0_COPTRC_SUPPORTED U(1)
+#define ID_DFR0_COPTRC_LENGTH U(4)
+#define ID_DFR0_TRACEFILT_SHIFT U(28)
+#define ID_DFR0_TRACEFILT_MASK U(0xf)
+#define ID_DFR0_TRACEFILT_SUPPORTED U(1)
+#define ID_DFR0_TRACEFILT_LENGTH U(4)
+
/* ID_DFR1_EL1 definitions */
#define ID_DFR1_MTPMU_SHIFT U(0)
#define ID_DFR1_MTPMU_MASK U(0xf)
@@ -173,6 +183,7 @@
#define SDCR_SPD_DISABLE U(0x2)
#define SDCR_SPD_ENABLE U(0x3)
#define SDCR_SCCD_BIT (U(1) << 23)
+#define SDCR_TTRF_BIT (U(1) << 19)
#define SDCR_SPME_BIT (U(1) << 17)
#define SDCR_RESET_VAL U(0x0)
#define SDCR_MTPME_BIT (U(1) << 28)
@@ -516,6 +527,7 @@
#define CTR p15, 0, c0, c0, 1
#define CNTFRQ p15, 0, c14, c0, 0
#define ID_MMFR4 p15, 0, c0, c2, 6
+#define ID_DFR0 p15, 0, c0, c1, 2
#define ID_DFR1 p15, 0, c0, c3, 5
#define ID_PFR0 p15, 0, c0, c1, 0
#define ID_PFR1 p15, 0, c0, c1, 1
diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h
index 726baf596e..0330989153 100644
--- a/include/arch/aarch32/arch_helpers.h
+++ b/include/arch/aarch32/arch_helpers.h
@@ -217,6 +217,7 @@ DEFINE_SYSREG_RW_FUNCS(cpsr)
DEFINE_COPROCR_READ_FUNC(mpidr, MPIDR)
DEFINE_COPROCR_READ_FUNC(midr, MIDR)
DEFINE_COPROCR_READ_FUNC(id_mmfr4, ID_MMFR4)
+DEFINE_COPROCR_READ_FUNC(id_dfr0, ID_DFR0)
DEFINE_COPROCR_READ_FUNC(id_pfr0, ID_PFR0)
DEFINE_COPROCR_READ_FUNC(id_pfr1, ID_PFR1)
DEFINE_COPROCR_READ_FUNC(isr, ISR)
@@ -282,6 +283,7 @@ DEFINE_COPROCR_RW_FUNCS(icc_eoir1_el1, ICC_EOIR1)
DEFINE_COPROCR_RW_FUNCS_64(icc_sgi0r_el1, ICC_SGI0R_EL1_64)
DEFINE_COPROCR_WRITE_FUNC_64(icc_sgi1r, ICC_SGI1R_EL1_64)
+DEFINE_COPROCR_RW_FUNCS(sdcr, SDCR)
DEFINE_COPROCR_RW_FUNCS(hdcr, HDCR)
DEFINE_COPROCR_RW_FUNCS(cnthp_ctl, CNTHP_CTL)
DEFINE_COPROCR_READ_FUNC(pmcr, PMCR)
diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S
index 7fff4c754e..65f9a8e6be 100644
--- a/include/arch/aarch32/el3_common_macros.S
+++ b/include/arch/aarch32/el3_common_macros.S
@@ -63,11 +63,23 @@
* cp11 field is ignored, but is set to same value as cp10. The cp10
* field is set to allow access to Advanced SIMD and floating point
* features from both Security states.
+ *
+ * NSACR.NSTRCDIS: When system register trace implemented, Set to one
+ * so that NS System register accesses to all implemented trace
+ * registers are disabled.
+ * When system register trace is not implemented, this bit is RES0 and
+ * hence set to zero.
* ---------------------------------------------------------------------
*/
ldcopr r0, NSACR
and r0, r0, #NSACR_IMP_DEF_MASK
orr r0, r0, #(NSACR_RESET_VAL | NSACR_ENABLE_FP_ACCESS)
+ ldcopr r1, ID_DFR0
+ ubfx r1, r1, #ID_DFR0_COPTRC_SHIFT, #ID_DFR0_COPTRC_LENGTH
+ cmp r1, #ID_DFR0_COPTRC_SUPPORTED
+ bne 1f
+ orr r0, r0, #NSTRCDIS_BIT
+1:
stcopr r0, NSACR
isb
@@ -119,9 +131,22 @@
* in Secure state. This bit is RES0 in versions of the architecture
* earlier than ARMv8.5, setting it to 1 doesn't have any effect on
* them.
+ *
+ * SDCR.TTRF: Set to one so that access to trace filter control
+ * registers in non-monitor mode generate Monitor trap exception,
+ * unless the access generates a higher priority exception when
+ * trace filter control(FEAT_TRF) is implemented.
+ * When FEAT_TRF is not implemented, this bit is RES0.
* ---------------------------------------------------------------------
*/
- ldr r0, =(SDCR_RESET_VAL | SDCR_SPD(SDCR_SPD_DISABLE) | SDCR_SCCD_BIT)
+ ldr r0, =((SDCR_RESET_VAL | SDCR_SPD(SDCR_SPD_DISABLE) | \
+ SDCR_SCCD_BIT) & ~SDCR_TTRF_BIT)
+ ldcopr r1, ID_DFR0
+ ubfx r1, r1, #ID_DFR0_TRACEFILT_SHIFT, #ID_DFR0_TRACEFILT_LENGTH
+ cmp r1, #ID_DFR0_TRACEFILT_SUPPORTED
+ bne 1f
+ orr r0, r0, #SDCR_TTRF_BIT
+1:
stcopr r0, SDCR
/* ---------------------------------------------------------------------
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index c12dbc4b4d..9ea111452a 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -188,10 +188,25 @@
#define EL_IMPL_A64ONLY ULL(1)
#define EL_IMPL_A64_A32 ULL(2)
+/* ID_AA64DFR0_EL1.TraceVer definitions */
+#define ID_AA64DFR0_TRACEVER_SHIFT U(4)
+#define ID_AA64DFR0_TRACEVER_MASK ULL(0xf)
+#define ID_AA64DFR0_TRACEVER_SUPPORTED ULL(1)
+#define ID_AA64DFR0_TRACEVER_LENGTH U(4)
+#define ID_AA64DFR0_TRACEFILT_SHIFT U(40)
+#define ID_AA64DFR0_TRACEFILT_MASK U(0xf)
+#define ID_AA64DFR0_TRACEFILT_SUPPORTED U(1)
+#define ID_AA64DFR0_TRACEFILT_LENGTH U(4)
+
/* ID_AA64DFR0_EL1.PMS definitions (for ARMv8.2+) */
#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)
@@ -442,6 +457,9 @@
#define MDCR_EnPMSN_BIT (ULL(1) << 36)
#define MDCR_MPMX_BIT (ULL(1) << 35)
#define MDCR_MCCD_BIT (ULL(1) << 34)
+#define MDCR_NSTB(x) ((x) << 24)
+#define MDCR_NSTB_EL1 ULL(0x3)
+#define MDCR_NSTBE (ULL(1) << 26)
#define MDCR_MTPME_BIT (ULL(1) << 28)
#define MDCR_TDCC_BIT (ULL(1) << 27)
#define MDCR_SCCD_BIT (ULL(1) << 23)
@@ -465,6 +483,8 @@
/* MDCR_EL2 definitions */
#define MDCR_EL2_MTPME (U(1) << 28)
#define MDCR_EL2_HLP (U(1) << 26)
+#define MDCR_EL2_E2TB(x) ((x) << 24)
+#define MDCR_EL2_E2TB_EL1 U(0x3)
#define MDCR_EL2_HCCD (U(1) << 23)
#define MDCR_EL2_TTRF (U(1) << 19)
#define MDCR_EL2_HPMD (U(1) << 17)
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 9734335755..d4965841f8 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -126,13 +126,31 @@
* Debug is not implemented this bit does not have any effect on the
* counters unless there is support for the implementation defined
* authentication interface ExternalSecureNoninvasiveDebugEnabled().
+ *
+ * MDCR_EL3.NSTB, MDCR_EL3.NSTBE: Set to zero so that Trace Buffer
+ * owning security state is Secure state. If FEAT_TRBE is implemented,
+ * accesses to Trace Buffer control registers at EL2 and EL1 in any
+ * security state generates trap exceptions to EL3.
+ * If FEAT_TRBE is not implemented, these bits are RES0.
+ *
+ * MDCR_EL3.TTRF: Set to one so that access to trace filter control
+ * registers in non-monitor mode generate EL3 trap exception,
+ * unless the access generates a higher priority exception when trace
+ * filter control(FEAT_TRF) is implemented.
+ * When FEAT_TRF is not implemented, this bit is RES0.
* ---------------------------------------------------------------------
*/
mov_imm x0, ((MDCR_EL3_RESET_VAL | MDCR_SDD_BIT | \
MDCR_SPD32(MDCR_SPD32_DISABLE) | MDCR_SCCD_BIT | \
MDCR_MCCD_BIT) & ~(MDCR_SPME_BIT | MDCR_TDOSA_BIT | \
- MDCR_TDA_BIT | MDCR_TPM_BIT))
+ MDCR_TDA_BIT | MDCR_TPM_BIT | MDCR_NSTB(MDCR_NSTB_EL1) | \
+ MDCR_NSTBE | MDCR_TTRF_BIT))
+ mrs x1, id_aa64dfr0_el1
+ ubfx x1, x1, #ID_AA64DFR0_TRACEFILT_SHIFT, #ID_AA64DFR0_TRACEFILT_LENGTH
+ cbz x1, 1f
+ orr x0, x0, #MDCR_TTRF_BIT
+1:
msr mdcr_el3, x0
/* ---------------------------------------------------------------------
@@ -179,6 +197,12 @@
* CPTR_EL3.TCPAC: Set to zero so that any accesses to CPACR_EL1,
* CPTR_EL2, CPACR, or HCPTR do not trap to EL3.
*
+ * CPTR_EL3.TTA: Set to one so that accesses to the trace system
+ * registers trap to EL3 from all exception levels and security
+ * states when system register trace is implemented.
+ * When system register trace is not implemented, this bit is RES0 and
+ * hence set to zero.
+ *
* CPTR_EL3.TTA: Set to zero so that System register accesses to the
* trace registers do not trap to EL3.
*
@@ -194,6 +218,11 @@
*/
mov_imm x0, (CPTR_EL3_RESET_VAL & ~(TCPAC_BIT | TTA_BIT | TFP_BIT))
+ mrs x1, id_aa64dfr0_el1
+ ubfx x1, x1, #ID_AA64DFR0_TRACEVER_SHIFT, #ID_AA64DFR0_TRACEVER_LENGTH
+ cbz x1, 1f
+ orr x0, x0, #TTA_BIT
+1:
msr cptr_el3, x0
/*
diff --git a/include/lib/extensions/sys_reg_trace.h b/include/lib/extensions/sys_reg_trace.h
new file mode 100644
index 0000000000..74470fee22
--- /dev/null
+++ b/include/lib/extensions/sys_reg_trace.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SYS_REG_TRACE_H
+#define SYS_REG_TRACE_H
+
+#include <context.h>
+
+#if __aarch64__
+void sys_reg_trace_enable(cpu_context_t *context);
+#else
+void sys_reg_trace_enable(void);
+#endif /* __aarch64__ */
+
+#endif /* SYS_REG_TRACE_H */
diff --git a/include/lib/extensions/trbe.h b/include/lib/extensions/trbe.h
new file mode 100644
index 0000000000..1753ab6bf0
--- /dev/null
+++ b/include/lib/extensions/trbe.h
@@ -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 */
diff --git a/include/lib/extensions/trf.h b/include/lib/extensions/trf.h
new file mode 100644
index 0000000000..18f17f36df
--- /dev/null
+++ b/include/lib/extensions/trf.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TRF_H
+#define TRF_H
+
+void trf_enable(void);
+
+#endif /* TRF_H */
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index 81d793b46b..3ef378ce10 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -16,6 +16,8 @@
#include <context.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/extensions/amu.h>
+#include <lib/extensions/sys_reg_trace.h>
+#include <lib/extensions/trf.h>
#include <lib/utils.h>
/*******************************************************************************
@@ -136,6 +138,14 @@ static void enable_extensions_nonsecure(bool el2_unused)
#if ENABLE_AMU
amu_enable(el2_unused);
#endif
+
+#if ENABLE_SYS_REG_TRACE_FOR_NS
+ sys_reg_trace_enable();
+#endif /* ENABLE_SYS_REG_TRACE_FOR_NS */
+
+#if ENABLE_TRF_FOR_NS
+ trf_enable();
+#endif /* ENABLE_TRF_FOR_NS */
#endif
}
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 7c6f953b26..52102ddd45 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -22,6 +22,9 @@
#include <lib/extensions/mpam.h>
#include <lib/extensions/spe.h>
#include <lib/extensions/sve.h>
+#include <lib/extensions/sys_reg_trace.h>
+#include <lib/extensions/trbe.h>
+#include <lib/extensions/trf.h>
#include <lib/extensions/twed.h>
#include <lib/utils.h>
@@ -348,6 +351,19 @@ 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 */
+
+#if ENABLE_SYS_REG_TRACE_FOR_NS
+ sys_reg_trace_enable(ctx);
+#endif /* ENABLE_SYS_REG_TRACE_FOR_NS */
+
+#if ENABLE_TRF_FOR_NS
+ trf_enable();
+#endif /* ENABLE_TRF_FOR_NS */
+
#endif
}
@@ -457,6 +473,8 @@ void cm_prepare_el3_exit(uint32_t security_state)
* CPTR_EL2.TTA: Set to zero so that Non-secure System
* register accesses to the trace registers from both
* Execution states do not trap to EL2.
+ * If PE trace unit System registers are not implemented
+ * then this bit is reserved, and must be set to zero.
*
* CPTR_EL2.TFP: Set to zero so that Non-secure accesses
* to SIMD and floating-point functionality from both
@@ -565,6 +583,11 @@ void cm_prepare_el3_exit(uint32_t security_state)
*
* MDCR_EL2.HPMN: Set to value of PMCR_EL0.N which is the
* architecturally-defined reset value.
+ *
+ * MDCR_EL2.E2TB: Set to zero so that the trace Buffer
+ * owning exception level is NS-EL1 and, tracing is
+ * prohibited at NS-EL2. These bits are RES0 when
+ * FEAT_TRBE is not implemented.
*/
mdcr_el2 = ((MDCR_EL2_RESET_VAL | MDCR_EL2_HLP |
MDCR_EL2_HPMD) |
@@ -574,7 +597,8 @@ void cm_prepare_el3_exit(uint32_t security_state)
MDCR_EL2_TDRA_BIT | MDCR_EL2_TDOSA_BIT |
MDCR_EL2_TDA_BIT | MDCR_EL2_TDE_BIT |
MDCR_EL2_HPME_BIT | MDCR_EL2_TPM_BIT |
- MDCR_EL2_TPMCR_BIT);
+ MDCR_EL2_TPMCR_BIT |
+ MDCR_EL2_E2TB(MDCR_EL2_E2TB_EL1));
write_mdcr_el2(mdcr_el2);
diff --git a/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c b/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c
new file mode 100644
index 0000000000..89b8029ca5
--- /dev/null
+++ b/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <lib/extensions/sys_reg_trace.h>
+
+static bool sys_reg_trace_supported(void)
+{
+ uint32_t features;
+
+ features = read_id_dfr0() >> ID_DFR0_COPTRC_SHIFT;
+ return ((features & ID_DFR0_COPTRC_MASK) ==
+ ID_DFR0_COPTRC_SUPPORTED);
+}
+
+void sys_reg_trace_enable(void)
+{
+ uint32_t val;
+
+ if (sys_reg_trace_supported()) {
+ /*
+ * NSACR.NSTRCDIS = b0
+ * enable NS system register access to implemented trace
+ * registers.
+ */
+ val = read_nsacr();
+ val &= ~NSTRCDIS_BIT;
+ write_nsacr(val);
+ }
+}
diff --git a/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c b/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
new file mode 100644
index 0000000000..960d69842a
--- /dev/null
+++ b/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <lib/extensions/sys_reg_trace.h>
+
+static bool sys_reg_trace_supported(void)
+{
+ uint64_t features;
+
+ features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEVER_SHIFT;
+ return ((features & ID_AA64DFR0_TRACEVER_MASK) ==
+ ID_AA64DFR0_TRACEVER_SUPPORTED);
+}
+
+void sys_reg_trace_enable(cpu_context_t *ctx)
+{
+ uint64_t val;
+
+ if (sys_reg_trace_supported()) {
+ /* Retrieve CPTR_EL3 value from the given context 'ctx',
+ * and update CPTR_EL3.TTA bit to 0.
+ * This function is called while switching context to NS to
+ * allow system trace register access to NS-EL2 and NS-EL1
+ * when NS-EL2 is implemented but not used.
+ */
+ val = read_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3);
+ val &= ~TTA_BIT;
+ write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, val);
+ }
+}
diff --git a/lib/extensions/trbe/trbe.c b/lib/extensions/trbe/trbe.c
new file mode 100644
index 0000000000..9f754d5213
--- /dev/null
+++ b/lib/extensions/trbe/trbe.c
@@ -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);
diff --git a/lib/extensions/trf/aarch32/trf.c b/lib/extensions/trf/aarch32/trf.c
new file mode 100644
index 0000000000..834092d5a0
--- /dev/null
+++ b/lib/extensions/trf/aarch32/trf.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <lib/extensions/trf.h>
+
+static bool trf_supported(void)
+{
+ uint32_t features;
+
+ features = read_id_dfr0() >> ID_DFR0_TRACEFILT_SHIFT;
+ return ((features & ID_DFR0_TRACEFILT_MASK) ==
+ ID_DFR0_TRACEFILT_SUPPORTED);
+}
+
+void trf_enable(void)
+{
+ uint32_t val;
+
+ if (trf_supported()) {
+ /*
+ * Allow access of trace filter control registers from
+ * non-monitor mode
+ */
+ val = read_sdcr();
+ val &= ~SDCR_TTRF_BIT;
+ write_sdcr(val);
+ }
+}
diff --git a/lib/extensions/trf/aarch64/trf.c b/lib/extensions/trf/aarch64/trf.c
new file mode 100644
index 0000000000..1da5dcee0b
--- /dev/null
+++ b/lib/extensions/trf/aarch64/trf.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <lib/extensions/trf.h>
+
+static bool trf_supported(void)
+{
+ uint64_t features;
+
+ features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEFILT_SHIFT;
+ return ((features & ID_AA64DFR0_TRACEFILT_MASK) ==
+ ID_AA64DFR0_TRACEFILT_SUPPORTED);
+}
+
+void trf_enable(void)
+{
+ uint64_t val;
+
+ if (trf_supported()) {
+ /*
+ * MDCR_EL3.TTRF = b0
+ * Allow access of trace filter control registers from NS-EL2
+ * and NS-EL1 when NS-EL2 is implemented but not used
+ */
+ val = read_mdcr_el3();
+ val &= ~MDCR_TTRF_BIT;
+ write_mdcr_el3(val);
+ }
+}
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 72f84b52e0..c1886218d7 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -355,3 +355,24 @@ 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
+
+# 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.
+ENABLE_SYS_REG_TRACE_FOR_NS := 0
+
+# By default, disable trace filter control registers access to NS
+# lower ELs, i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
+# if FEAT_TRF is implemented.
+ENABLE_TRF_FOR_NS := 0
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 3c70eede33..2f8a65e568 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -378,3 +378,12 @@ endif
# dynamically if TRUSTED_BOARD_BOOT is set.
DYN_DISABLE_AUTH := 1
endif
+
+# enable trace buffer control registers access to NS by default
+ENABLE_TRBE_FOR_NS := 1
+
+# enable trace system registers access to NS by default
+ENABLE_SYS_REG_TRACE_FOR_NS := 1
+
+# enable trace filter control registers access to NS by default
+ENABLE_TRF_FOR_NS := 1