1281a08ccSDimitris Papastamos /* 2fc7dca72SBoyan Karatotev * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved. 3281a08ccSDimitris Papastamos * 4281a08ccSDimitris Papastamos * SPDX-License-Identifier: BSD-3-Clause 5281a08ccSDimitris Papastamos */ 6281a08ccSDimitris Papastamos 709d40e0eSAntonio Nino Diaz #include <stdbool.h> 809d40e0eSAntonio Nino Diaz 9281a08ccSDimitris Papastamos #include <arch.h> 106437a09aSAndre Przywara #include <arch_features.h> 11281a08ccSDimitris Papastamos #include <arch_helpers.h> 1209d40e0eSAntonio Nino Diaz #include <lib/extensions/spe.h> 13281a08ccSDimitris Papastamos 14777f1f68SJayanth Dodderi Chidanand #include <plat/common/platform.h> 15777f1f68SJayanth Dodderi Chidanand 16123002f9SJayanth Dodderi Chidanand void spe_enable(cpu_context_t *ctx) 172ff8fbf3SDimitris Papastamos { 18123002f9SJayanth Dodderi Chidanand el3_state_t *state = get_el3state_ctx(ctx); 19123002f9SJayanth Dodderi Chidanand u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3); 20281a08ccSDimitris Papastamos 21281a08ccSDimitris Papastamos /* 2299506facSBoyan Karatotev * MDCR_EL3.NSPB (ARM v8.2): SPE enabled in Non-secure state 23281a08ccSDimitris Papastamos * and disabled in secure state. Accesses to SPE registers at 24281a08ccSDimitris Papastamos * S-EL1 generate trap exceptions to EL3. 25f20eb893SManish V Badarkhe * 2699506facSBoyan Karatotev * MDCR_EL3.NSPBE: Profiling Buffer uses Non-secure Virtual Addresses. 2799506facSBoyan Karatotev * When FEAT_RME is not implemented, this field is RES0. 2899506facSBoyan Karatotev * 29*4fd9814fSJames Clark * MDCR_EL3.EnPMSN (ARM v8.7) and MDCR_EL3.EnPMS3: Do not trap access to 30*4fd9814fSJames Clark * PMSNEVFR_EL1 or PMSDSFR_EL1 register at NS-EL1 or NS-EL2 to EL3 if FEAT_SPEv1p2 31*4fd9814fSJames Clark * or FEAT_SPE_FDS are implemented. Setting these bits to 1 doesn't have any 32*4fd9814fSJames Clark * effect on it when the features aren't implemented. 33281a08ccSDimitris Papastamos */ 34*4fd9814fSJames Clark mdcr_el3_val |= MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_EnPMSN_BIT | MDCR_EnPMS3_BIT; 35123002f9SJayanth Dodderi Chidanand mdcr_el3_val &= ~(MDCR_NSPBE_BIT); 36123002f9SJayanth Dodderi Chidanand write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val); 37281a08ccSDimitris Papastamos } 38281a08ccSDimitris Papastamos 39651fe507SManish Pandey void spe_disable(cpu_context_t *ctx) 40651fe507SManish Pandey { 41651fe507SManish Pandey el3_state_t *state = get_el3state_ctx(ctx); 42651fe507SManish Pandey u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3); 43651fe507SManish Pandey 44651fe507SManish Pandey /* 4513f4a252SBoyan Karatotev * MDCR_EL3.{NSPB,NSPBE} = 0b00, 0b0 4613f4a252SBoyan Karatotev * Disable access of profiling buffer control registers from lower ELs 4713f4a252SBoyan Karatotev * in any security state. Secure state owns the buffer. 48651fe507SManish Pandey * 49*4fd9814fSJames Clark * MDCR_EL3.EnPMSN (ARM v8.7) and MDCR_EL3.EnPMS3: Clear the bits to trap access 50*4fd9814fSJames Clark * of PMSNEVFR_EL1 and PMSDSFR_EL1 from EL2/EL1 to EL3. 51651fe507SManish Pandey */ 52*4fd9814fSJames Clark mdcr_el3_val &= ~(MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_NSPBE_BIT | MDCR_EnPMSN_BIT | 53*4fd9814fSJames Clark MDCR_EnPMS3_BIT); 54651fe507SManish Pandey write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val); 55651fe507SManish Pandey } 56651fe507SManish Pandey 5760d330dcSBoyan Karatotev void spe_init_el2_unused(void) 5860d330dcSBoyan Karatotev { 5960d330dcSBoyan Karatotev uint64_t v; 6060d330dcSBoyan Karatotev 6160d330dcSBoyan Karatotev /* 6260d330dcSBoyan Karatotev * MDCR_EL2.TPMS (ARM v8.2): Do not trap statistical 6360d330dcSBoyan Karatotev * profiling controls to EL2. 6460d330dcSBoyan Karatotev * 6560d330dcSBoyan Karatotev * MDCR_EL2.E2PB (ARM v8.2): SPE enabled in Non-secure 6660d330dcSBoyan Karatotev * state. Accesses to profiling buffer controls at 6760d330dcSBoyan Karatotev * Non-secure EL1 are not trapped to EL2. 6860d330dcSBoyan Karatotev */ 6960d330dcSBoyan Karatotev v = read_mdcr_el2(); 7060d330dcSBoyan Karatotev v &= ~MDCR_EL2_TPMS; 7160d330dcSBoyan Karatotev v |= MDCR_EL2_E2PB(MDCR_EL2_E2PB_EL1); 7260d330dcSBoyan Karatotev write_mdcr_el2(v); 7360d330dcSBoyan Karatotev } 74