blob: 9912e7277242cd104706bb9f549a4df0c5e5b7dd [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}