blob: b0fea4b453a243114258d7fcfc6aa19ff93ffcbd [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
Arunachalam Ganapathy417edca2023-09-05 17:44:24 +01002 * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Arunachalam Ganapathy417edca2023-09-05 17:44:24 +01007#include <arch.h>
8#include <arch_features.h>
9#include <lib/extensions/sve.h>
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020010#include <stdint.h>
Arunachalam Ganapathy417edca2023-09-05 17:44:24 +010011#include <smccc.h>
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020012#include <tftf.h>
Arunachalam Ganapathy417edca2023-09-05 17:44:24 +010013#include <utils_def.h>
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020014
Arunachalam Ganapathy417edca2023-09-05 17:44:24 +010015static void sve_enable(void)
16{
17 if (IS_IN_EL2()) {
18 write_cptr_el2(read_cptr_el2() & ~CPTR_EL2_TZ_BIT);
19 } else {
20 write_cpacr_el1(read_cpacr_el1() |
21 CPACR_EL1_ZEN(CPACR_EL1_ZEN_TRAP_NONE));
22 }
23
24 isb();
25}
26
27static void sve_disable(void)
28{
29 if (IS_IN_EL2()) {
30 write_cptr_el2(read_cptr_el2() | CPTR_EL2_TZ_BIT);
31 } else {
32 unsigned long val = read_cpacr_el1();
33
34 val &= ~CPACR_EL1_ZEN(CPACR_EL1_ZEN_TRAP_NONE);
35 val |= CPACR_EL1_ZEN(CPACR_EL1_ZEN_TRAP_ALL);
36 write_cpacr_el1(val);
37 }
38
39 isb();
40}
41
42static bool is_sve_enabled(void)
43{
44 if (IS_IN_EL2()) {
45 return ((read_cptr_el2() & CPTR_EL2_TZ_BIT) == 0UL);
46 } else {
47 return ((read_cpacr_el1() &
48 CPACR_EL1_ZEN(CPACR_EL1_ZEN_TRAP_NONE)) ==
49 CPACR_EL1_ZEN(CPACR_EL1_ZEN_TRAP_NONE));
50 }
51}
52
53/*
54 * Use Trap control register SVE flags to represent SVE hint bit. On SVE capable
55 * CPU, setting sve_hint_flag = true denotes absence of SVE (disables SVE), else
56 * presence of SVE (enables SVE).
57 */
58void tftf_smc_set_sve_hint(bool sve_hint_flag)
59{
60 if (!is_armv8_2_sve_present()) {
61 return;
62 }
63
64 if (sve_hint_flag) {
65 sve_disable();
66 } else {
67 sve_enable();
68 }
69}
70
71/*
72 * On SVE capable CPU, return value of 'true' denotes SVE not used and return
73 * value of 'false' denotes SVE used.
74 *
75 * If the CPU do not support SVE, always return 'false'.
76 */
77bool tftf_smc_get_sve_hint(void)
78{
79 if (is_armv8_2_sve_present()) {
80 return is_sve_enabled() ? false : true;
81 }
82
83 return false;
84}
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020085
86smc_ret_values tftf_smc(const smc_args *args)
87{
Arunachalam Ganapathy417edca2023-09-05 17:44:24 +010088 uint32_t fid = args->fid;
89
90 if (tftf_smc_get_sve_hint()) {
91 fid |= MASK(FUNCID_SVE_HINT);
92 } else {
93 fid &= ~MASK(FUNCID_SVE_HINT);
94 }
95
96 return asm_tftf_smc64(fid,
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020097 args->arg1,
98 args->arg2,
99 args->arg3,
100 args->arg4,
101 args->arg5,
102 args->arg6,
103 args->arg7);
104}
Juan Pablo Condec79338a2024-10-28 18:48:25 -0500105
106void tftf_smc_no_retval_x8(const smc_args_ext *args, smc_ret_values_ext *ret)
107{
108 uint32_t fid = args->fid;
109 /* Copy args into new structure so the fid field can be modified */
110 smc_args_ext args_copy = *args;
111
112 if (tftf_smc_get_sve_hint()) {
113 fid |= MASK(FUNCID_SVE_HINT);
114 } else {
115 fid &= ~MASK(FUNCID_SVE_HINT);
116 }
117 args_copy.fid = fid;
118
119 asm_tftf_smc64_no_retval_x8(&args_copy, ret);
120}