1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2021-2023, Arm Limited. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <arch.h> 8*91f16700Schasinglulu #include <arch_features.h> 9*91f16700Schasinglulu #include <arch_helpers.h> 10*91f16700Schasinglulu #include <lib/el3_runtime/pubsub.h> 11*91f16700Schasinglulu #include <lib/extensions/trbe.h> 12*91f16700Schasinglulu 13*91f16700Schasinglulu static void tsb_csync(void) 14*91f16700Schasinglulu { 15*91f16700Schasinglulu /* 16*91f16700Schasinglulu * The assembler does not yet understand the tsb csync mnemonic 17*91f16700Schasinglulu * so use the equivalent hint instruction. 18*91f16700Schasinglulu */ 19*91f16700Schasinglulu __asm__ volatile("hint #18"); 20*91f16700Schasinglulu } 21*91f16700Schasinglulu 22*91f16700Schasinglulu void trbe_init_el3(void) 23*91f16700Schasinglulu { 24*91f16700Schasinglulu u_register_t val; 25*91f16700Schasinglulu 26*91f16700Schasinglulu /* 27*91f16700Schasinglulu * MDCR_EL3.NSTBE = 0b0 28*91f16700Schasinglulu * Trace Buffer owning Security state is Non-secure state. If FEAT_RME 29*91f16700Schasinglulu * is not implemented, this field is RES0. 30*91f16700Schasinglulu * 31*91f16700Schasinglulu * MDCR_EL3.NSTB = 0b11 32*91f16700Schasinglulu * Allow access of trace buffer control registers from NS-EL1 and 33*91f16700Schasinglulu * NS-EL2, tracing is prohibited in Secure and Realm state (if 34*91f16700Schasinglulu * implemented). 35*91f16700Schasinglulu */ 36*91f16700Schasinglulu val = read_mdcr_el3(); 37*91f16700Schasinglulu val |= MDCR_NSTB(MDCR_NSTB_EL1); 38*91f16700Schasinglulu val &= ~(MDCR_NSTBE_BIT); 39*91f16700Schasinglulu write_mdcr_el3(val); 40*91f16700Schasinglulu } 41*91f16700Schasinglulu 42*91f16700Schasinglulu void trbe_init_el2_unused(void) 43*91f16700Schasinglulu { 44*91f16700Schasinglulu /* 45*91f16700Schasinglulu * MDCR_EL2.E2TB: Set to zero so that the trace Buffer 46*91f16700Schasinglulu * owning exception level is NS-EL1 and, tracing is 47*91f16700Schasinglulu * prohibited at NS-EL2. These bits are RES0 when 48*91f16700Schasinglulu * FEAT_TRBE is not implemented. 49*91f16700Schasinglulu */ 50*91f16700Schasinglulu write_mdcr_el2(read_mdcr_el2() & ~MDCR_EL2_E2TB(MDCR_EL2_E2TB_EL1)); 51*91f16700Schasinglulu } 52*91f16700Schasinglulu 53*91f16700Schasinglulu static void *trbe_drain_trace_buffers_hook(const void *arg __unused) 54*91f16700Schasinglulu { 55*91f16700Schasinglulu if (is_feat_trbe_supported()) { 56*91f16700Schasinglulu /* 57*91f16700Schasinglulu * Before switching from normal world to secure world 58*91f16700Schasinglulu * the trace buffers need to be drained out to memory. This is 59*91f16700Schasinglulu * required to avoid an invalid memory access when TTBR is switched 60*91f16700Schasinglulu * for entry to S-EL1. 61*91f16700Schasinglulu */ 62*91f16700Schasinglulu tsb_csync(); 63*91f16700Schasinglulu dsbnsh(); 64*91f16700Schasinglulu } 65*91f16700Schasinglulu 66*91f16700Schasinglulu return (void *)0; 67*91f16700Schasinglulu } 68*91f16700Schasinglulu 69*91f16700Schasinglulu SUBSCRIBE_TO_EVENT(cm_entering_secure_world, trbe_drain_trace_buffers_hook); 70