blob: a7337ee6544c5ace6624278daaee8fc219ca1d92 [file] [log] [blame]
johpow0150ccb552020-11-10 19:22:13 -06001/*
Olivier Deprez6043eaf2024-03-08 14:14:12 +01002 * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
johpow0150ccb552020-11-10 19:22:13 -06003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stdbool.h>
8#include <stdio.h>
9
10#include <arch.h>
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000011#include <arch_features.h>
johpow0150ccb552020-11-10 19:22:13 -060012#include <arch_helpers.h>
Arunachalam Ganapathy5b68e202023-06-06 16:31:19 +010013#include <assert.h>
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000014#include <debug.h>
johpow0150ccb552020-11-10 19:22:13 -060015#include <lib/extensions/sme.h>
16
johpow0150ccb552020-11-10 19:22:13 -060017/*
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000018 * Function: sme_smstart
19 * This function enables streaming mode and ZA array storage access
20 * independently or together based on the type of instruction variant.
21 *
johpow0150ccb552020-11-10 19:22:13 -060022 * Parameters
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000023 * smstart_type: If SMSTART, streaming mode and ZA access is enabled.
24 * If SMSTART_SM, streaming mode enabled.
25 * If SMSTART_ZA enables SME ZA storage and, ZT0 storage access.
johpow0150ccb552020-11-10 19:22:13 -060026 */
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000027void sme_smstart(smestart_instruction_type_t smstart_type)
johpow0150ccb552020-11-10 19:22:13 -060028{
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000029 u_register_t svcr = 0ULL;
johpow0150ccb552020-11-10 19:22:13 -060030
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000031 switch (smstart_type) {
32 case SMSTART:
33 svcr = (SVCR_SM_BIT | SVCR_ZA_BIT);
34 break;
35
36 case SMSTART_SM:
37 svcr = SVCR_SM_BIT;
38 break;
39
40 case SMSTART_ZA:
41 svcr = SVCR_ZA_BIT;
42 break;
43
44 default:
45 ERROR("Illegal SMSTART Instruction Variant\n");
46 break;
johpow0150ccb552020-11-10 19:22:13 -060047 }
johpow0150ccb552020-11-10 19:22:13 -060048 write_svcr(read_svcr() | svcr);
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000049
50 isb();
johpow0150ccb552020-11-10 19:22:13 -060051}
52
53/*
54 * sme_smstop
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000055 * This function exits streaming mode and disables ZA array storage access
56 * independently or together based on the type of instruction variant.
57 *
johpow0150ccb552020-11-10 19:22:13 -060058 * Parameters
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000059 * smstop_type: If SMSTOP, exits streaming mode and ZA access is disabled
60 * If SMSTOP_SM, exits streaming mode.
61 * If SMSTOP_ZA disables SME ZA storage and, ZT0 storage access.
johpow0150ccb552020-11-10 19:22:13 -060062 */
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000063void sme_smstop(smestop_instruction_type_t smstop_type)
johpow0150ccb552020-11-10 19:22:13 -060064{
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000065 u_register_t svcr = 0ULL;
johpow0150ccb552020-11-10 19:22:13 -060066
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000067 switch (smstop_type) {
68 case SMSTOP:
69 svcr = (~SVCR_SM_BIT) & (~SVCR_ZA_BIT);
70 break;
71
72 case SMSTOP_SM:
johpow0150ccb552020-11-10 19:22:13 -060073 svcr = ~SVCR_SM_BIT;
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000074 break;
75
76 case SMSTOP_ZA:
77 svcr = ~SVCR_ZA_BIT;
78 break;
79
80 default:
81 ERROR("Illegal SMSTOP Instruction Variant\n");
82 break;
johpow0150ccb552020-11-10 19:22:13 -060083 }
johpow0150ccb552020-11-10 19:22:13 -060084 write_svcr(read_svcr() & svcr);
johpow0150ccb552020-11-10 19:22:13 -060085
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +000086 isb();
87}
Arunachalam Ganapathy5b68e202023-06-06 16:31:19 +010088
89/* Set the Streaming SVE vector length (SVL) in the SMCR_EL2 register */
90void sme_config_svq(uint32_t svq)
91{
92 u_register_t smcr_el2_val;
93
Olivier Deprez6043eaf2024-03-08 14:14:12 +010094 /* Cap svq to arch supported max value. */
Arunachalam Ganapathy5b68e202023-06-06 16:31:19 +010095 if (svq > SME_SVQ_ARCH_MAX) {
96 svq = SME_SVQ_ARCH_MAX;
97 }
98
99 smcr_el2_val = read_smcr_el2();
100
101 smcr_el2_val &= ~(MASK(SMCR_ELX_LEN));
102 smcr_el2_val |= INPLACE(SMCR_ELX_LEN, svq);
103
104 write_smcr_el2(smcr_el2_val);
105 isb();
106}
107
108static void set_smcr_fa64(bool enable)
109{
110 if (enable) {
111 write_smcr_el2(read_smcr_el2() | SMCR_ELX_FA64_BIT);
112 } else {
113 write_smcr_el2(read_smcr_el2() & ~SMCR_ELX_FA64_BIT);
114 }
115
116 isb();
117}
118
119/*
120 * Enable FEAT_SME_FA64, This control causes all implemented A64 instructions
121 * to be treated as legal in Streaming SVE mode at EL2, if they are treated as
122 * legal at EL3.
123 */
124void sme_enable_fa64(void)
125{
126 return set_smcr_fa64(true);
127}
128
129/*
130 * Disable FEAT_SME_FA64, This control does not cause any instruction to be
131 * treated as legal in Streaming SVE mode.
132 */
133void sme_disable_fa64(void)
134{
135 return set_smcr_fa64(false);
136}
137
138/* Returns 'true' if the CPU is in Streaming SVE mode */
139bool sme_smstat_sm(void)
140{
141 return ((read_svcr() & SVCR_SM_BIT) != 0U);
142}
143
144bool sme_feat_fa64_enabled(void)
145{
146 return ((read_smcr_el2() & SMCR_ELX_FA64_BIT) != 0U);
147}
Olivier Deprez6043eaf2024-03-08 14:14:12 +0100148
149uint32_t sme_probe_svl(uint8_t sme_max_svq)
150{
151 uint32_t svl_bitmap = 0;
152 uint8_t svq, rdsvl_vq;
153
154 /* Cap svq to arch supported max value. */
155 if (sme_max_svq > SME_SVQ_ARCH_MAX) {
156 sme_max_svq = SME_SVQ_ARCH_MAX;
157 }
158
159 for (svq = 0; svq <= sme_max_svq; svq++) {
160 sme_config_svq(svq);
161 rdsvl_vq = SME_SVL_TO_SVQ(sme_rdsvl_1());
162 if (svl_bitmap & BIT_32(rdsvl_vq)) {
163 continue;
164 }
165 svl_bitmap |= BIT_32(rdsvl_vq);
166 }
167
168 return svl_bitmap;
169}