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