blob: 236b10272a83800388fd458d891245b36b66bf56 [file] [log] [blame]
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +01001/*
Boyan Karatotev6468d4a2023-02-16 15:12:45 +00002 * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00007#include <stdbool.h>
8
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +01009#include <arch.h>
Andre Przywaraf3e8cfc2022-11-17 16:42:09 +000010#include <arch_features.h>
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +010011#include <arch_helpers.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000012#include <lib/el3_runtime/pubsub.h>
13#include <lib/extensions/spe.h>
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +010014
Antonio Nino Diaz033b4bb2018-10-25 16:52:26 +010015static inline void psb_csync(void)
16{
17 /*
18 * The assembler does not yet understand the psb csync mnemonic
19 * so use the equivalent hint instruction.
20 */
21 __asm__ volatile("hint #17");
22}
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +010023
Boyan Karatotev6468d4a2023-02-16 15:12:45 +000024void spe_init_el3(void)
Dimitris Papastamos5e8cd792018-02-19 14:52:19 +000025{
26 uint64_t v;
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +010027
Dimitris Papastamos5e8cd792018-02-19 14:52:19 +000028 /*
29 * MDCR_EL2.NSPB (ARM v8.2): SPE enabled in Non-secure state
30 * and disabled in secure state. Accesses to SPE registers at
31 * S-EL1 generate trap exceptions to EL3.
Manish V Badarkhe67fec3e2021-12-31 16:08:51 +000032 *
33 * MDCR_EL3.EnPMSN (ARM v8.7): Do not trap access to PMSNEVFR_EL1
34 * register at NS-EL1 or NS-EL2 to EL3 if FEAT_SPEv1p2 is implemented.
35 * Setting this bit to 1 doesn't have any effect on it when
36 * FEAT_SPEv1p2 not implemented.
Dimitris Papastamos5e8cd792018-02-19 14:52:19 +000037 */
38 v = read_mdcr_el3();
Manish V Badarkhe67fec3e2021-12-31 16:08:51 +000039 v |= MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_EnPMSN_BIT;
Dimitris Papastamos5e8cd792018-02-19 14:52:19 +000040 write_mdcr_el3(v);
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +010041}
42
Boyan Karatotev6468d4a2023-02-16 15:12:45 +000043void spe_init_el2_unused(void)
44{
45 uint64_t v;
46
47 /*
48 * MDCR_EL2.TPMS (ARM v8.2): Do not trap statistical
49 * profiling controls to EL2.
50 *
51 * MDCR_EL2.E2PB (ARM v8.2): SPE enabled in Non-secure
52 * state. Accesses to profiling buffer controls at
53 * Non-secure EL1 are not trapped to EL2.
54 */
55 v = read_mdcr_el2();
56 v &= ~MDCR_EL2_TPMS;
57 v |= MDCR_EL2_E2PB(MDCR_EL2_E2PB_EL1);
58 write_mdcr_el2(v);
59}
60
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +010061void spe_disable(void)
62{
Dimitris Papastamos5e8cd792018-02-19 14:52:19 +000063 uint64_t v;
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +010064
Dimitris Papastamos5e8cd792018-02-19 14:52:19 +000065 /* Drain buffered data */
66 psb_csync();
67 dsbnsh();
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +010068
Dimitris Papastamos5e8cd792018-02-19 14:52:19 +000069 /* Disable profiling buffer */
70 v = read_pmblimitr_el1();
71 v &= ~(1ULL << 0);
72 write_pmblimitr_el1(v);
73 isb();
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +010074}
75
76static void *spe_drain_buffers_hook(const void *arg)
77{
Andre Przywaraf3e8cfc2022-11-17 16:42:09 +000078 if (!is_feat_spe_supported())
Dimitris Papastamos5e8cd792018-02-19 14:52:19 +000079 return (void *)-1;
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +010080
Dimitris Papastamos5e8cd792018-02-19 14:52:19 +000081 /* Drain buffered data */
82 psb_csync();
83 dsbnsh();
Antonio Nino Diaz033b4bb2018-10-25 16:52:26 +010084
85 return (void *)0;
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +010086}
87
88SUBSCRIBE_TO_EVENT(cm_entering_secure_world, spe_drain_buffers_hook);