1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2019 Broadcom.
4  */
5 
6 #include <drivers/bcm/bnxt.h>
7 #include <io.h>
8 #include <kernel/misc.h>
9 #include <kernel/pseudo_ta.h>
10 #include <mm/core_memprot.h>
11 #include <string.h>
12 #include <util.h>
13 
14 #define BNXT_SERVICE_UUID \
15 		{0x6272636D, 0x2019, 0x0716,  \
16 		{0x42, 0x43, 0x4D, 0x5F, 0x53, 0x43, 0x48, 0x49} }
17 
18 /*
19  * enum pta_bnxt_cmd - commands supported by this PTA
20  * PTA_BNXT_FASTBOOT:		boot bnxt device by copying f/w into sram
21  *
22  * PTA_BNXT_HEALTH_STATUS:	check health of bnxt device
23  *					[out] value[0].a - health status
24  *
25  * PTA_BNXT_HANDSHAKE_STATUS:	check bnxt device is booted
26  *					[inout] value[0].a - max timeout value
27  *						value[0].a - boot status
28  *
29  * PTA_BNXT_CRASH_DUMP_COPY:	copy the core dump into shm
30  *					[inout] memref[0].buf: destination addr
31  *					[in] value[1].a: offset
32  *					[in] value[1].b: size
33  */
34 enum pta_bnxt_cmd {
35 	PTA_BNXT_FASTBOOT = 0,
36 	PTA_BNXT_HEALTH_STATUS,
37 	PTA_BNXT_HANDSHAKE_STATUS,
38 	PTA_BNXT_CRASH_DUMP_COPY,
39 };
40 
41 #define BNXT_TA_NAME		"pta_bnxt.ta"
42 
get_bnxt_status(uint32_t type,TEE_Param p[TEE_NUM_PARAMS])43 static TEE_Result get_bnxt_status(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
44 {
45 	if (type != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT,
46 				    TEE_PARAM_TYPE_NONE,
47 				    TEE_PARAM_TYPE_NONE,
48 				    TEE_PARAM_TYPE_NONE))
49 		return TEE_ERROR_BAD_PARAMETERS;
50 
51 	p[0].value.a = bnxt_health_status();
52 
53 	return TEE_SUCCESS;
54 }
55 
get_bnxt_handshake_status(uint32_t type,TEE_Param p[TEE_NUM_PARAMS])56 static TEE_Result get_bnxt_handshake_status(uint32_t type,
57 					    TEE_Param p[TEE_NUM_PARAMS])
58 {
59 	if (type != TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INOUT,
60 				    TEE_PARAM_TYPE_NONE,
61 				    TEE_PARAM_TYPE_NONE,
62 				    TEE_PARAM_TYPE_NONE))
63 		return TEE_ERROR_BAD_PARAMETERS;
64 
65 	p[0].value.a = bnxt_wait_handshake(p[0].value.a);
66 
67 	return TEE_SUCCESS;
68 }
69 
copy_bnxt_crash_dump(uint32_t types,TEE_Param params[TEE_NUM_PARAMS])70 static TEE_Result copy_bnxt_crash_dump(uint32_t types,
71 				       TEE_Param params[TEE_NUM_PARAMS])
72 {
73 	uint32_t *d = NULL;
74 	uint32_t offset = 0;
75 	uint32_t req_len = 0;
76 	TEE_Result res = TEE_SUCCESS;
77 
78 	if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
79 				     TEE_PARAM_TYPE_VALUE_INPUT,
80 				     TEE_PARAM_TYPE_NONE,
81 				     TEE_PARAM_TYPE_NONE)) {
82 		DMSG("bad parameters types: 0x%" PRIx32, types);
83 		return TEE_ERROR_BAD_PARAMETERS;
84 	}
85 
86 	d = (uint32_t *)params[0].memref.buffer;
87 	offset = params[1].value.a;
88 	req_len = params[1].value.b;
89 
90 	if (!d || params[0].memref.size < req_len)
91 		return TEE_ERROR_BAD_PARAMETERS;
92 
93 	res = bnxt_copy_crash_dump((uint8_t *)d, offset, req_len);
94 
95 	return res;
96 }
97 
invoke_command(void * session_context __unused,uint32_t cmd_id,uint32_t param_types __unused,TEE_Param params[TEE_NUM_PARAMS]__unused)98 static TEE_Result invoke_command(void *session_context __unused,
99 				 uint32_t cmd_id,
100 				 uint32_t param_types __unused,
101 				 TEE_Param params[TEE_NUM_PARAMS] __unused)
102 {
103 	TEE_Result res = TEE_SUCCESS;
104 
105 	DMSG("command entry point[%d] for \"%s\"", cmd_id, BNXT_TA_NAME);
106 
107 	switch (cmd_id) {
108 	case PTA_BNXT_FASTBOOT:
109 		DMSG("bnxt fastboot");
110 		if (bnxt_load_fw(1) != BNXT_SUCCESS)
111 			return TEE_ERROR_TARGET_DEAD;
112 		break;
113 	case PTA_BNXT_HEALTH_STATUS:
114 		DMSG("bnxt health status");
115 		return get_bnxt_status(param_types, params);
116 	case PTA_BNXT_HANDSHAKE_STATUS:
117 		DMSG("bnxt handshake status");
118 		return get_bnxt_handshake_status(param_types, params);
119 	case PTA_BNXT_CRASH_DUMP_COPY:
120 		DMSG("bnxt copy crash dump data");
121 		return copy_bnxt_crash_dump(param_types, params);
122 	default:
123 		DMSG("cmd: %d Not supported %s", cmd_id, BNXT_TA_NAME);
124 		res = TEE_ERROR_NOT_SUPPORTED;
125 		break;
126 	}
127 
128 	return res;
129 }
130 
131 pseudo_ta_register(.uuid = BNXT_SERVICE_UUID,
132 		   .name = BNXT_TA_NAME,
133 		   .flags = PTA_DEFAULT_FLAGS | TA_FLAG_DEVICE_ENUM,
134 		   .invoke_command_entry_point = invoke_command);
135