1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (C) 2016 Freescale Semiconductor, Inc.
4  * Copyright 2017-2021 NXP
5  */
6 #include <drivers/imx_mu.h>
7 #include <drivers/imx_sc_api.h>
8 #include <imx-regs.h>
9 #include <initcall.h>
10 #include <kernel/mutex.h>
11 #include <mm/core_memprot.h>
12 #include <tee_api_types.h>
13 #include <trace.h>
14 
15 #define RNG_INIT_RETRY 100
16 
17 #define SC_RPC_VERSION 1
18 #define SC_RPC_MAX_MSG 8
19 
20 /* Macros to fill struct sc_rpc_msg data field */
21 #define RPC_U32(mesg, idx) ((mesg)->data.u32[(idx)])
22 #define RPC_U16(mesg, idx) ((mesg)->data.u16[(idx)])
23 #define RPC_U8(mesg, idx)  ((mesg)->data.u8[(idx)])
24 
25 /* Defines for struct sc_rpc_msg svc field */
26 #define SC_RPC_SVC_PM	2
27 #define SC_RPC_SVC_RM	3
28 #define SC_RPC_SVC_SECO 9
29 
30 /* Define for PM function calls */
31 enum sc_pm_func {
32 	SC_PM_FUNC_SET_RESOURCE_POWER_MODE = 3
33 };
34 
35 /* Defines for RM function calls */
36 enum sc_rm_func {
37 	SC_RM_FUNC_GET_PARTITION = 5,
38 	SC_RM_FUNC_ASSIGN_RESOURCE = 8
39 };
40 
41 /* Define for SECO function calls */
42 enum sc_seco_func {
43 	SC_SECO_FUNC_START_RNG = 22
44 };
45 
46 /* Internal SCFW API error codes */
47 enum sc_error {
48 	SC_ERR_NONE = 0,	/* Success */
49 	SC_ERR_VERSION,		/* Incompatible API version */
50 	SC_ERR_CONFIG,		/* Configuration error */
51 	SC_ERR_PARM,		/* Bad parameter */
52 	SC_ERR_NOACCESS,	/* Permission error (no access) */
53 	SC_ERR_LOCKED,		/* Permission error (locked) */
54 	SC_ERR_UNAVAILABLE,	/* Unavailable (out of resources) */
55 	SC_ERR_NOTFOUND,	/* Not found */
56 	SC_ERR_NOPOWER,		/* No power */
57 	SC_ERR_IPC,		/* Generic IPC error */
58 	SC_ERR_BUSY,		/* Resource is currently busy/active */
59 	SC_ERR_FAIL,		/* General I/O failure */
60 	SC_ERR_LAST
61 };
62 
63 /* RNG SECO states */
64 enum sc_seco_rng_status {
65 	SC_SECO_RNG_STAT_UNAVAILABLE = 0,
66 	SC_SECO_RNG_STAT_INPROGRESS,
67 	SC_SECO_RNG_STAT_READY
68 };
69 
70 /* Resources IDs */
71 enum sc_resource {
72 	SC_RES_CAAM_JR1 = 500,
73 	SC_RES_CAAM_JR2,
74 	SC_RES_CAAM_JR3,
75 	SC_RES_CAAM_JR1_OUT = 514,
76 	SC_RES_CAAM_JR2_OUT,
77 	SC_RES_CAAM_JR3_OUT,
78 	SC_RES_CAAM_JR0 = 519,
79 	SC_RES_CAAM_JR0_OUT,
80 	SC_RES_LAST = 546
81 };
82 
83 /* Power modes */
84 enum sc_power_mode {
85 	SC_PM_PW_MODE_OFF = 0,
86 	SC_PM_PW_MODE_STBY,
87 	SC_PM_PW_MODE_LP,
88 	SC_PM_PW_MODE_ON
89 };
90 
91 /* RPC message header */
92 struct sc_rpc_msg_header {
93 	uint8_t version;	/* SC RPC version */
94 	uint8_t size;		/* Size of the message */
95 	uint8_t svc;		/* Type of service: one of SC_RPC_SVC_* */
96 	uint8_t func;		/* Function ID or Error code */
97 };
98 
99 /* RPC message format */
100 struct sc_rpc_msg {
101 	struct sc_rpc_msg_header header;
102 	union {
103 		uint32_t u32[SC_RPC_MAX_MSG - 1];
104 		uint16_t u16[(SC_RPC_MAX_MSG - 1) * 2];
105 		uint8_t u8[(SC_RPC_MAX_MSG - 1) * 4];
106 	} data;
107 };
108 
109 static struct mutex scu_mu_mutex = MUTEX_INITIALIZER;
110 static vaddr_t secure_ipc_addr;
111 
112 register_phys_mem(MEM_AREA_IO_SEC, SC_IPC_BASE_SECURE, SC_IPC_SIZE);
113 
114 /*
115  * Read a message from an IPC channel
116  *
117  * @ipc	IPC channel
118  * @msg	Received message
119  */
sc_ipc_read(vaddr_t ipc,struct sc_rpc_msg * msg)120 static TEE_Result sc_ipc_read(vaddr_t ipc, struct sc_rpc_msg *msg)
121 {
122 	TEE_Result res = TEE_ERROR_GENERIC;
123 	unsigned int count = 0;
124 
125 	if (!msg) {
126 		EMSG("msg is NULL");
127 		return TEE_ERROR_BAD_PARAMETERS;
128 	}
129 
130 	assert(ipc);
131 
132 	res = mu_receive_msg(ipc, 0, (uint32_t *)msg);
133 	if (res)
134 		return res;
135 
136 	/* Check the size of the message to receive */
137 	if (msg->header.size > SC_RPC_MAX_MSG) {
138 		EMSG("Size of the message is > than SC_RPC_MAX_MSG");
139 		return TEE_ERROR_BAD_FORMAT;
140 	}
141 
142 	for (count = 1; count < msg->header.size; count++) {
143 		res = mu_receive_msg(ipc, count % MU_NB_RR,
144 				     &msg->data.u32[count - 1]);
145 		if (res)
146 			return res;
147 	}
148 
149 	return TEE_SUCCESS;
150 }
151 
152 /*
153  * Write a message to an IPC channel
154  *
155  * @ipc	IPC channel
156  * @msg	Send message pointer
157  */
sc_ipc_write(vaddr_t ipc,struct sc_rpc_msg * msg)158 static TEE_Result sc_ipc_write(vaddr_t ipc, struct sc_rpc_msg *msg)
159 {
160 	TEE_Result res = TEE_ERROR_GENERIC;
161 	unsigned int count = 0;
162 
163 	if (!msg) {
164 		EMSG("msg is NULL");
165 		return TEE_ERROR_BAD_PARAMETERS;
166 	}
167 
168 	if (msg->header.size > SC_RPC_MAX_MSG) {
169 		EMSG("msg->size is > than SC_RPC_MAX_MSG");
170 		return TEE_ERROR_BAD_FORMAT;
171 	}
172 
173 	assert(ipc);
174 
175 	res = mu_send_msg(ipc, 0, *(uint32_t *)msg);
176 	if (res)
177 		return res;
178 
179 	for (count = 1; count < msg->header.size; count++) {
180 		res = mu_send_msg(ipc, count % MU_NB_TR,
181 				  msg->data.u32[count - 1]);
182 		if (res)
183 			return res;
184 	}
185 
186 	return TEE_SUCCESS;
187 }
188 
189 /*
190  * Send an RPC message over the secure world IPC channel
191  *
192  * @msg		Message to send. This pointer will also return the answer
193  *		message if expected.
194  * @wait_resp	Set to true if an answer is expected.
195  */
sc_call_rpc(struct sc_rpc_msg * msg,bool wait_resp)196 static TEE_Result sc_call_rpc(struct sc_rpc_msg *msg, bool wait_resp)
197 {
198 	TEE_Result res = TEE_ERROR_GENERIC;
199 
200 	mutex_lock(&scu_mu_mutex);
201 
202 	res = sc_ipc_write(secure_ipc_addr, msg);
203 
204 	if (res == TEE_SUCCESS && wait_resp)
205 		res = sc_ipc_read(secure_ipc_addr, msg);
206 
207 	mutex_unlock(&scu_mu_mutex);
208 
209 	return res;
210 }
211 
212 /*
213  * Get the partition ID of secure world
214  *
215  * @partition Partition ID
216  */
sc_rm_get_partition(uint8_t * partition)217 static TEE_Result sc_rm_get_partition(uint8_t *partition)
218 {
219 	TEE_Result res = TEE_ERROR_GENERIC;
220 	enum sc_error err = SC_ERR_LAST;
221 	struct sc_rpc_msg msg = {
222 		.header.version = SC_RPC_VERSION,
223 		.header.size = 1,
224 		.header.svc = SC_RPC_SVC_RM,
225 		.header.func = SC_RM_FUNC_GET_PARTITION,
226 	};
227 
228 	res = sc_call_rpc(&msg, true);
229 	if (res != TEE_SUCCESS) {
230 		EMSG("Communication error");
231 		return res;
232 	}
233 
234 	err = msg.header.func;
235 	if (err != SC_ERR_NONE) {
236 		EMSG("Unable to get partition ID, sc_error: %d", err);
237 		return TEE_ERROR_GENERIC;
238 	}
239 
240 	*partition = RPC_U8(&msg, 0);
241 
242 	return TEE_SUCCESS;
243 }
244 
245 /*
246  * Set the given power mode of a resource
247  *
248  * @resource	ID of the resource
249  * @mode	Power mode to apply
250  */
sc_pm_set_resource_power_mode(enum sc_resource resource,enum sc_power_mode mode)251 static TEE_Result sc_pm_set_resource_power_mode(enum sc_resource resource,
252 						enum sc_power_mode mode)
253 {
254 	TEE_Result res = TEE_ERROR_GENERIC;
255 	enum sc_error scu_error = SC_ERR_LAST;
256 	struct sc_rpc_msg msg = {
257 		.header.version = SC_RPC_VERSION,
258 		.header.size = 2,
259 		.header.svc = SC_RPC_SVC_PM,
260 		.header.func = SC_PM_FUNC_SET_RESOURCE_POWER_MODE,
261 	};
262 
263 	RPC_U16(&msg, 0) = (uint16_t)resource;
264 	RPC_U8(&msg, 2) = (uint8_t)mode;
265 
266 	res = sc_call_rpc(&msg, true);
267 	if (res != TEE_SUCCESS) {
268 		EMSG("Communication error");
269 		return res;
270 	}
271 
272 	scu_error = msg.header.func;
273 	if (scu_error != SC_ERR_NONE) {
274 		EMSG("Unable to set resource power mode sc_error: %d",
275 		     scu_error);
276 		return TEE_ERROR_GENERIC;
277 	}
278 
279 	return TEE_SUCCESS;
280 }
281 
282 /*
283  * Assign ownership of a resource to the secure partition
284  *
285  * @resource Resource to assign
286  */
sc_rm_assign_resource(enum sc_resource resource)287 static TEE_Result sc_rm_assign_resource(enum sc_resource resource)
288 {
289 	TEE_Result res = TEE_ERROR_GENERIC;
290 	enum sc_error err = SC_ERR_LAST;
291 	uint8_t secure_partition = 0;
292 	struct sc_rpc_msg msg = {
293 		.header.version = SC_RPC_VERSION,
294 		.header.size = 2,
295 		.header.svc = SC_RPC_SVC_RM,
296 		.header.func = SC_RM_FUNC_ASSIGN_RESOURCE,
297 	};
298 
299 	res = sc_rm_get_partition(&secure_partition);
300 	if (res != TEE_SUCCESS) {
301 		EMSG("Cannot get secure partition ID");
302 		return res;
303 	}
304 
305 	RPC_U16(&msg, 0) = (uint16_t)resource;
306 	RPC_U8(&msg, 2) = secure_partition;
307 
308 	res = sc_call_rpc(&msg, true);
309 	if (res != TEE_SUCCESS) {
310 		EMSG("Communication error");
311 		return res;
312 	}
313 
314 	err = msg.header.func;
315 	if (err != SC_ERR_NONE) {
316 		EMSG("Unable to assign resource, sc_error: %d", err);
317 		return TEE_ERROR_GENERIC;
318 	}
319 
320 	return TEE_SUCCESS;
321 }
322 
imx_sc_rm_enable_jr(unsigned int jr_index)323 TEE_Result imx_sc_rm_enable_jr(unsigned int jr_index)
324 {
325 	TEE_Result res = TEE_ERROR_GENERIC;
326 	enum sc_resource jr_res = SC_RES_LAST;
327 	enum sc_resource jr_out_res = SC_RES_LAST;
328 
329 	switch (jr_index) {
330 	case 0:
331 		jr_res = SC_RES_CAAM_JR0;
332 		jr_out_res = SC_RES_CAAM_JR0_OUT;
333 		break;
334 
335 	case 1:
336 		jr_res = SC_RES_CAAM_JR1;
337 		jr_out_res = SC_RES_CAAM_JR1_OUT;
338 		break;
339 
340 	case 2:
341 		jr_res = SC_RES_CAAM_JR2;
342 		jr_out_res = SC_RES_CAAM_JR2_OUT;
343 		break;
344 
345 	case 3:
346 		jr_res = SC_RES_CAAM_JR3;
347 		jr_out_res = SC_RES_CAAM_JR3_OUT;
348 		break;
349 
350 	default:
351 		EMSG("Wrong JR Index, should be 0, 1, 2 or 3");
352 		return TEE_ERROR_GENERIC;
353 	}
354 
355 	/* Assign JR resources to secure world */
356 	res = sc_rm_assign_resource(jr_res);
357 	if (res != TEE_SUCCESS) {
358 		EMSG("Assign SC_R_CAAM_JR%u resource failed", jr_index);
359 		return res;
360 	}
361 
362 	res = sc_rm_assign_resource(jr_out_res);
363 	if (res != TEE_SUCCESS) {
364 		EMSG("Assign SC_R_CAAM_JR%u_OUT resource failed", jr_index);
365 		return res;
366 	}
367 
368 	/* Power ON JR resources */
369 	res = sc_pm_set_resource_power_mode(jr_res, SC_PM_PW_MODE_ON);
370 	if (res != TEE_SUCCESS) {
371 		EMSG("POWER ON SC_R_CAAM_JR%u resource failed", jr_index);
372 		return res;
373 	}
374 
375 	res = sc_pm_set_resource_power_mode(jr_out_res, SC_PM_PW_MODE_ON);
376 	if (res != TEE_SUCCESS) {
377 		EMSG("POWER ON SC_R_CAAM_JR%u_OUT resource failed", jr_index);
378 		return res;
379 	}
380 
381 	return TEE_SUCCESS;
382 }
383 
imx_sc_seco_start_rng(void)384 TEE_Result imx_sc_seco_start_rng(void)
385 {
386 	TEE_Result res = TEE_ERROR_GENERIC;
387 	enum sc_error err = SC_ERR_LAST;
388 	enum sc_seco_rng_status status = SC_SECO_RNG_STAT_UNAVAILABLE;
389 	unsigned int retry = 0;
390 	struct sc_rpc_msg msg = {
391 		.header.version = SC_RPC_VERSION,
392 		.header.size = 1,
393 		.header.svc = SC_RPC_SVC_SECO,
394 		.header.func = SC_SECO_FUNC_START_RNG,
395 	};
396 
397 	for (retry = RNG_INIT_RETRY; retry; retry--) {
398 		res = sc_call_rpc(&msg, true);
399 		if (res != TEE_SUCCESS) {
400 			EMSG("Configuration error");
401 			return res;
402 		}
403 
404 		err = msg.header.func;
405 		if (err != SC_ERR_NONE) {
406 			EMSG("RNG status: %d", err);
407 			return TEE_ERROR_GENERIC;
408 		}
409 
410 		status = RPC_U32(&msg, 0);
411 
412 		if (status == SC_SECO_RNG_STAT_READY)
413 			return TEE_SUCCESS;
414 	}
415 
416 	return TEE_ERROR_GENERIC;
417 }
418 
imx_sc_driver_init(void)419 TEE_Result imx_sc_driver_init(void)
420 {
421 	vaddr_t va = 0;
422 
423 	va = core_mmu_get_va(SC_IPC_BASE_SECURE, MEM_AREA_IO_SEC, SC_IPC_SIZE);
424 	if (!va)
425 		return TEE_ERROR_GENERIC;
426 
427 	mutex_lock(&scu_mu_mutex);
428 	mu_init(va);
429 	secure_ipc_addr = va;
430 	mutex_unlock(&scu_mu_mutex);
431 
432 	return TEE_SUCCESS;
433 }
434