blob: 72f01c6281d38fbffc337cc6ece0fb3b2c13b6b6 [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>
Mark Dykesf41d8ee2025-07-10 16:41:28 -05009#include <drivers/console.h>
Arunachalam Ganapathy417edca2023-09-05 17:44:24 +010010#include <lib/extensions/sve.h>
Arunachalam Ganapathy417edca2023-09-05 17:44:24 +010011#include <smccc.h>
Mark Dykesf41d8ee2025-07-10 16:41:28 -050012#include <stdint.h>
13#include <stdio.h>
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020014#include <tftf.h>
Arunachalam Ganapathy417edca2023-09-05 17:44:24 +010015#include <utils_def.h>
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020016
Mark Dykesf41d8ee2025-07-10 16:41:28 -050017
Arunachalam Ganapathy417edca2023-09-05 17:44:24 +010018static void sve_enable(void)
19{
20 if (IS_IN_EL2()) {
21 write_cptr_el2(read_cptr_el2() & ~CPTR_EL2_TZ_BIT);
22 } else {
23 write_cpacr_el1(read_cpacr_el1() |
24 CPACR_EL1_ZEN(CPACR_EL1_ZEN_TRAP_NONE));
25 }
26
27 isb();
28}
29
30static void sve_disable(void)
31{
32 if (IS_IN_EL2()) {
33 write_cptr_el2(read_cptr_el2() | CPTR_EL2_TZ_BIT);
34 } else {
35 unsigned long val = read_cpacr_el1();
36
37 val &= ~CPACR_EL1_ZEN(CPACR_EL1_ZEN_TRAP_NONE);
38 val |= CPACR_EL1_ZEN(CPACR_EL1_ZEN_TRAP_ALL);
39 write_cpacr_el1(val);
40 }
41
42 isb();
43}
44
45static bool is_sve_enabled(void)
46{
47 if (IS_IN_EL2()) {
48 return ((read_cptr_el2() & CPTR_EL2_TZ_BIT) == 0UL);
49 } else {
50 return ((read_cpacr_el1() &
51 CPACR_EL1_ZEN(CPACR_EL1_ZEN_TRAP_NONE)) ==
52 CPACR_EL1_ZEN(CPACR_EL1_ZEN_TRAP_NONE));
53 }
54}
55
56/*
57 * Use Trap control register SVE flags to represent SVE hint bit. On SVE capable
58 * CPU, setting sve_hint_flag = true denotes absence of SVE (disables SVE), else
59 * presence of SVE (enables SVE).
60 */
61void tftf_smc_set_sve_hint(bool sve_hint_flag)
62{
63 if (!is_armv8_2_sve_present()) {
64 return;
65 }
66
67 if (sve_hint_flag) {
68 sve_disable();
69 } else {
70 sve_enable();
71 }
72}
73
74/*
75 * On SVE capable CPU, return value of 'true' denotes SVE not used and return
76 * value of 'false' denotes SVE used.
77 *
78 * If the CPU do not support SVE, always return 'false'.
79 */
80bool tftf_smc_get_sve_hint(void)
81{
82 if (is_armv8_2_sve_present()) {
83 return is_sve_enabled() ? false : true;
84 }
85
86 return false;
87}
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020088
89smc_ret_values tftf_smc(const smc_args *args)
90{
Arunachalam Ganapathy417edca2023-09-05 17:44:24 +010091 uint32_t fid = args->fid;
92
93 if (tftf_smc_get_sve_hint()) {
94 fid |= MASK(FUNCID_SVE_HINT);
95 } else {
96 fid &= ~MASK(FUNCID_SVE_HINT);
97 }
98
Mark Dykesf41d8ee2025-07-10 16:41:28 -050099#ifdef SMC_FUZZ_VARIABLE_COVERAGE
100 tftf_switch_console_state(CONSOLE_FLAG_SMC_FUZZER);
101 printf("SMC FUZZER CALL fid:%x arg1:%lx arg2:%lx arg3:%lx arg4:%lx arg5:%lx arg6:%lx arg7:%lx\n",
102 fid, args->arg1, args->arg2, args->arg3, args->arg4, args->arg5, args->arg6, args->arg7);
103 tftf_switch_console_state(CONSOLE_FLAG_PLAT_UART);
104#endif
Arunachalam Ganapathy417edca2023-09-05 17:44:24 +0100105 return asm_tftf_smc64(fid,
Mark Dykesf41d8ee2025-07-10 16:41:28 -0500106 args->arg1,
107 args->arg2,
108 args->arg3,
109 args->arg4,
110 args->arg5,
111 args->arg6,
112 args->arg7);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200113}
Juan Pablo Condec79338a2024-10-28 18:48:25 -0500114
115void tftf_smc_no_retval_x8(const smc_args_ext *args, smc_ret_values_ext *ret)
116{
117 uint32_t fid = args->fid;
118 /* Copy args into new structure so the fid field can be modified */
119 smc_args_ext args_copy = *args;
120
121 if (tftf_smc_get_sve_hint()) {
122 fid |= MASK(FUNCID_SVE_HINT);
123 } else {
124 fid &= ~MASK(FUNCID_SVE_HINT);
125 }
126 args_copy.fid = fid;
127
128 asm_tftf_smc64_no_retval_x8(&args_copy, ret);
129}