1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Texas Instruments System Control Interface Driver
4 *
5 * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
6 * Manorit Chawdhry <m-chawdhry@ti.com>
7 */
8
9 #include <drivers/ti_sci.h>
10 #include <inttypes.h>
11 #include <k3/otp_keywriting_ta.h>
12 #include <kernel/pseudo_ta.h>
13
write_otp_row(uint32_t param_types,TEE_Param params[4])14 static TEE_Result write_otp_row(uint32_t param_types, TEE_Param params[4])
15 {
16 TEE_Result ret = TEE_SUCCESS;
17 const uint32_t exp_param_types =
18 TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
19 TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
20 TEE_PARAM_TYPE_NONE);
21
22 /*
23 * Safely get the invocation parameters
24 */
25 if (param_types != exp_param_types)
26 return TEE_ERROR_BAD_PARAMETERS;
27
28 ret = ti_sci_write_otp_row(params[0].value.a, params[1].value.a,
29 params[1].value.b);
30 if (ret)
31 return ret;
32
33 DMSG("Written the value: 0x%08"PRIx32, params[1].value.a);
34
35 return TEE_SUCCESS;
36 }
37
read_otp_mmr(uint32_t param_types,TEE_Param params[4])38 static TEE_Result read_otp_mmr(uint32_t param_types, TEE_Param params[4])
39 {
40 TEE_Result ret = TEE_SUCCESS;
41 const uint32_t exp_param_types =
42 TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
43 TEE_PARAM_TYPE_VALUE_OUTPUT,
44 TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE);
45
46 /*
47 * Safely get the invocation parameters
48 */
49 if (param_types != exp_param_types)
50 return TEE_ERROR_BAD_PARAMETERS;
51
52 ret = ti_sci_read_otp_mmr(params[0].value.a, ¶ms[1].value.a);
53 if (ret)
54 return ret;
55
56 DMSG("Got the value: 0x%08"PRIx32, params[1].value.a);
57
58 return TEE_SUCCESS;
59 }
60
lock_otp_row(uint32_t param_types,TEE_Param params[4])61 static TEE_Result lock_otp_row(uint32_t param_types, TEE_Param params[4])
62 {
63 TEE_Result ret = TEE_SUCCESS;
64 int hw_write_lock = 0;
65 int hw_read_lock = 0;
66 int soft_lock = 0;
67 const uint32_t exp_param_types =
68 TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
69 TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE);
70
71 /*
72 * Safely get the invocation parameters
73 */
74 if (param_types != exp_param_types)
75 return TEE_ERROR_BAD_PARAMETERS;
76
77 if (params[0].value.b & K3_OTP_KEYWRITING_SOFT_LOCK)
78 soft_lock = 0x5A;
79 if (params[0].value.b & K3_OTP_KEYWRITING_HW_READ_LOCK)
80 hw_read_lock = 0x5A;
81 if (params[0].value.b & K3_OTP_KEYWRITING_HW_WRITE_LOCK)
82 hw_write_lock = 0x5A;
83
84 DMSG("hw_write_lock: 0x%#x", hw_write_lock);
85 DMSG("hw_read_lock: 0x%#x", hw_read_lock);
86 DMSG("soft_lock: 0x%#x", soft_lock);
87
88 ret = ti_sci_lock_otp_row(params[0].value.a, hw_write_lock,
89 hw_read_lock, soft_lock);
90
91 if (ret)
92 return ret;
93
94 DMSG("Locked the row: 0x%08"PRIx32, params[1].value.a);
95
96 return TEE_SUCCESS;
97 }
98
invoke_command(void * session __unused,uint32_t command,uint32_t param_types,TEE_Param params[4])99 static TEE_Result invoke_command(void *session __unused,
100 uint32_t command, uint32_t param_types,
101 TEE_Param params[4])
102 {
103 switch (command) {
104 case TA_OTP_KEYWRITING_CMD_READ_MMR:
105 return read_otp_mmr(param_types, params);
106 case TA_OTP_KEYWRITING_CMD_WRITE_ROW:
107 return write_otp_row(param_types, params);
108 case TA_OTP_KEYWRITING_CMD_LOCK_ROW:
109 return lock_otp_row(param_types, params);
110 default:
111 EMSG("Command ID 0x%"PRIx32" is not supported", command);
112 return TEE_ERROR_NOT_SUPPORTED;
113 }
114 }
115
116 pseudo_ta_register(.uuid = PTA_K3_OTP_KEYWRITING_UUID,
117 .name = PTA_K3_OTP_KEYWRITING_NAME,
118 .flags = PTA_DEFAULT_FLAGS,
119 .invoke_command_entry_point = invoke_command);
120