1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2019, Broadcom
4  */
5 
6 #include <config.h>
7 #include <drivers/bcm_sotp.h>
8 #include <io.h>
9 #include <kernel/misc.h>
10 #include <kernel/pseudo_ta.h>
11 
12 #define SOTP_SERVICE_UUID \
13 		{0x6272636D, 0x2018, 0x1101,  \
14 		{0x42, 0x43, 0x4D, 0x5F, 0x53, 0x4F, 0x54, 0x50} }
15 
16 enum pta_bcm_sotp_cmd {
17 	PTA_BCM_SOTP_CMD_READ = 0,
18 	PTA_BCM_SOTP_CMD_WRITE,
19 };
20 
21 #define SOTP_TA_NAME		"pta_bcm_sotp.ta"
22 
23 static bool sotp_access_disabled;
24 
25 /**
26  * close_session() - Print a debug message when closing a session and set the
27  *		     driver to disallow any more pta sessions to connect.
28  * @pSessionContext	Unused.
29  */
close_session(void * pSessionContext __unused)30 static void close_session(void *pSessionContext __unused)
31 {
32 	DMSG("close entry point for \"%s\"", SOTP_TA_NAME);
33 	if (IS_ENABLED(CFG_BCM_SOTP_SINGLE_SESSION))
34 		sotp_access_disabled = true;
35 }
36 
pta_sotp_read(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])37 static TEE_Result pta_sotp_read(uint32_t param_types,
38 				TEE_Param params[TEE_NUM_PARAMS])
39 {
40 	uint64_t sotp_row_value = 0;
41 	uint32_t val = 0;
42 	uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
43 						   TEE_PARAM_TYPE_VALUE_OUTPUT,
44 						   TEE_PARAM_TYPE_NONE,
45 						   TEE_PARAM_TYPE_NONE);
46 	if (exp_param_types != param_types) {
47 		EMSG("Invalid Param types");
48 		return TEE_ERROR_BAD_PARAMETERS;
49 	}
50 
51 	val = params[0].value.a;
52 
53 	bcm_iproc_sotp_mem_read(val, true, &sotp_row_value);
54 	reg_pair_from_64(sotp_row_value, &params[1].value.a,
55 			 &params[1].value.b);
56 
57 	return TEE_SUCCESS;
58 }
59 
pta_sotp_write(uint32_t param_types __unused,TEE_Param params[TEE_NUM_PARAMS]__unused)60 static TEE_Result pta_sotp_write(uint32_t param_types __unused,
61 				 TEE_Param params[TEE_NUM_PARAMS] __unused)
62 {
63 	/* Nothing as of now */
64 	return TEE_ERROR_NOT_IMPLEMENTED;
65 }
66 
invoke_command(void * session_context __unused,uint32_t cmd_id,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])67 static TEE_Result invoke_command(void *session_context __unused,
68 				 uint32_t cmd_id,
69 				 uint32_t param_types,
70 				 TEE_Param params[TEE_NUM_PARAMS])
71 {
72 	TEE_Result res = TEE_SUCCESS;
73 
74 	DMSG("command entry point[%d] for \"%s\"", cmd_id, SOTP_TA_NAME);
75 
76 	if (IS_ENABLED(CFG_BCM_SOTP_SINGLE_SESSION) && sotp_access_disabled) {
77 		DMSG("bcm sotp pta access disabled");
78 		return TEE_ERROR_ACCESS_DENIED;
79 	}
80 
81 	switch (cmd_id) {
82 	case PTA_BCM_SOTP_CMD_READ:
83 		res = pta_sotp_read(param_types, params);
84 		break;
85 	case PTA_BCM_SOTP_CMD_WRITE:
86 		res = pta_sotp_write(param_types, params);
87 		break;
88 	default:
89 		EMSG("cmd %d Not supported %s", cmd_id, SOTP_TA_NAME);
90 		res = TEE_ERROR_NOT_SUPPORTED;
91 		break;
92 	}
93 
94 	return res;
95 }
96 
97 pseudo_ta_register(.uuid = SOTP_SERVICE_UUID,
98 		   .name = SOTP_TA_NAME,
99 		   .flags = PTA_DEFAULT_FLAGS,
100 		   .close_session_entry_point = close_session,
101 		   .invoke_command_entry_point = invoke_command);
102