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