xref: /rk3399_ARM-atf/plat/qti/common/src/qti_syscall.c (revision 5bd9c17d023288e6b819fa3eecc01b7981399cfa)
1*5bd9c17dSSaurabh Gorecha /*
2*5bd9c17dSSaurabh Gorecha  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3*5bd9c17dSSaurabh Gorecha  * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
4*5bd9c17dSSaurabh Gorecha  *
5*5bd9c17dSSaurabh Gorecha  * SPDX-License-Identifier: BSD-3-Clause
6*5bd9c17dSSaurabh Gorecha  */
7*5bd9c17dSSaurabh Gorecha #include <stdbool.h>
8*5bd9c17dSSaurabh Gorecha #include <stddef.h>
9*5bd9c17dSSaurabh Gorecha #include <stdint.h>
10*5bd9c17dSSaurabh Gorecha #include <string.h>
11*5bd9c17dSSaurabh Gorecha 
12*5bd9c17dSSaurabh Gorecha #include <common/debug.h>
13*5bd9c17dSSaurabh Gorecha #include <common/runtime_svc.h>
14*5bd9c17dSSaurabh Gorecha #include <context.h>
15*5bd9c17dSSaurabh Gorecha #include <lib/coreboot.h>
16*5bd9c17dSSaurabh Gorecha #include <lib/utils_def.h>
17*5bd9c17dSSaurabh Gorecha #include <lib/xlat_tables/xlat_tables_v2.h>
18*5bd9c17dSSaurabh Gorecha #include <smccc_helpers.h>
19*5bd9c17dSSaurabh Gorecha #include <tools_share/uuid.h>
20*5bd9c17dSSaurabh Gorecha 
21*5bd9c17dSSaurabh Gorecha #include <qti_plat.h>
22*5bd9c17dSSaurabh Gorecha #include <qti_secure_io_cfg.h>
23*5bd9c17dSSaurabh Gorecha #include <qtiseclib_interface.h>
24*5bd9c17dSSaurabh Gorecha /*
25*5bd9c17dSSaurabh Gorecha  * SIP service - SMC function IDs for SiP Service queries
26*5bd9c17dSSaurabh Gorecha  *
27*5bd9c17dSSaurabh Gorecha  */
28*5bd9c17dSSaurabh Gorecha #define	QTI_SIP_SVC_CALL_COUNT_ID			U(0x0200ff00)
29*5bd9c17dSSaurabh Gorecha #define	QTI_SIP_SVC_UID_ID				U(0x0200ff01)
30*5bd9c17dSSaurabh Gorecha /*							0x8200ff02 is reserved */
31*5bd9c17dSSaurabh Gorecha #define	QTI_SIP_SVC_VERSION_ID				U(0x0200ff03)
32*5bd9c17dSSaurabh Gorecha 
33*5bd9c17dSSaurabh Gorecha /*
34*5bd9c17dSSaurabh Gorecha  * Syscall's to allow Non Secure world accessing peripheral/IO memory
35*5bd9c17dSSaurabh Gorecha  * those are secure/proteced BUT not required to be secure.
36*5bd9c17dSSaurabh Gorecha  */
37*5bd9c17dSSaurabh Gorecha #define	QTI_SIP_SVC_SECURE_IO_READ_ID		U(0x02000501)
38*5bd9c17dSSaurabh Gorecha #define	QTI_SIP_SVC_SECURE_IO_WRITE_ID		U(0x02000502)
39*5bd9c17dSSaurabh Gorecha 
40*5bd9c17dSSaurabh Gorecha /*
41*5bd9c17dSSaurabh Gorecha  * Syscall's to assigns a list of intermediate PAs from a
42*5bd9c17dSSaurabh Gorecha  * source Virtual Machine (VM) to a destination VM.
43*5bd9c17dSSaurabh Gorecha  */
44*5bd9c17dSSaurabh Gorecha #define	QTI_SIP_SVC_MEM_ASSIGN_ID		U(0x02000C16)
45*5bd9c17dSSaurabh Gorecha 
46*5bd9c17dSSaurabh Gorecha #define	QTI_SIP_SVC_SECURE_IO_READ_PARAM_ID	U(0x1)
47*5bd9c17dSSaurabh Gorecha #define	QTI_SIP_SVC_SECURE_IO_WRITE_PARAM_ID	U(0x2)
48*5bd9c17dSSaurabh Gorecha #define	QTI_SIP_SVC_MEM_ASSIGN_PARAM_ID		U(0x1117)
49*5bd9c17dSSaurabh Gorecha 
50*5bd9c17dSSaurabh Gorecha #define	QTI_SIP_SVC_CALL_COUNT			U(0x3)
51*5bd9c17dSSaurabh Gorecha #define QTI_SIP_SVC_VERSION_MAJOR		U(0x0)
52*5bd9c17dSSaurabh Gorecha #define	QTI_SIP_SVC_VERSION_MINOR		U(0x0)
53*5bd9c17dSSaurabh Gorecha 
54*5bd9c17dSSaurabh Gorecha #define QTI_VM_LAST				U(44)
55*5bd9c17dSSaurabh Gorecha #define SIZE4K					U(0x1000)
56*5bd9c17dSSaurabh Gorecha #define QTI_VM_MAX_LIST_SIZE			U(0x20)
57*5bd9c17dSSaurabh Gorecha 
58*5bd9c17dSSaurabh Gorecha #define	FUNCID_OEN_NUM_MASK	((FUNCID_OEN_MASK << FUNCID_OEN_SHIFT)\
59*5bd9c17dSSaurabh Gorecha 				|(FUNCID_NUM_MASK << FUNCID_NUM_SHIFT))
60*5bd9c17dSSaurabh Gorecha 
61*5bd9c17dSSaurabh Gorecha enum {
62*5bd9c17dSSaurabh Gorecha 	QTI_SIP_SUCCESS = 0,
63*5bd9c17dSSaurabh Gorecha 	QTI_SIP_NOT_SUPPORTED = -1,
64*5bd9c17dSSaurabh Gorecha 	QTI_SIP_PREEMPTED = -2,
65*5bd9c17dSSaurabh Gorecha 	QTI_SIP_INVALID_PARAM = -3,
66*5bd9c17dSSaurabh Gorecha };
67*5bd9c17dSSaurabh Gorecha 
68*5bd9c17dSSaurabh Gorecha /* QTI SiP Service UUID */
69*5bd9c17dSSaurabh Gorecha DEFINE_SVC_UUID2(qti_sip_svc_uid,
70*5bd9c17dSSaurabh Gorecha 		 0x43864748, 0x217f, 0x41ad, 0xaa, 0x5a,
71*5bd9c17dSSaurabh Gorecha 		 0xba, 0xe7, 0x0f, 0xa5, 0x52, 0xaf);
72*5bd9c17dSSaurabh Gorecha 
73*5bd9c17dSSaurabh Gorecha static bool qti_is_secure_io_access_allowed(u_register_t addr)
74*5bd9c17dSSaurabh Gorecha {
75*5bd9c17dSSaurabh Gorecha 	int i = 0;
76*5bd9c17dSSaurabh Gorecha 
77*5bd9c17dSSaurabh Gorecha 	for (i = 0; i < ARRAY_SIZE(qti_secure_io_allowed_regs); i++) {
78*5bd9c17dSSaurabh Gorecha 		if ((uintptr_t) addr == qti_secure_io_allowed_regs[i]) {
79*5bd9c17dSSaurabh Gorecha 			return true;
80*5bd9c17dSSaurabh Gorecha 		}
81*5bd9c17dSSaurabh Gorecha 	}
82*5bd9c17dSSaurabh Gorecha 
83*5bd9c17dSSaurabh Gorecha 	return false;
84*5bd9c17dSSaurabh Gorecha }
85*5bd9c17dSSaurabh Gorecha 
86*5bd9c17dSSaurabh Gorecha bool qti_mem_assign_validate_param(memprot_info_t *mem_info,
87*5bd9c17dSSaurabh Gorecha 				   u_register_t u_num_mappings,
88*5bd9c17dSSaurabh Gorecha 				   uint32_t *source_vm_list,
89*5bd9c17dSSaurabh Gorecha 				   u_register_t src_vm_list_cnt,
90*5bd9c17dSSaurabh Gorecha 				   memprot_dst_vm_perm_info_t *dest_vm_list,
91*5bd9c17dSSaurabh Gorecha 				   u_register_t dst_vm_list_cnt)
92*5bd9c17dSSaurabh Gorecha {
93*5bd9c17dSSaurabh Gorecha 	int i;
94*5bd9c17dSSaurabh Gorecha 
95*5bd9c17dSSaurabh Gorecha 	if (!source_vm_list || !dest_vm_list || !mem_info
96*5bd9c17dSSaurabh Gorecha 	    || (src_vm_list_cnt == 0)
97*5bd9c17dSSaurabh Gorecha 	    || (src_vm_list_cnt >= QTI_VM_LAST) || (dst_vm_list_cnt == 0)
98*5bd9c17dSSaurabh Gorecha 	    || (dst_vm_list_cnt >= QTI_VM_LAST) || (u_num_mappings == 0)
99*5bd9c17dSSaurabh Gorecha 	    || u_num_mappings > QTI_VM_MAX_LIST_SIZE) {
100*5bd9c17dSSaurabh Gorecha 		return false;
101*5bd9c17dSSaurabh Gorecha 	}
102*5bd9c17dSSaurabh Gorecha 	for (i = 0; i < u_num_mappings; i++) {
103*5bd9c17dSSaurabh Gorecha 		if ((mem_info[i].mem_addr & (SIZE4K - 1))
104*5bd9c17dSSaurabh Gorecha 		    || (mem_info[i].mem_size & (SIZE4K - 1))) {
105*5bd9c17dSSaurabh Gorecha 			return false;
106*5bd9c17dSSaurabh Gorecha 		}
107*5bd9c17dSSaurabh Gorecha 
108*5bd9c17dSSaurabh Gorecha 		if ((mem_info[i].mem_addr + mem_info[i].mem_size) <
109*5bd9c17dSSaurabh Gorecha 		    mem_info[i].mem_addr) {
110*5bd9c17dSSaurabh Gorecha 			return false;
111*5bd9c17dSSaurabh Gorecha 		}
112*5bd9c17dSSaurabh Gorecha 		if (coreboot_get_memory_type(mem_info[i].mem_addr) !=
113*5bd9c17dSSaurabh Gorecha 		    CB_MEM_RAM) {
114*5bd9c17dSSaurabh Gorecha 			return false;
115*5bd9c17dSSaurabh Gorecha 		}
116*5bd9c17dSSaurabh Gorecha 
117*5bd9c17dSSaurabh Gorecha 		if (coreboot_get_memory_type
118*5bd9c17dSSaurabh Gorecha 		    (mem_info[i].mem_addr + mem_info[i].mem_size) !=
119*5bd9c17dSSaurabh Gorecha 		    CB_MEM_RAM) {
120*5bd9c17dSSaurabh Gorecha 			return false;
121*5bd9c17dSSaurabh Gorecha 		}
122*5bd9c17dSSaurabh Gorecha 
123*5bd9c17dSSaurabh Gorecha 	}
124*5bd9c17dSSaurabh Gorecha 	for (i = 0; i < src_vm_list_cnt; i++) {
125*5bd9c17dSSaurabh Gorecha 		if (source_vm_list[i] >= QTI_VM_LAST) {
126*5bd9c17dSSaurabh Gorecha 			return false;
127*5bd9c17dSSaurabh Gorecha 		}
128*5bd9c17dSSaurabh Gorecha 	}
129*5bd9c17dSSaurabh Gorecha 	for (i = 0; i < dst_vm_list_cnt; i++) {
130*5bd9c17dSSaurabh Gorecha 		if (dest_vm_list[i].dst_vm >= QTI_VM_LAST) {
131*5bd9c17dSSaurabh Gorecha 			return false;
132*5bd9c17dSSaurabh Gorecha 		}
133*5bd9c17dSSaurabh Gorecha 	}
134*5bd9c17dSSaurabh Gorecha 	return true;
135*5bd9c17dSSaurabh Gorecha }
136*5bd9c17dSSaurabh Gorecha 
137*5bd9c17dSSaurabh Gorecha static uintptr_t qti_sip_mem_assign(void *handle, uint32_t smc_cc,
138*5bd9c17dSSaurabh Gorecha 				    u_register_t x1,
139*5bd9c17dSSaurabh Gorecha 				    u_register_t x2,
140*5bd9c17dSSaurabh Gorecha 				    u_register_t x3, u_register_t x4)
141*5bd9c17dSSaurabh Gorecha {
142*5bd9c17dSSaurabh Gorecha 	uintptr_t dyn_map_start = 0, dyn_map_end = 0;
143*5bd9c17dSSaurabh Gorecha 	size_t dyn_map_size = 0;
144*5bd9c17dSSaurabh Gorecha 	u_register_t x6, x7;
145*5bd9c17dSSaurabh Gorecha 	int ret = QTI_SIP_NOT_SUPPORTED;
146*5bd9c17dSSaurabh Gorecha 	u_register_t x5 = read_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X5);
147*5bd9c17dSSaurabh Gorecha 
148*5bd9c17dSSaurabh Gorecha 	if (smc_cc == SMC_32) {
149*5bd9c17dSSaurabh Gorecha 		x5 = (uint32_t) x5;
150*5bd9c17dSSaurabh Gorecha 	}
151*5bd9c17dSSaurabh Gorecha 	/* Validate input arg count & retrieve arg3-6 from NS Buffer. */
152*5bd9c17dSSaurabh Gorecha 	if ((x1 != QTI_SIP_SVC_MEM_ASSIGN_PARAM_ID) || (x5 == 0x0)) {
153*5bd9c17dSSaurabh Gorecha 		goto unmap_return;
154*5bd9c17dSSaurabh Gorecha 	}
155*5bd9c17dSSaurabh Gorecha 
156*5bd9c17dSSaurabh Gorecha 	/* Map NS Buffer. */
157*5bd9c17dSSaurabh Gorecha 	dyn_map_start = x5;
158*5bd9c17dSSaurabh Gorecha 	dyn_map_size =
159*5bd9c17dSSaurabh Gorecha 		(smc_cc ==
160*5bd9c17dSSaurabh Gorecha 		 SMC_32) ? (sizeof(uint32_t) * 4) : (sizeof(uint64_t) * 4);
161*5bd9c17dSSaurabh Gorecha 	if (qti_mmap_add_dynamic_region(dyn_map_start, dyn_map_size,
162*5bd9c17dSSaurabh Gorecha 				(MT_NS | MT_RO_DATA)) != 0) {
163*5bd9c17dSSaurabh Gorecha 		goto unmap_return;
164*5bd9c17dSSaurabh Gorecha 	}
165*5bd9c17dSSaurabh Gorecha 	/* Retrieve indirect args. */
166*5bd9c17dSSaurabh Gorecha 	if (smc_cc == SMC_32) {
167*5bd9c17dSSaurabh Gorecha 		x6 = *((uint32_t *) x5 + 1);
168*5bd9c17dSSaurabh Gorecha 		x7 = *((uint32_t *) x5 + 2);
169*5bd9c17dSSaurabh Gorecha 		x5 = *(uint32_t *) x5;
170*5bd9c17dSSaurabh Gorecha 	} else {
171*5bd9c17dSSaurabh Gorecha 		x6 = *((uint64_t *) x5 + 1);
172*5bd9c17dSSaurabh Gorecha 		x7 = *((uint64_t *) x5 + 2);
173*5bd9c17dSSaurabh Gorecha 		x5 = *(uint64_t *) x5;
174*5bd9c17dSSaurabh Gorecha 	}
175*5bd9c17dSSaurabh Gorecha 	/* Un-Map NS Buffer. */
176*5bd9c17dSSaurabh Gorecha 	if (qti_mmap_remove_dynamic_region(dyn_map_start, dyn_map_size) != 0) {
177*5bd9c17dSSaurabh Gorecha 		goto unmap_return;
178*5bd9c17dSSaurabh Gorecha 	}
179*5bd9c17dSSaurabh Gorecha 
180*5bd9c17dSSaurabh Gorecha 	/*
181*5bd9c17dSSaurabh Gorecha 	 * Map NS Buffers.
182*5bd9c17dSSaurabh Gorecha 	 * arg0,2,4 points to buffers & arg1,3,5 hold sizes.
183*5bd9c17dSSaurabh Gorecha 	 * MAP api's fail to map if it's already mapped. Let's
184*5bd9c17dSSaurabh Gorecha 	 * find lowest start & highest end address, then map once.
185*5bd9c17dSSaurabh Gorecha 	 */
186*5bd9c17dSSaurabh Gorecha 	dyn_map_start = MIN(x2, x4);
187*5bd9c17dSSaurabh Gorecha 	dyn_map_start = MIN(dyn_map_start, x6);
188*5bd9c17dSSaurabh Gorecha 	dyn_map_end = MAX((x2 + x3), (x4 + x5));
189*5bd9c17dSSaurabh Gorecha 	dyn_map_end = MAX(dyn_map_end, (x6 + x7));
190*5bd9c17dSSaurabh Gorecha 	dyn_map_size = dyn_map_end - dyn_map_start;
191*5bd9c17dSSaurabh Gorecha 
192*5bd9c17dSSaurabh Gorecha 	if (qti_mmap_add_dynamic_region(dyn_map_start, dyn_map_size,
193*5bd9c17dSSaurabh Gorecha 					(MT_NS | MT_RO_DATA)) != 0) {
194*5bd9c17dSSaurabh Gorecha 		goto unmap_return;
195*5bd9c17dSSaurabh Gorecha 	}
196*5bd9c17dSSaurabh Gorecha 	memprot_info_t *mem_info_p = (memprot_info_t *) x2;
197*5bd9c17dSSaurabh Gorecha 	uint32_t u_num_mappings = x3 / sizeof(memprot_info_t);
198*5bd9c17dSSaurabh Gorecha 	uint32_t *source_vm_list_p = (uint32_t *) x4;
199*5bd9c17dSSaurabh Gorecha 	uint32_t src_vm_list_cnt = x5 / sizeof(uint32_t);
200*5bd9c17dSSaurabh Gorecha 	memprot_dst_vm_perm_info_t *dest_vm_list_p =
201*5bd9c17dSSaurabh Gorecha 		(memprot_dst_vm_perm_info_t *) x6;
202*5bd9c17dSSaurabh Gorecha 	uint32_t dst_vm_list_cnt =
203*5bd9c17dSSaurabh Gorecha 		x7 / sizeof(memprot_dst_vm_perm_info_t);
204*5bd9c17dSSaurabh Gorecha 	if (qti_mem_assign_validate_param(mem_info_p, u_num_mappings,
205*5bd9c17dSSaurabh Gorecha 				source_vm_list_p, src_vm_list_cnt,
206*5bd9c17dSSaurabh Gorecha 				dest_vm_list_p,
207*5bd9c17dSSaurabh Gorecha 				dst_vm_list_cnt) != true) {
208*5bd9c17dSSaurabh Gorecha 		goto unmap_return;
209*5bd9c17dSSaurabh Gorecha 	}
210*5bd9c17dSSaurabh Gorecha 
211*5bd9c17dSSaurabh Gorecha 	memprot_info_t mem_info[QTI_VM_MAX_LIST_SIZE];
212*5bd9c17dSSaurabh Gorecha 	/* Populating the arguments */
213*5bd9c17dSSaurabh Gorecha 	for (int i = 0; i < u_num_mappings; i++) {
214*5bd9c17dSSaurabh Gorecha 		mem_info[i].mem_addr = mem_info_p[i].mem_addr;
215*5bd9c17dSSaurabh Gorecha 		mem_info[i].mem_size = mem_info_p[i].mem_size;
216*5bd9c17dSSaurabh Gorecha 	}
217*5bd9c17dSSaurabh Gorecha 
218*5bd9c17dSSaurabh Gorecha 	memprot_dst_vm_perm_info_t dest_vm_list[QTI_VM_LAST];
219*5bd9c17dSSaurabh Gorecha 
220*5bd9c17dSSaurabh Gorecha 	for (int i = 0; i < dst_vm_list_cnt; i++) {
221*5bd9c17dSSaurabh Gorecha 		dest_vm_list[i].dst_vm = dest_vm_list_p[i].dst_vm;
222*5bd9c17dSSaurabh Gorecha 		dest_vm_list[i].dst_vm_perm =
223*5bd9c17dSSaurabh Gorecha 			dest_vm_list_p[i].dst_vm_perm;
224*5bd9c17dSSaurabh Gorecha 		dest_vm_list[i].ctx = dest_vm_list_p[i].ctx;
225*5bd9c17dSSaurabh Gorecha 		dest_vm_list[i].ctx_size = dest_vm_list_p[i].ctx_size;
226*5bd9c17dSSaurabh Gorecha 	}
227*5bd9c17dSSaurabh Gorecha 
228*5bd9c17dSSaurabh Gorecha 	uint32_t source_vm_list[QTI_VM_LAST];
229*5bd9c17dSSaurabh Gorecha 
230*5bd9c17dSSaurabh Gorecha 	for (int i = 0; i < src_vm_list_cnt; i++) {
231*5bd9c17dSSaurabh Gorecha 		source_vm_list[i] = source_vm_list_p[i];
232*5bd9c17dSSaurabh Gorecha 	}
233*5bd9c17dSSaurabh Gorecha 	/* Un-Map NS Buffers. */
234*5bd9c17dSSaurabh Gorecha 	if (qti_mmap_remove_dynamic_region(dyn_map_start,
235*5bd9c17dSSaurabh Gorecha 				dyn_map_size) != 0) {
236*5bd9c17dSSaurabh Gorecha 		goto unmap_return;
237*5bd9c17dSSaurabh Gorecha 	}
238*5bd9c17dSSaurabh Gorecha 	/* Invoke API lib api. */
239*5bd9c17dSSaurabh Gorecha 	ret = qtiseclib_mem_assign(mem_info, u_num_mappings,
240*5bd9c17dSSaurabh Gorecha 			source_vm_list, src_vm_list_cnt,
241*5bd9c17dSSaurabh Gorecha 			dest_vm_list, dst_vm_list_cnt);
242*5bd9c17dSSaurabh Gorecha 
243*5bd9c17dSSaurabh Gorecha 	if (ret == 0) {
244*5bd9c17dSSaurabh Gorecha 		SMC_RET2(handle, QTI_SIP_SUCCESS, ret);
245*5bd9c17dSSaurabh Gorecha 	}
246*5bd9c17dSSaurabh Gorecha unmap_return:
247*5bd9c17dSSaurabh Gorecha 	/* Un-Map NS Buffers if mapped */
248*5bd9c17dSSaurabh Gorecha 	if (dyn_map_start && dyn_map_size) {
249*5bd9c17dSSaurabh Gorecha 		qti_mmap_remove_dynamic_region(dyn_map_start, dyn_map_size);
250*5bd9c17dSSaurabh Gorecha 	}
251*5bd9c17dSSaurabh Gorecha 
252*5bd9c17dSSaurabh Gorecha 	SMC_RET2(handle, QTI_SIP_INVALID_PARAM, ret);
253*5bd9c17dSSaurabh Gorecha }
254*5bd9c17dSSaurabh Gorecha 
255*5bd9c17dSSaurabh Gorecha /*
256*5bd9c17dSSaurabh Gorecha  * This function handles QTI specific syscalls. Currently only SiP calls are present.
257*5bd9c17dSSaurabh Gorecha  * Both FAST & YIELD type call land here.
258*5bd9c17dSSaurabh Gorecha  */
259*5bd9c17dSSaurabh Gorecha static uintptr_t qti_sip_handler(uint32_t smc_fid,
260*5bd9c17dSSaurabh Gorecha 				 u_register_t x1,
261*5bd9c17dSSaurabh Gorecha 				 u_register_t x2,
262*5bd9c17dSSaurabh Gorecha 				 u_register_t x3,
263*5bd9c17dSSaurabh Gorecha 				 u_register_t x4,
264*5bd9c17dSSaurabh Gorecha 				 void *cookie, void *handle, u_register_t flags)
265*5bd9c17dSSaurabh Gorecha {
266*5bd9c17dSSaurabh Gorecha 	uint32_t l_smc_fid = smc_fid & FUNCID_OEN_NUM_MASK;
267*5bd9c17dSSaurabh Gorecha 
268*5bd9c17dSSaurabh Gorecha 	if (GET_SMC_CC(smc_fid) == SMC_32) {
269*5bd9c17dSSaurabh Gorecha 		x1 = (uint32_t) x1;
270*5bd9c17dSSaurabh Gorecha 		x2 = (uint32_t) x2;
271*5bd9c17dSSaurabh Gorecha 		x3 = (uint32_t) x3;
272*5bd9c17dSSaurabh Gorecha 		x4 = (uint32_t) x4;
273*5bd9c17dSSaurabh Gorecha 	}
274*5bd9c17dSSaurabh Gorecha 
275*5bd9c17dSSaurabh Gorecha 	switch (l_smc_fid) {
276*5bd9c17dSSaurabh Gorecha 	case QTI_SIP_SVC_CALL_COUNT_ID:
277*5bd9c17dSSaurabh Gorecha 		{
278*5bd9c17dSSaurabh Gorecha 			SMC_RET1(handle, QTI_SIP_SVC_CALL_COUNT);
279*5bd9c17dSSaurabh Gorecha 			break;
280*5bd9c17dSSaurabh Gorecha 		}
281*5bd9c17dSSaurabh Gorecha 	case QTI_SIP_SVC_UID_ID:
282*5bd9c17dSSaurabh Gorecha 		{
283*5bd9c17dSSaurabh Gorecha 			/* Return UID to the caller */
284*5bd9c17dSSaurabh Gorecha 			SMC_UUID_RET(handle, qti_sip_svc_uid);
285*5bd9c17dSSaurabh Gorecha 			break;
286*5bd9c17dSSaurabh Gorecha 		}
287*5bd9c17dSSaurabh Gorecha 	case QTI_SIP_SVC_VERSION_ID:
288*5bd9c17dSSaurabh Gorecha 		{
289*5bd9c17dSSaurabh Gorecha 			/* Return the version of current implementation */
290*5bd9c17dSSaurabh Gorecha 			SMC_RET2(handle, QTI_SIP_SVC_VERSION_MAJOR,
291*5bd9c17dSSaurabh Gorecha 				 QTI_SIP_SVC_VERSION_MINOR);
292*5bd9c17dSSaurabh Gorecha 			break;
293*5bd9c17dSSaurabh Gorecha 		}
294*5bd9c17dSSaurabh Gorecha 	case QTI_SIP_SVC_SECURE_IO_READ_ID:
295*5bd9c17dSSaurabh Gorecha 		{
296*5bd9c17dSSaurabh Gorecha 			if ((x1 == QTI_SIP_SVC_SECURE_IO_READ_PARAM_ID) &&
297*5bd9c17dSSaurabh Gorecha 			    qti_is_secure_io_access_allowed(x2)) {
298*5bd9c17dSSaurabh Gorecha 				SMC_RET2(handle, QTI_SIP_SUCCESS,
299*5bd9c17dSSaurabh Gorecha 					 *((volatile uint32_t *)x2));
300*5bd9c17dSSaurabh Gorecha 			}
301*5bd9c17dSSaurabh Gorecha 			SMC_RET1(handle, QTI_SIP_INVALID_PARAM);
302*5bd9c17dSSaurabh Gorecha 			break;
303*5bd9c17dSSaurabh Gorecha 		}
304*5bd9c17dSSaurabh Gorecha 	case QTI_SIP_SVC_SECURE_IO_WRITE_ID:
305*5bd9c17dSSaurabh Gorecha 		{
306*5bd9c17dSSaurabh Gorecha 			if ((x1 == QTI_SIP_SVC_SECURE_IO_WRITE_PARAM_ID) &&
307*5bd9c17dSSaurabh Gorecha 			    qti_is_secure_io_access_allowed(x2)) {
308*5bd9c17dSSaurabh Gorecha 				*((volatile uint32_t *)x2) = x3;
309*5bd9c17dSSaurabh Gorecha 				SMC_RET1(handle, QTI_SIP_SUCCESS);
310*5bd9c17dSSaurabh Gorecha 			}
311*5bd9c17dSSaurabh Gorecha 			SMC_RET1(handle, QTI_SIP_INVALID_PARAM);
312*5bd9c17dSSaurabh Gorecha 			break;
313*5bd9c17dSSaurabh Gorecha 		}
314*5bd9c17dSSaurabh Gorecha 	case QTI_SIP_SVC_MEM_ASSIGN_ID:
315*5bd9c17dSSaurabh Gorecha 		{
316*5bd9c17dSSaurabh Gorecha 			return qti_sip_mem_assign(handle, GET_SMC_CC(smc_fid),
317*5bd9c17dSSaurabh Gorecha 						  x1, x2, x3, x4);
318*5bd9c17dSSaurabh Gorecha 			break;
319*5bd9c17dSSaurabh Gorecha 		}
320*5bd9c17dSSaurabh Gorecha 	default:
321*5bd9c17dSSaurabh Gorecha 		{
322*5bd9c17dSSaurabh Gorecha 			SMC_RET1(handle, QTI_SIP_NOT_SUPPORTED);
323*5bd9c17dSSaurabh Gorecha 		}
324*5bd9c17dSSaurabh Gorecha 	}
325*5bd9c17dSSaurabh Gorecha 	return (uintptr_t) handle;
326*5bd9c17dSSaurabh Gorecha }
327*5bd9c17dSSaurabh Gorecha 
328*5bd9c17dSSaurabh Gorecha /* Define a runtime service descriptor for both fast & yield SiP calls */
329*5bd9c17dSSaurabh Gorecha DECLARE_RT_SVC(qti_sip_fast_svc, OEN_SIP_START,
330*5bd9c17dSSaurabh Gorecha 	       OEN_SIP_END, SMC_TYPE_FAST, NULL, qti_sip_handler);
331*5bd9c17dSSaurabh Gorecha 
332*5bd9c17dSSaurabh Gorecha DECLARE_RT_SVC(qti_sip_yield_svc, OEN_SIP_START,
333*5bd9c17dSSaurabh Gorecha 	       OEN_SIP_END, SMC_TYPE_YIELD, NULL, qti_sip_handler);
334