blob: e499486cbe1daad5eb656ee6c5787388b8a5fa3f [file] [log] [blame]
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +01001/*
Boyan Karatotevf9263222024-12-16 16:23:26 +00002 * Copyright (c) 2017-2025, 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/extensions/spe.h>
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +010013
Jayanth Dodderi Chidanand18d93792023-07-18 14:48:09 +010014#include <plat/common/platform.h>
15
Jayanth Dodderi Chidanand118b3352024-06-18 15:22:54 +010016void spe_enable(cpu_context_t *ctx)
Dimitris Papastamos5e8cd792018-02-19 14:52:19 +000017{
Jayanth Dodderi Chidanand118b3352024-06-18 15:22:54 +010018 el3_state_t *state = get_el3state_ctx(ctx);
19 u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +010020
Dimitris Papastamos5e8cd792018-02-19 14:52:19 +000021 /*
Boyan Karatotev6e2fd8b2023-02-13 16:38:37 +000022 * MDCR_EL3.NSPB (ARM v8.2): SPE enabled in Non-secure state
Dimitris Papastamos5e8cd792018-02-19 14:52:19 +000023 * and disabled in secure state. Accesses to SPE registers at
24 * S-EL1 generate trap exceptions to EL3.
Manish V Badarkhe67fec3e2021-12-31 16:08:51 +000025 *
Boyan Karatotev6e2fd8b2023-02-13 16:38:37 +000026 * MDCR_EL3.NSPBE: Profiling Buffer uses Non-secure Virtual Addresses.
27 * When FEAT_RME is not implemented, this field is RES0.
28 *
James Clark536ca3a2025-04-24 16:00:26 +010029 * MDCR_EL3.EnPMSN (ARM v8.7) and MDCR_EL3.EnPMS3: Do not trap access to
30 * PMSNEVFR_EL1 or PMSDSFR_EL1 register at NS-EL1 or NS-EL2 to EL3 if FEAT_SPEv1p2
31 * or FEAT_SPE_FDS are implemented. Setting these bits to 1 doesn't have any
32 * effect on it when the features aren't implemented.
Dimitris Papastamos5e8cd792018-02-19 14:52:19 +000033 */
James Clark536ca3a2025-04-24 16:00:26 +010034 mdcr_el3_val |= MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_EnPMSN_BIT | MDCR_EnPMS3_BIT;
Jayanth Dodderi Chidanand118b3352024-06-18 15:22:54 +010035 mdcr_el3_val &= ~(MDCR_NSPBE_BIT);
36 write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
Dimitris Papastamos5bdbb472017-10-13 12:06:06 +010037}
38
Manish Pandeye01b4222024-07-18 16:17:45 +010039void spe_disable(cpu_context_t *ctx)
40{
41 el3_state_t *state = get_el3state_ctx(ctx);
42 u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
43
44 /*
Boyan Karatotev3eaf1b32025-01-10 12:04:50 +000045 * MDCR_EL3.{NSPB,NSPBE} = 0b00, 0b0
46 * Disable access of profiling buffer control registers from lower ELs
47 * in any security state. Secure state owns the buffer.
Manish Pandeye01b4222024-07-18 16:17:45 +010048 *
James Clark536ca3a2025-04-24 16:00:26 +010049 * MDCR_EL3.EnPMSN (ARM v8.7) and MDCR_EL3.EnPMS3: Clear the bits to trap access
50 * of PMSNEVFR_EL1 and PMSDSFR_EL1 from EL2/EL1 to EL3.
Manish Pandeye01b4222024-07-18 16:17:45 +010051 */
James Clark536ca3a2025-04-24 16:00:26 +010052 mdcr_el3_val &= ~(MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_NSPBE_BIT | MDCR_EnPMSN_BIT |
53 MDCR_EnPMS3_BIT);
Manish Pandeye01b4222024-07-18 16:17:45 +010054 write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
55}
56
Boyan Karatotev6468d4a2023-02-16 15:12:45 +000057void spe_init_el2_unused(void)
58{
59 uint64_t v;
60
61 /*
62 * MDCR_EL2.TPMS (ARM v8.2): Do not trap statistical
63 * profiling controls to EL2.
64 *
65 * MDCR_EL2.E2PB (ARM v8.2): SPE enabled in Non-secure
66 * state. Accesses to profiling buffer controls at
67 * Non-secure EL1 are not trapped to EL2.
68 */
69 v = read_mdcr_el2();
70 v &= ~MDCR_EL2_TPMS;
71 v |= MDCR_EL2_E2PB(MDCR_EL2_E2PB_EL1);
72 write_mdcr_el2(v);
73}