1 /* 2 * Copyright (c) 2021-2022, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch.h> 8 #include <arch_features.h> 9 #include <arch_helpers.h> 10 #include <lib/el3_runtime/pubsub.h> 11 #include <lib/extensions/trbe.h> 12 13 static void tsb_csync(void) 14 { 15 /* 16 * The assembler does not yet understand the tsb csync mnemonic 17 * so use the equivalent hint instruction. 18 */ 19 __asm__ volatile("hint #18"); 20 } 21 22 void trbe_enable(void) 23 { 24 uint64_t val; 25 26 if (is_feat_trbe_present()) { 27 /* 28 * MDCR_EL3.NSTB = 0b11 29 * Allow access of trace buffer control registers from NS-EL1 30 * and NS-EL2, tracing is prohibited in Secure and Realm state 31 * (if implemented). 32 */ 33 val = read_mdcr_el3(); 34 val |= MDCR_NSTB(MDCR_NSTB_EL1); 35 write_mdcr_el3(val); 36 } 37 } 38 39 static void *trbe_drain_trace_buffers_hook(const void *arg __unused) 40 { 41 if (is_feat_trbe_present()) { 42 /* 43 * Before switching from normal world to secure world 44 * the trace buffers need to be drained out to memory. This is 45 * required to avoid an invalid memory access when TTBR is switched 46 * for entry to S-EL1. 47 */ 48 tsb_csync(); 49 dsbnsh(); 50 } 51 52 return (void *)0; 53 } 54 55 SUBSCRIBE_TO_EVENT(cm_entering_secure_world, trbe_drain_trace_buffers_hook); 56