1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2020 Broadcom.
4  */
5 
6 #include <common.h>
7 #include <tee.h>
8 #include <broadcom/chimp.h>
9 
10 #ifdef CONFIG_CHIMP_OPTEE
11 
12 #define CHMIP_BOOT_UUID { 0x6272636D, 0x2019, 0x0716, \
13 		   { 0x42, 0x43, 0x4D, 0x5F, 0x53, 0x43, 0x48, 0x49 } }
14 
15 enum {
16 	TEE_CHIMP_FASTBOOT = 0,
17 	TEE_CHIMP_HEALTH_STATUS,
18 	TEE_CHIMP_HANDSHAKE_STATUS,
19 } tee_chmip_cmd;
20 
21 struct bcm_chimp_data {
22 	struct udevice *tee;
23 	u32 session;
24 } chimp_data;
25 
get_open_session(struct bcm_chimp_data * b_data)26 static int get_open_session(struct bcm_chimp_data *b_data)
27 {
28 	const struct tee_optee_ta_uuid uuid = CHMIP_BOOT_UUID;
29 	struct tee_open_session_arg arg;
30 	struct udevice *tee = NULL;
31 	int rc;
32 
33 	tee = tee_find_device(NULL, NULL, NULL, NULL);
34 	if (!tee)
35 		return -ENODEV;
36 
37 	memset(&arg, 0, sizeof(arg));
38 	tee_optee_ta_uuid_to_octets(arg.uuid, &uuid);
39 	rc = tee_open_session(tee, &arg, 0, NULL);
40 	if (rc < 0)
41 		return -ENODEV;
42 
43 	b_data->tee = tee;
44 	b_data->session = arg.session;
45 
46 	return 0;
47 }
48 
init_arg(struct tee_invoke_arg * arg,u32 func)49 static int init_arg(struct tee_invoke_arg *arg, u32 func)
50 {
51 	if (get_open_session(&chimp_data))
52 		return -EINVAL;
53 
54 	memset(arg, 0, sizeof(struct tee_invoke_arg));
55 	arg->func = func;
56 	arg->session = chimp_data.session;
57 
58 	return 0;
59 }
60 
chimp_handshake_status_optee(u32 timeout,u32 * hs)61 int chimp_handshake_status_optee(u32 timeout, u32 *hs)
62 {
63 	struct tee_invoke_arg arg;
64 	struct tee_param param[1];
65 	int ret;
66 
67 	ret = init_arg(&arg, TEE_CHIMP_HANDSHAKE_STATUS);
68 	if (ret < 0)
69 		return ret;
70 
71 	param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INOUT;
72 	param[0].u.value.a = timeout;
73 
74 	ret = tee_invoke_func(chimp_data.tee, &arg, ARRAY_SIZE(param), param);
75 	if (ret < 0) {
76 		printf("Handshake status command failed\n");
77 		goto out;
78 	}
79 
80 	switch (arg.ret) {
81 	case TEE_SUCCESS:
82 		*hs = param[0].u.value.a;
83 		ret =  0;
84 		break;
85 	default:
86 		ret = -EINVAL;
87 		break;
88 	}
89 
90 out:
91 	tee_close_session(chimp_data.tee, chimp_data.session);
92 	chimp_data.tee = NULL;
93 
94 	return ret;
95 }
96 
chimp_health_status_optee(u32 * health)97 int chimp_health_status_optee(u32 *health)
98 {
99 	struct tee_invoke_arg arg;
100 	struct tee_param param[1];
101 	int ret;
102 
103 	ret = init_arg(&arg, TEE_CHIMP_HEALTH_STATUS);
104 	if (ret < 0)
105 		return ret;
106 
107 	param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT;
108 
109 	ret = tee_invoke_func(chimp_data.tee, &arg, ARRAY_SIZE(param), param);
110 	if (ret < 0) {
111 		printf("Helath status command failed\n");
112 		goto out;
113 	}
114 
115 	switch (arg.ret) {
116 	case TEE_SUCCESS:
117 		*health = param[0].u.value.a;
118 		ret =  0;
119 		break;
120 	default:
121 		ret = -EINVAL;
122 		break;
123 	}
124 
125 out:
126 	tee_close_session(chimp_data.tee, chimp_data.session);
127 	chimp_data.tee = NULL;
128 
129 	return ret;
130 }
131 
chimp_fastboot_optee(void)132 int chimp_fastboot_optee(void)
133 {
134 	struct tee_invoke_arg arg;
135 	int ret;
136 
137 	ret = init_arg(&arg, TEE_CHIMP_FASTBOOT);
138 	if (ret < 0)
139 		return ret;
140 
141 	ret = tee_invoke_func(chimp_data.tee, &arg, 0, NULL);
142 	if (ret < 0) {
143 		printf("Chimp boot_fail\n");
144 		goto out;
145 	}
146 
147 	switch (arg.ret) {
148 	case TEE_SUCCESS:
149 		ret = 0;
150 		break;
151 	default:
152 		ret = -EINVAL;
153 		break;
154 	}
155 
156 out:
157 	tee_close_session(chimp_data.tee, chimp_data.session);
158 	chimp_data.tee = NULL;
159 
160 	return ret;
161 }
162 #else
chimp_handshake_status_optee(u32 timeout,u32 * status)163 int chimp_handshake_status_optee(u32 timeout, u32 *status)
164 {
165 	printf("ChiMP handshake status fail (OPTEE not enabled)\n");
166 
167 	return -EINVAL;
168 }
169 
chimp_health_status_optee(u32 * status)170 int chimp_health_status_optee(u32 *status)
171 {
172 	printf("ChiMP health status fail (OPTEE not enabled)\n");
173 
174 	return -EINVAL;
175 }
176 
chimp_fastboot_optee(void)177 int chimp_fastboot_optee(void)
178 {
179 	printf("ChiMP secure boot fail (OPTEE not enabled)\n");
180 
181 	return -EINVAL;
182 }
183 #endif /* CONFIG_CHIMP_OPTEE */
184