xref: /rk3399_ARM-atf/plat/qti/common/src/qti_syscall.c (revision 7ad4b5ed31e33dca21dd4d2f4a9f64f9b7d4db85)
1 /*
2  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3  * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 #include <errno.h>
8 #include <stdbool.h>
9 #include <stddef.h>
10 #include <stdint.h>
11 #include <string.h>
12 
13 #include <common/debug.h>
14 #include <common/runtime_svc.h>
15 #include <context.h>
16 #include <lib/coreboot.h>
17 #include <lib/utils_def.h>
18 #include <lib/xlat_tables/xlat_tables_v2.h>
19 #include <smccc_helpers.h>
20 #include <tools_share/uuid.h>
21 
22 #include <drivers/qti/accesscontrol/accesscontrol.h>
23 
24 #include <qti_plat.h>
25 #include <qti_secure_io_cfg.h>
26 
27 /*
28  * SIP service - SMC function IDs for SiP Service queries
29  *
30  */
31 #define	QTI_SIP_SVC_CALL_COUNT_ID			U(0x0200ff00)
32 #define	QTI_SIP_SVC_UID_ID				U(0x0200ff01)
33 /*							0x8200ff02 is reserved*/
34 #define	QTI_SIP_SVC_VERSION_ID				U(0x0200ff03)
35 #define QTI_SIP_SVC_AVAILABLE_ID			U(0x02000601)
36 /*
37  * Syscall's to allow Non Secure world accessing peripheral/IO memory
38  * those are secure/proteced BUT not required to be secure.
39  */
40 #define	QTI_SIP_SVC_SECURE_IO_READ_ID		U(0x02000501)
41 #define	QTI_SIP_SVC_SECURE_IO_WRITE_ID		U(0x02000502)
42 
43 /*
44  * Syscall's to assigns a list of intermediate PAs from a
45  * source Virtual Machine (VM) to a destination VM.
46  */
47 #define	QTI_SIP_SVC_MEM_ASSIGN_ID		U(0x02000C16)
48 
49 #define	QTI_SIP_SVC_SECURE_IO_READ_PARAM_ID	U(0x1)
50 #define	QTI_SIP_SVC_SECURE_IO_WRITE_PARAM_ID	U(0x2)
51 #define	QTI_SIP_SVC_MEM_ASSIGN_PARAM_ID		U(0x1117)
52 
53 #define	QTI_SIP_SVC_CALL_COUNT			U(0x3)
54 #define QTI_SIP_SVC_VERSION_MAJOR		U(0x0)
55 #define	QTI_SIP_SVC_VERSION_MINOR		U(0x0)
56 
57 #define QTI_VM_LAST				U(44)
58 #define SIZE4K					U(0x1000)
59 #define QTI_VM_MAX_LIST_SIZE			U(0x20)
60 
61 #define	FUNCID_OEN_NUM_MASK	((FUNCID_OEN_MASK << FUNCID_OEN_SHIFT)\
62 				|(FUNCID_NUM_MASK << FUNCID_NUM_SHIFT))
63 
64 struct qti_mmap_params {
65 	qti_accesscontrol_mem_t mem[QTI_VM_MAX_LIST_SIZE];
66 	u_register_t mem_cnt;
67 	qti_accesscontrol_perm_t dst[QTI_VM_LAST];
68 	u_register_t dst_cnt;
69 	uint32_t src[QTI_VM_LAST];
70 	u_register_t src_cnt;
71 };
72 
73 enum {
74 	QTI_SIP_SUCCESS = 0,
75 	QTI_SIP_NOT_SUPPORTED = -1,
76 	QTI_SIP_PREEMPTED = -2,
77 	QTI_SIP_INVALID_PARAM = -3,
78 };
79 
80 /* QTI SiP Service UUID */
81 DEFINE_SVC_UUID2(qti_sip_svc_uid,
82 		 0x43864748, 0x217f, 0x41ad, 0xaa, 0x5a,
83 		 0xba, 0xe7, 0x0f, 0xa5, 0x52, 0xaf);
84 
85 static bool qti_is_secure_io_access_allowed(u_register_t addr)
86 {
87 	int i = 0;
88 
89 	for (i = 0; i < ARRAY_SIZE(qti_secure_io_allowed_regs); i++) {
90 		if ((uintptr_t) addr == qti_secure_io_allowed_regs[i]) {
91 			return true;
92 		}
93 	}
94 
95 	return false;
96 }
97 
98 static bool qti_check_syscall_availability(u_register_t smc_fid)
99 {
100 	switch (smc_fid) {
101 	case QTI_SIP_SVC_CALL_COUNT_ID:
102 	case QTI_SIP_SVC_UID_ID:
103 	case QTI_SIP_SVC_VERSION_ID:
104 	case QTI_SIP_SVC_AVAILABLE_ID:
105 	case QTI_SIP_SVC_SECURE_IO_READ_ID:
106 	case QTI_SIP_SVC_SECURE_IO_WRITE_ID:
107 	case QTI_SIP_SVC_MEM_ASSIGN_ID:
108 		return true;
109 	default:
110 		return false;
111 	}
112 }
113 
114 static bool qti_mem_assign_validate_param(qti_accesscontrol_mem_t *mem_info,
115 					  u_register_t u_num_mappings,
116 					  uint32_t *src_vm_list,
117 					  u_register_t src_vm_list_cnt,
118 					  qti_accesscontrol_perm_t *dst_vm_list,
119 					  u_register_t dst_vm_list_cnt)
120 {
121 	u_register_t end;
122 	int i;
123 
124 	if ((src_vm_list == NULL) || (dst_vm_list == NULL)
125 	    || (mem_info == NULL) || (src_vm_list_cnt == 0)
126 	    || (src_vm_list_cnt >= QTI_VM_LAST) || (dst_vm_list_cnt == 0)
127 	    || (dst_vm_list_cnt >= QTI_VM_LAST) || (u_num_mappings == 0)
128 	    || u_num_mappings > QTI_VM_MAX_LIST_SIZE) {
129 		ERROR("vm count is 0 or more then QTI_VM_LAST or empty list\n");
130 		ERROR("src_vm_list %p dst_vm_list %p mem_info %p src_vm_list_cnt %u dst_vm_list_cnt %u u_num_mappings %u\n",
131 		     src_vm_list, dst_vm_list, mem_info,
132 		     (unsigned int)src_vm_list_cnt,
133 		     (unsigned int)dst_vm_list_cnt,
134 		     (unsigned int)u_num_mappings);
135 		return false;
136 	}
137 
138 	for (i = 0; i < u_num_mappings; i++) {
139 		if (((mem_info[i].mem_addr & (SIZE4K - 1)) != 0)
140 		    || (mem_info[i].mem_size == 0)
141 		    || ((mem_info[i].mem_size & (SIZE4K - 1)) != 0)) {
142 			ERROR("mem_info passed buffer 0x%x or size 0x%x is not 4k aligned\n",
143 			     (unsigned int)mem_info[i].mem_addr,
144 			     (unsigned int)mem_info[i].mem_size);
145 			return false;
146 		}
147 
148 		if (add_overflow(mem_info[i].mem_addr, mem_info[i].mem_size,
149 				 &end) != 0) {
150 			ERROR("overflow in mem_addr 0x%x add mem_size 0x%x\n",
151 			      (unsigned int)mem_info[i].mem_addr,
152 			      (unsigned int)mem_info[i].mem_size);
153 			return false;
154 		}
155 
156 #if COREBOOT == 1
157 		coreboot_memory_t mem_type = coreboot_get_memory_type(
158 						mem_info[i].mem_addr,
159 						mem_info[i].mem_size);
160 		if (mem_type != CB_MEM_RAM && mem_type != CB_MEM_RESERVED) {
161 			ERROR("memory region not in CB MEM RAM or RESERVED area: region start 0x%x size 0x%x\n",
162 			     (unsigned int)mem_info[i].mem_addr,
163 			     (unsigned int)mem_info[i].mem_size);
164 			return false;
165 		}
166 #endif
167 	}
168 	for (i = 0; i < src_vm_list_cnt; i++) {
169 		if (src_vm_list[i] >= QTI_VM_LAST) {
170 			ERROR("src_vm_list[%d] 0x%x is more then QTI_VM_LAST\n",
171 			      i, (unsigned int)src_vm_list[i]);
172 			return false;
173 		}
174 	}
175 	for (i = 0; i < dst_vm_list_cnt; i++) {
176 		if (dst_vm_list[i].dst_vm >= QTI_VM_LAST) {
177 			ERROR("dst_vm_list[%d] 0x%x is more then QTI_VM_LAST\n",
178 			      i, (unsigned int)dst_vm_list[i].dst_vm);
179 			return false;
180 		}
181 	}
182 	return true;
183 }
184 
185 static int get_indirect_args(uint32_t smccc, u_register_t *x5, u_register_t *x6,
186 			     u_register_t *x7)
187 {
188 	const uintptr_t addr = (uintptr_t)*x5;
189 	int ret = -EPERM;
190 	size_t len = 0;
191 
192 	if (smccc == SMC_32) {
193 		len = sizeof(uint32_t) * 4;
194 	} else {
195 		len = sizeof(uint64_t) * 4;
196 	}
197 
198 	ret = qti_mmap_add_dynamic_region(addr, len, MT_NS | MT_RO_DATA);
199 	if (ret != 0) {
200 		ERROR("map failed for params NS Buffer 0x%lx 0x%lx\n",
201 		      (unsigned long)addr, (unsigned long)len);
202 		return ret;
203 	}
204 
205 	if (smccc == SMC_32) {
206 		const uint32_t *args = (const uint32_t *)addr;
207 
208 		*x5 = args[0];
209 		*x6 = args[1];
210 		*x7 = args[2];
211 	} else {
212 		const uint64_t *args = (const uint64_t *)addr;
213 
214 		*x5 = args[0];
215 		*x6 = args[1];
216 		*x7 = args[2];
217 	}
218 
219 	ret = qti_mmap_remove_dynamic_region(addr, len);
220 	if (ret != 0) {
221 		ERROR("unmap failed for params NS Buffer 0x%lx 0x%lx\n",
222 		      (unsigned long)addr, (unsigned long)len);
223 	}
224 
225 	return ret;
226 }
227 
228 static int get_mem_params(struct qti_mmap_params *params,
229 			  u_register_t x2, u_register_t x3, u_register_t x4,
230 			  u_register_t x5, u_register_t x6, u_register_t x7)
231 {
232 	u_register_t e2, e4, e6;
233 	u_register_t start = 0;
234 	u_register_t end = 0;
235 	u_register_t len = 0;
236 	bool rc = false;
237 	int ret = -EINVAL;
238 	int ret1 = -EINVAL;
239 
240 	/* Overflow check:
241 	 *   args 2,4,6 contain buffer addresses
242 	 *   args 3,5,7 contain buffer sizes
243 	 */
244 	if (x2 == 0 || x4 == 0 || x6 == 0) {
245 		return -EINVAL;
246 	}
247 
248 	if (add_overflow(x2, x3, &e2) != 0 ||
249 	    add_overflow(x4, x5, &e4) != 0 ||
250 	    add_overflow(x6, x7, &e6) != 0) {
251 		ERROR("map failed for params NS Buffer2, invalid params\n");
252 		return -EINVAL;
253 	}
254 
255 	start = MIN(x2, x4);
256 	start = MIN(start, x6);
257 	end = MAX(e2, e4);
258 	end = MAX(end, e6);
259 	len = end - start;
260 
261 	ret = qti_mmap_add_dynamic_region((uintptr_t)start, (size_t)len,
262 					  (MT_NS | MT_RO_DATA));
263 	if (ret != 0) {
264 		ERROR("map failed for params NS Buffer2 0x%lx 0x%lx\n",
265 		      (unsigned long)start, (unsigned long)len);
266 		return ret;
267 	}
268 
269 	/* Parameter validation */
270 	ret = -EINVAL;
271 
272 	if ((x3 % sizeof(qti_accesscontrol_mem_t)) != 0U ||
273 	    (x5 % sizeof(uint32_t)) != 0U ||
274 	    (x7 % sizeof(qti_accesscontrol_perm_t)) != 0U) {
275 		ERROR("invalid parameter buffer sizes\n");
276 		goto error;
277 	}
278 
279 	params->mem_cnt = x3 / sizeof(params->mem[0]);
280 	if (params->mem_cnt > ARRAY_SIZE(params->mem)) {
281 		ERROR("Param validation failed\n");
282 		goto error;
283 	}
284 	memcpy(params->mem, (void *)(uintptr_t)x2,
285 	       params->mem_cnt * sizeof(params->mem[0]));
286 
287 	params->src_cnt = x5 / sizeof(params->src[0]);
288 	if (params->src_cnt >= ARRAY_SIZE(params->src)) {
289 		ERROR("Param validation failed\n");
290 		goto error;
291 	}
292 	memcpy(params->src, (void *)(uintptr_t)x4,
293 	       params->src_cnt * sizeof(params->src[0]));
294 
295 	params->dst_cnt = x7 / sizeof(params->dst[0]);
296 	if (params->dst_cnt >= ARRAY_SIZE(params->dst)) {
297 		ERROR("Param validation failed\n");
298 		goto error;
299 	}
300 	memcpy(params->dst, (void *)(uintptr_t)x6,
301 	       params->dst_cnt * sizeof(params->dst[0]));
302 
303 	rc = qti_mem_assign_validate_param(params->mem, params->mem_cnt,
304 					   params->src, params->src_cnt,
305 					   params->dst, params->dst_cnt);
306 	if (rc != true) {
307 		ERROR("Param validation failed\n");
308 	}
309 
310 	ret = rc == true ? 0 : -EINVAL;
311 error:
312 	ret1 = qti_mmap_remove_dynamic_region((uintptr_t)start, (size_t)len);
313 	if (ret1 != 0) {
314 		ERROR("unmap failed for params NS Buffer 0x%lx 0x%lx\n",
315 		      (unsigned long)start, (unsigned long)len);
316 	}
317 
318 	return ret ? ret : ret1;
319 }
320 
321 
322 static uintptr_t qti_sip_mem_assign(void *handle, uint32_t smc_cc,
323 				    u_register_t x1,
324 				    u_register_t x2,
325 				    u_register_t x3, u_register_t x4)
326 {
327 	struct qti_mmap_params params = { 0 };
328 	int ret = QTI_SIP_NOT_SUPPORTED;
329 	u_register_t x5, x6, x7;
330 
331 	if (x1 != QTI_SIP_SVC_MEM_ASSIGN_PARAM_ID) {
332 		ERROR("invalid mem_assign param id\n");
333 		goto out;
334 	}
335 
336 	x5 = read_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X5);
337 	if (x5 == 0x0) {
338 		ERROR("no mem_assign mapping info\n");
339 		goto out;
340 	}
341 
342 	if (smc_cc == SMC_32) {
343 		x5 = (uint32_t)x5;
344 	}
345 
346 	ret = get_indirect_args(smc_cc, &x5, &x6, &x7);
347 	if (ret != 0)
348 		goto out;
349 
350 	ret = get_mem_params(&params, x2, x3, x4, x5, x6, x7);
351 	if (ret != 0)
352 		goto out;
353 
354 	ret = qti_accesscontrol_mem_assign(params.mem, params.mem_cnt,
355 					   params.src, params.src_cnt,
356 					   params.dst, params.dst_cnt);
357 out:
358 	SMC_RET2(handle, ret == 0 ? QTI_SIP_SUCCESS : QTI_SIP_INVALID_PARAM,
359 		 ret);
360 }
361 
362 /*
363  * This function handles QTI specific syscalls. Currently only SiP calls are present.
364  * Both FAST & YIELD type call land here.
365  */
366 static uintptr_t qti_sip_handler(uint32_t smc_fid,
367 				 u_register_t x1,
368 				 u_register_t x2,
369 				 u_register_t x3,
370 				 u_register_t x4,
371 				 void *cookie, void *handle, u_register_t flags)
372 {
373 	uint32_t l_smc_fid = smc_fid & FUNCID_OEN_NUM_MASK;
374 
375 	if (GET_SMC_CC(smc_fid) == SMC_32) {
376 		x1 = (uint32_t) x1;
377 		x2 = (uint32_t) x2;
378 		x3 = (uint32_t) x3;
379 		x4 = (uint32_t) x4;
380 	}
381 
382 	switch (l_smc_fid) {
383 	case QTI_SIP_SVC_CALL_COUNT_ID:
384 		{
385 			SMC_RET1(handle, QTI_SIP_SVC_CALL_COUNT);
386 			break;
387 		}
388 	case QTI_SIP_SVC_UID_ID:
389 		{
390 			/* Return UID to the caller */
391 			SMC_UUID_RET(handle, qti_sip_svc_uid);
392 			break;
393 		}
394 	case QTI_SIP_SVC_VERSION_ID:
395 		{
396 			/* Return the version of current implementation */
397 			SMC_RET2(handle, QTI_SIP_SVC_VERSION_MAJOR,
398 				 QTI_SIP_SVC_VERSION_MINOR);
399 			break;
400 		}
401 	case QTI_SIP_SVC_AVAILABLE_ID:
402 		{
403 			if (x1 != 1) {
404 				SMC_RET1(handle, QTI_SIP_INVALID_PARAM);
405 			}
406 			if (qti_check_syscall_availability(x2) == true) {
407 				SMC_RET2(handle, QTI_SIP_SUCCESS, 1);
408 			} else {
409 				SMC_RET2(handle, QTI_SIP_SUCCESS, 0);
410 			}
411 			break;
412 		}
413 	case QTI_SIP_SVC_SECURE_IO_READ_ID:
414 		{
415 			if ((x1 == QTI_SIP_SVC_SECURE_IO_READ_PARAM_ID) &&
416 			    qti_is_secure_io_access_allowed(x2)) {
417 				SMC_RET2(handle, QTI_SIP_SUCCESS,
418 					 *((volatile uint32_t *)x2));
419 			}
420 			SMC_RET1(handle, QTI_SIP_INVALID_PARAM);
421 			break;
422 		}
423 	case QTI_SIP_SVC_SECURE_IO_WRITE_ID:
424 		{
425 			if ((x1 == QTI_SIP_SVC_SECURE_IO_WRITE_PARAM_ID) &&
426 			    qti_is_secure_io_access_allowed(x2)) {
427 				*((volatile uint32_t *)x2) = x3;
428 				SMC_RET1(handle, QTI_SIP_SUCCESS);
429 			}
430 			SMC_RET1(handle, QTI_SIP_INVALID_PARAM);
431 			break;
432 		}
433 	case QTI_SIP_SVC_MEM_ASSIGN_ID:
434 		{
435 			return qti_sip_mem_assign(handle, GET_SMC_CC(smc_fid),
436 						  x1, x2, x3, x4);
437 			break;
438 		}
439 	default:
440 		{
441 			SMC_RET1(handle, QTI_SIP_NOT_SUPPORTED);
442 		}
443 	}
444 	return (uintptr_t) handle;
445 }
446 
447 /* Define a runtime service descriptor for both fast & yield SiP calls */
448 DECLARE_RT_SVC(qti_sip_fast_svc, OEN_SIP_START,
449 	       OEN_SIP_END, SMC_TYPE_FAST, NULL, qti_sip_handler);
450 
451 DECLARE_RT_SVC(qti_sip_yield_svc, OEN_SIP_START,
452 	       OEN_SIP_END, SMC_TYPE_YIELD, NULL, qti_sip_handler);
453