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