blob: 632b2a793cb8029401ddb4eddf686015352731bf [file] [log] [blame]
/*
* Copyright (c) 2021-2023, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdbool.h>
#include <stdio.h>
#include <arch.h>
#include <arch_features.h>
#include <arch_helpers.h>
#include <debug.h>
#include <lib/extensions/sme.h>
/*
* Function : sme_enable
* Enable SME for nonsecure use at EL2 for TFTF cases.
*/
void sme_enable(void)
{
u_register_t reg;
/*
* Make sure SME accesses don't cause traps by setting appropriate
* fields in CPTR_EL2.
*/
reg = read_cptr_el2();
if ((read_hcr_el2() & HCR_E2H_BIT) == 0U) {
/* When HCR_EL2.E2H == 0, clear TSM bit in CPTR_EL2. */
reg = reg & ~CPTR_EL2_TSM_BIT;
} else {
/* When HCR_EL2.E2H == 1, set SMEN bits in CPTR_EL2. */
reg = reg | (CPTR_EL2_SMEN_MASK << CPTR_EL2_SMEN_SHIFT);
}
write_cptr_el2(reg);
isb();
}
/*
* Function: sme_smstart
* This function enables streaming mode and ZA array storage access
* independently or together based on the type of instruction variant.
*
* Parameters
* smstart_type: If SMSTART, streaming mode and ZA access is enabled.
* If SMSTART_SM, streaming mode enabled.
* If SMSTART_ZA enables SME ZA storage and, ZT0 storage access.
*/
void sme_smstart(smestart_instruction_type_t smstart_type)
{
u_register_t svcr = 0ULL;
switch (smstart_type) {
case SMSTART:
svcr = (SVCR_SM_BIT | SVCR_ZA_BIT);
break;
case SMSTART_SM:
svcr = SVCR_SM_BIT;
break;
case SMSTART_ZA:
svcr = SVCR_ZA_BIT;
break;
default:
ERROR("Illegal SMSTART Instruction Variant\n");
break;
}
write_svcr(read_svcr() | svcr);
isb();
}
/*
* sme_smstop
* This function exits streaming mode and disables ZA array storage access
* independently or together based on the type of instruction variant.
*
* Parameters
* smstop_type: If SMSTOP, exits streaming mode and ZA access is disabled
* If SMSTOP_SM, exits streaming mode.
* If SMSTOP_ZA disables SME ZA storage and, ZT0 storage access.
*/
void sme_smstop(smestop_instruction_type_t smstop_type)
{
u_register_t svcr = 0ULL;
switch (smstop_type) {
case SMSTOP:
svcr = (~SVCR_SM_BIT) & (~SVCR_ZA_BIT);
break;
case SMSTOP_SM:
svcr = ~SVCR_SM_BIT;
break;
case SMSTOP_ZA:
svcr = ~SVCR_ZA_BIT;
break;
default:
ERROR("Illegal SMSTOP Instruction Variant\n");
break;
}
write_svcr(read_svcr() & svcr);
isb();
}