• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  */
13 #include <linux/arm-smccc.h>
14 #include "smc_call.h"
15 #include "smc_smp.h"
16 #include "teek_ns_client.h"
17 #include "smc_abi.h"
18 
19 #ifndef CONFIG_ARCH32
do_smc_transport(struct smc_in_params * in,struct smc_out_params * out,uint8_t wait)20 void do_smc_transport(struct smc_in_params *in, struct smc_out_params *out, uint8_t wait)
21 {
22 	isb();
23 	wmb();
24 	do {
25 		asm volatile(
26 			"mov x0, %[fid]\n"
27 			"mov x1, %[a1]\n"
28 			"mov x2, %[a2]\n"
29 			"mov x3, %[a3]\n"
30 			"mov x4, %[a4]\n"
31 			"mov x5, %[a5]\n"
32 			"mov x6, %[a6]\n"
33 			"mov x7, %[a7]\n"
34 			SMCCC_SMC_INST"\n"
35 			"str x0, [%[re0]]\n"
36 			"str x1, [%[re1]]\n"
37 			"str x2, [%[re2]]\n"
38 			"str x3, [%[re3]]\n" :
39 			[fid] "+r"(in->x0),
40 			[a1] "+r"(in->x1),
41 			[a2] "+r"(in->x2),
42 			[a3] "+r"(in->x3),
43 			[a4] "+r"(in->x4),
44 			[a5] "+r"(in->x5),
45 			[a6] "+r"(in->x6),
46 			[a7] "+r"(in->x7):
47 			[re0] "r"(&out->ret),
48 			[re1] "r"(&out->exit_reason),
49 			[re2] "r"(&out->ta),
50 			[re3] "r"(&out->target) :
51 			"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7");
52 	} while (out->ret == TSP_REQUEST && wait != 0);
53 	isb();
54 	wmb();
55 }
56 #else
do_smc_transport(struct smc_in_params * in,struct smc_out_params * out,uint8_t wait)57 void do_smc_transport(struct smc_in_params *in, struct smc_out_params *out, uint8_t wait)
58 {
59 	isb();
60 	wmb();
61 	do {
62 		asm volatile(
63 			"mov r0, %[fid]\n"
64 			"mov r1, %[a1]\n"
65 			"mov r2, %[a2]\n"
66 			"mov r3, %[a3]\n"
67 			".arch_extension sec\n"
68 			SMCCC_SMC_INST"\n"
69 			"str r0, [%[re0]]\n"
70 			"str r1, [%[re1]]\n"
71 			"str r2, [%[re2]]\n"
72 			"str r3, [%[re3]]\n" :
73 			[fid] "+r"(in->x0),
74 			[a1] "+r"(in->x1),
75 			[a2] "+r"(in->x2),
76 			[a3] "+r"(in->x3):
77 			[re0] "r"(&out->ret),
78 			[re1] "r"(&out->exit_reason),
79 			[re2] "r"(&out->ta),
80 			[re3] "r"(&out->target) :
81 			"r0", "r1", "r2", "r3");
82 	} while (out->ret == TSP_REQUEST && wait != 0);
83 	isb();
84 	wmb();
85 }
86 #endif
87 
88 #ifdef CONFIG_THIRDPARTY_COMPATIBLE
fix_params_offset(struct smc_out_params * out_param)89 static void fix_params_offset(struct smc_out_params *out_param)
90 {
91 	out_param->target = out_param->ta;
92 	out_param->ta = out_param->exit_reason;
93 	out_param->exit_reason = out_param->ret;
94 	out_param->ret = TSP_RESPONSE;
95 	if (out_param->exit_reason == TEE_EXIT_REASON_CRASH) {
96 		union crash_inf temp_info;
97 		temp_info.crash_reg[0] = out_param->ta;
98 		temp_info.crash_reg[1] = 0;
99 		temp_info.crash_reg[2] = out_param->target;
100 		temp_info.crash_msg.far = temp_info.crash_msg.elr;
101 		temp_info.crash_msg.elr = 0;
102 		out_param->ret = TSP_CRASH;
103 		out_param->exit_reason = temp_info.crash_reg[0];
104 		out_param->ta = temp_info.crash_reg[1];
105 		out_param->target = temp_info.crash_reg[2];
106 	}
107 }
108 #endif
109 
smc_req(struct smc_in_params * in,struct smc_out_params * out,uint8_t wait)110 void smc_req(struct smc_in_params *in, struct smc_out_params *out, uint8_t wait)
111 {
112 	do_smc_transport(in, out, wait);
113 #ifdef CONFIG_THIRDPARTY_COMPATIBLE
114 	fix_params_offset(out);
115 #endif
116 }
117