xref: /rk3399_ARM-atf/lib/extensions/trbe/trbe.c (revision 6dc5979a6cb2121e4c16e7bd62e24030e0f42755)
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