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