mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 18:14:24 +00:00

Currently, enabling SME forces SVE off. However, the SME enablement requires SVE to be enabled, which is reflected in code. This is the opposite of what the build flags require. Further, the few platforms that enable SME also explicitly enable SVE. Their platform.mk runs after the defaults.mk file so this override never materializes. As a result, the override is only present on the commandline. Change it to something sensible where if SME is on then code can rely on SVE being on too. Do this with a check in the Makefile as it is the more widely used pattern. This maintains all valid use cases but subtly changes corner cases no one uses at the moment to require a slightly different combination of flags. Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com> Change-Id: If7ca3972ebc3c321e554533d7bc81af49c2472be
89 lines
2.2 KiB
C
89 lines
2.2 KiB
C
/*
|
|
* Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <arch.h>
|
|
#include <arch_features.h>
|
|
#include <arch_helpers.h>
|
|
#include <common/debug.h>
|
|
#include <lib/el3_runtime/context_mgmt.h>
|
|
#include <lib/extensions/sme.h>
|
|
#include <lib/extensions/sve.h>
|
|
|
|
void sme_enable(cpu_context_t *context)
|
|
{
|
|
u_register_t reg;
|
|
u_register_t cptr_el3;
|
|
el3_state_t *state;
|
|
|
|
/* Get the context state. */
|
|
state = get_el3state_ctx(context);
|
|
|
|
/* Enable SME in CPTR_EL3. */
|
|
reg = read_ctx_reg(state, CTX_CPTR_EL3);
|
|
reg |= ESM_BIT;
|
|
write_ctx_reg(state, CTX_CPTR_EL3, reg);
|
|
|
|
/* Set the ENTP2 bit in SCR_EL3 to enable access to TPIDR2_EL0. */
|
|
reg = read_ctx_reg(state, CTX_SCR_EL3);
|
|
reg |= SCR_ENTP2_BIT;
|
|
write_ctx_reg(state, CTX_SCR_EL3, reg);
|
|
|
|
/* Set CPTR_EL3.ESM bit so we can write SMCR_EL3 without trapping. */
|
|
cptr_el3 = read_cptr_el3();
|
|
write_cptr_el3(cptr_el3 | ESM_BIT);
|
|
isb();
|
|
|
|
/*
|
|
* Set the max LEN value and FA64 bit. This register is set up globally
|
|
* to be the least restrictive, then lower ELs can restrict as needed
|
|
* using SMCR_EL2 and SMCR_EL1.
|
|
*/
|
|
reg = SMCR_ELX_LEN_MAX;
|
|
|
|
if (read_feat_sme_fa64_id_field() != 0U) {
|
|
VERBOSE("[SME] FA64 enabled\n");
|
|
reg |= SMCR_ELX_FA64_BIT;
|
|
}
|
|
|
|
/*
|
|
* Enable access to ZT0 register.
|
|
* Make sure FEAT_SME2 is supported by the hardware before continuing.
|
|
* If supported, Set the EZT0 bit in SMCR_EL3 to allow instructions to
|
|
* access ZT0 register without trapping.
|
|
*/
|
|
if (is_feat_sme2_supported()) {
|
|
VERBOSE("SME2 enabled\n");
|
|
reg |= SMCR_ELX_EZT0_BIT;
|
|
}
|
|
write_smcr_el3(reg);
|
|
|
|
/* Reset CPTR_EL3 value. */
|
|
write_cptr_el3(cptr_el3);
|
|
isb();
|
|
}
|
|
|
|
void sme_disable(cpu_context_t *context)
|
|
{
|
|
u_register_t reg;
|
|
el3_state_t *state;
|
|
|
|
/* Get the context state. */
|
|
state = get_el3state_ctx(context);
|
|
|
|
/* Disable SME, SVE, and FPU since they all share registers. */
|
|
reg = read_ctx_reg(state, CTX_CPTR_EL3);
|
|
reg &= ~ESM_BIT; /* Trap SME */
|
|
reg &= ~CPTR_EZ_BIT; /* Trap SVE */
|
|
reg |= TFP_BIT; /* Trap FPU/SIMD */
|
|
write_ctx_reg(state, CTX_CPTR_EL3, reg);
|
|
|
|
/* Disable access to TPIDR2_EL0. */
|
|
reg = read_ctx_reg(state, CTX_SCR_EL3);
|
|
reg &= ~SCR_ENTP2_BIT;
|
|
write_ctx_reg(state, CTX_SCR_EL3, reg);
|
|
}
|