1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2021 NXP
4  */
5 #include <drivers/imx_ocotp.h>
6 #include <kernel/pseudo_ta.h>
7 #include <kernel/tee_common_otp.h>
8 #include <pta_imx_ocotp.h>
9 
10 #define OCOTP_PTA_NAME "ocotp.pta"
11 
chip_uid(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])12 static TEE_Result chip_uid(uint32_t param_types,
13 			   TEE_Param params[TEE_NUM_PARAMS])
14 {
15 	uint8_t val[IMX_UID_SIZE] = { };
16 	uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT,
17 						   TEE_PARAM_TYPE_NONE,
18 						   TEE_PARAM_TYPE_NONE,
19 						   TEE_PARAM_TYPE_NONE);
20 
21 	if (param_types != exp_param_types)
22 		return TEE_ERROR_BAD_PARAMETERS;
23 
24 	/* On i.MX platforms, the chip UID is 64 bits long */
25 	if (params[0].memref.size != sizeof(uint64_t))
26 		return TEE_ERROR_BAD_PARAMETERS;
27 
28 	if (tee_otp_get_die_id(val, IMX_UID_SIZE))
29 		return TEE_ERROR_GENERIC;
30 
31 	memcpy(params[0].memref.buffer, val, IMX_UID_SIZE);
32 
33 	return TEE_SUCCESS;
34 }
35 
read_fuse(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])36 static TEE_Result read_fuse(uint32_t param_types,
37 			    TEE_Param params[TEE_NUM_PARAMS])
38 {
39 	TEE_Result ret = TEE_ERROR_GENERIC;
40 	uint32_t val = 0;
41 	uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
42 						   TEE_PARAM_TYPE_VALUE_OUTPUT,
43 						   TEE_PARAM_TYPE_NONE,
44 						   TEE_PARAM_TYPE_NONE);
45 
46 	if (param_types != exp_param_types)
47 		return TEE_ERROR_BAD_PARAMETERS;
48 
49 	params[1].value.a = 0;
50 	params[1].value.b = 0;
51 
52 	ret = imx_ocotp_read(params[0].value.a, params[0].value.b, &val);
53 	if (!ret)
54 		params[1].value.a = val;
55 
56 	return ret;
57 }
58 
invokeCommandEntryPoint(void * sess_ctx __unused,uint32_t cmd_id,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])59 static TEE_Result invokeCommandEntryPoint(void *sess_ctx __unused,
60 					  uint32_t cmd_id, uint32_t param_types,
61 					  TEE_Param params[TEE_NUM_PARAMS])
62 {
63 	switch (cmd_id) {
64 	case PTA_OCOTP_CMD_CHIP_UID:
65 		return chip_uid(param_types, params);
66 	case PTA_OCOTP_CMD_READ_FUSE:
67 		return read_fuse(param_types, params);
68 	default:
69 		return TEE_ERROR_BAD_PARAMETERS;
70 	}
71 }
72 
73 pseudo_ta_register(.uuid = PTA_OCOTP_UUID, .name = OCOTP_PTA_NAME,
74 		   .flags = PTA_DEFAULT_FLAGS,
75 		   .invoke_command_entry_point = invokeCommandEntryPoint);
76