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 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 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 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 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