blob: 28ddcd6641802102988449d5d135c1fccc78535f [file] [log] [blame]
johpow0150ccb552020-11-10 19:22:13 -06001/*
2 * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stdbool.h>
8#include <stdio.h>
9
10#include <arch.h>
11#include <arch_helpers.h>
12#include <lib/extensions/sme.h>
13
14#ifdef __aarch64__
15
16/*
17 * feat_sme_supported
18 * Check if SME is supported on this platform.
19 * Return
20 * true if SME supported, false if not.
21 */
22bool feat_sme_supported(void)
23{
24 uint64_t features;
25
26 features = read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_SME_SHIFT;
27 return (features & ID_AA64PFR1_EL1_SME_MASK) != 0U;
28}
29
30/*
31 * feat_sme_fa64_supported
32 * Check if FEAT_SME_FA64 is supported.
33 * Return
34 * True if supported, false if not.
35 */
36bool feat_sme_fa64_supported(void)
37{
38 uint64_t features;
39
40 features = read_id_aa64smfr0_el1();
41 return (features & ID_AA64SMFR0_EL1_FA64_BIT) != 0U;
42}
43
44/*
45 * sme_enable
46 * Enable SME for nonsecure use at EL2 for TFTF cases.
47 * Return
48 * 0 if successful.
49 */
50int sme_enable(void)
51{
52 u_register_t reg;
53
54 /* Make sure SME is supported. */
55 if (!feat_sme_supported()) {
56 return -1;
57 }
58
59 /*
60 * Make sure SME accesses don't cause traps by setting appropriate fields
61 * in CPTR_EL2.
62 */
63 reg = read_cptr_el2();
64 if ((read_hcr_el2() & HCR_E2H_BIT) == 0U) {
65 /* When HCR_EL2.E2H == 0, clear TSM bit in CPTR_EL2. */
66 reg = reg & ~CPTR_EL2_TSM_BIT;
67 } else {
68 /* When HCR_EL2.E2H == 1, set SMEN bits in CPTR_EL2. */
69 reg = reg | (CPTR_EL2_SMEN_MASK << CPTR_EL2_SMEN_SHIFT);
70 }
71 write_cptr_el2(reg);
72
73 return 0;
74}
75
76/*
77 * sme_smstart
78 * This function enables streaming mode and optinally enables ZA array access
79 * at the same time.
80 * Parameters
81 * enable_za: If set, ZA access is enabled. If cleared, ZA bit is untouched.
82 */
83void sme_smstart(bool enable_za)
84{
85 u_register_t svcr = SVCR_SM_BIT;
86
87 if (enable_za) {
88 svcr |= SVCR_ZA_BIT;
89 }
90
91 write_svcr(read_svcr() | svcr);
92}
93
94/*
95 * sme_smstop
96 * This function disables streaming mode OR disables ZA array access but not
97 * both. It might seem strange but this is the functionality of the SMSTOP
98 * assembly instruction.
99 * Parameters
100 * disable_za: If set, ZA access is disabled but streaming mode is not
101 * affected. If clear, streaming mode is exited and ZA bit is
102 * left alone.
103 */
104void sme_smstop(bool disable_za)
105{
106 u_register_t svcr;
107
108 if (disable_za) {
109 svcr = ~SVCR_ZA_BIT;
110 } else {
111 svcr = ~SVCR_SM_BIT;
112 }
113
114 write_svcr(read_svcr() & svcr);
115}
116
117#endif /* __aarch64__ */