blob: 9f754d5213e3a48e3bd197dc087f0765388ca7f4 [file] [log] [blame]
Manish V Badarkhe20df29c2021-07-02 09:10:56 +01001/*
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
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
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
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
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
63SUBSCRIBE_TO_EVENT(cm_entering_secure_world, trbe_drain_trace_buffers_hook);