blob: 8f321fbf40e4eff3ab9d33fec6d8673e68d42c83 [file] [log] [blame]
Ye Li0db17f42021-08-07 16:00:41 +08001// SPDX-License-Identifier: GPL-2.0
2/*
Peng Fanc88036d2023-06-15 18:09:08 +08003 * Copyright 2020, 2023 NXP
Mathieu Othacehec6143392024-08-26 12:07:07 +02004 * Copyright 2024 Mathieu Othacehe <othacehe@gnu.org>
Ye Li0db17f42021-08-07 16:00:41 +08005 *
6 */
7
Ye Li0db17f42021-08-07 16:00:41 +08008#include <asm/io.h>
Peng Fan00e2e862024-10-06 08:30:02 +08009#include <asm/mach-imx/sys_proto.h>
Peng Fand5c31832023-06-15 18:09:05 +080010#include <asm/mach-imx/ele_api.h>
Peng Fan00e2e862024-10-06 08:30:02 +080011#include <dm.h>
12#include <malloc.h>
13#include <memalign.h>
Ye Li0db17f42021-08-07 16:00:41 +080014#include <misc.h>
15
16DECLARE_GLOBAL_DATA_PTR;
17
Peng Fan16426c82023-06-15 18:09:09 +080018static u32 compute_crc(const struct ele_msg *msg)
19{
20 u32 crc = 0;
21 size_t i = 0;
22 u32 *data = (u32 *)msg;
23
24 for (i = 0; i < (msg->size - 1); i++)
25 crc ^= data[i];
26
27 return crc;
28}
29
Peng Fand5c31832023-06-15 18:09:05 +080030int ele_release_rdc(u8 core_id, u8 xrdc, u32 *response)
Ye Li0db17f42021-08-07 16:00:41 +080031{
Peng Fand5c31832023-06-15 18:09:05 +080032 struct udevice *dev = gd->arch.ele_dev;
33 int size = sizeof(struct ele_msg);
34 struct ele_msg msg;
Ye Li0db17f42021-08-07 16:00:41 +080035 int ret;
36
37 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +080038 printf("ele dev is not initialized\n");
Ye Li0db17f42021-08-07 16:00:41 +080039 return -ENODEV;
40 }
41
Peng Fand5c31832023-06-15 18:09:05 +080042 msg.version = ELE_VERSION;
43 msg.tag = ELE_CMD_TAG;
Ye Li0db17f42021-08-07 16:00:41 +080044 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +080045 msg.command = ELE_RELEASE_RDC_REQ;
Ye Lid4b3ba32022-07-26 16:40:51 +080046 switch (xrdc) {
47 case 0:
Ye Liacc9afe2021-08-07 16:00:53 +080048 msg.data[0] = (0x74 << 8) | core_id;
Ye Lid4b3ba32022-07-26 16:40:51 +080049 break;
50 case 1:
51 msg.data[0] = (0x78 << 8) | core_id;
52 break;
53 case 2:
54 msg.data[0] = (0x82 << 8) | core_id;
55 break;
56 case 3:
57 msg.data[0] = (0x86 << 8) | core_id;
58 break;
59 default:
60 printf("Error: wrong xrdc index %u\n", xrdc);
61 return -EINVAL;
62 }
Ye Li0db17f42021-08-07 16:00:41 +080063
64 ret = misc_call(dev, false, &msg, size, &msg, size);
65 if (ret)
66 printf("Error: %s: ret %d, core id %u, response 0x%x\n",
67 __func__, ret, core_id, msg.data[0]);
68
Ye Lia61f2672021-08-07 16:00:52 +080069 if (response)
70 *response = msg.data[0];
71
72 return ret;
73}
74
Peng Fand5c31832023-06-15 18:09:05 +080075int ele_auth_oem_ctnr(ulong ctnr_addr, u32 *response)
Ye Lia61f2672021-08-07 16:00:52 +080076{
Peng Fand5c31832023-06-15 18:09:05 +080077 struct udevice *dev = gd->arch.ele_dev;
78 int size = sizeof(struct ele_msg);
79 struct ele_msg msg;
Ye Lia61f2672021-08-07 16:00:52 +080080 int ret;
81
82 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +080083 printf("ele dev is not initialized\n");
Ye Lia61f2672021-08-07 16:00:52 +080084 return -ENODEV;
85 }
86
Peng Fand5c31832023-06-15 18:09:05 +080087 msg.version = ELE_VERSION;
88 msg.tag = ELE_CMD_TAG;
Ye Lia61f2672021-08-07 16:00:52 +080089 msg.size = 3;
Ye Liebb2be52023-01-30 18:39:53 +080090 msg.command = ELE_OEM_CNTN_AUTH_REQ;
Ye Lia61f2672021-08-07 16:00:52 +080091 msg.data[0] = upper_32_bits(ctnr_addr);
92 msg.data[1] = lower_32_bits(ctnr_addr);
93
94 ret = misc_call(dev, false, &msg, size, &msg, size);
95 if (ret)
96 printf("Error: %s: ret %d, cntr_addr 0x%lx, response 0x%x\n",
97 __func__, ret, ctnr_addr, msg.data[0]);
98
99 if (response)
100 *response = msg.data[0];
101
102 return ret;
103}
104
Peng Fand5c31832023-06-15 18:09:05 +0800105int ele_release_container(u32 *response)
Ye Lia61f2672021-08-07 16:00:52 +0800106{
Peng Fand5c31832023-06-15 18:09:05 +0800107 struct udevice *dev = gd->arch.ele_dev;
108 int size = sizeof(struct ele_msg);
109 struct ele_msg msg;
Ye Lia61f2672021-08-07 16:00:52 +0800110 int ret;
111
112 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800113 printf("ele dev is not initialized\n");
Ye Lia61f2672021-08-07 16:00:52 +0800114 return -ENODEV;
115 }
116
Peng Fand5c31832023-06-15 18:09:05 +0800117 msg.version = ELE_VERSION;
118 msg.tag = ELE_CMD_TAG;
Ye Lia61f2672021-08-07 16:00:52 +0800119 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800120 msg.command = ELE_RELEASE_CONTAINER_REQ;
Ye Lia61f2672021-08-07 16:00:52 +0800121
122 ret = misc_call(dev, false, &msg, size, &msg, size);
123 if (ret)
124 printf("Error: %s: ret %d, response 0x%x\n",
125 __func__, ret, msg.data[0]);
126
127 if (response)
128 *response = msg.data[0];
129
130 return ret;
131}
132
Peng Fand5c31832023-06-15 18:09:05 +0800133int ele_verify_image(u32 img_id, u32 *response)
Ye Lia61f2672021-08-07 16:00:52 +0800134{
Peng Fand5c31832023-06-15 18:09:05 +0800135 struct udevice *dev = gd->arch.ele_dev;
136 int size = sizeof(struct ele_msg);
137 struct ele_msg msg;
Ye Lia61f2672021-08-07 16:00:52 +0800138 int ret;
139
140 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800141 printf("ele dev is not initialized\n");
Ye Lia61f2672021-08-07 16:00:52 +0800142 return -ENODEV;
143 }
144
Peng Fand5c31832023-06-15 18:09:05 +0800145 msg.version = ELE_VERSION;
146 msg.tag = ELE_CMD_TAG;
Ye Lia61f2672021-08-07 16:00:52 +0800147 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +0800148 msg.command = ELE_VERIFY_IMAGE_REQ;
Ye Lia61f2672021-08-07 16:00:52 +0800149 msg.data[0] = 1 << img_id;
150
151 ret = misc_call(dev, false, &msg, size, &msg, size);
152 if (ret)
153 printf("Error: %s: ret %d, img_id %u, response 0x%x\n",
154 __func__, ret, img_id, msg.data[0]);
155
156 if (response)
157 *response = msg.data[0];
158
159 return ret;
160}
161
Peng Fand5c31832023-06-15 18:09:05 +0800162int ele_forward_lifecycle(u16 life_cycle, u32 *response)
Ye Lia61f2672021-08-07 16:00:52 +0800163{
Peng Fand5c31832023-06-15 18:09:05 +0800164 struct udevice *dev = gd->arch.ele_dev;
165 int size = sizeof(struct ele_msg);
166 struct ele_msg msg;
Ye Lia61f2672021-08-07 16:00:52 +0800167 int ret;
168
169 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800170 printf("ele dev is not initialized\n");
Ye Lia61f2672021-08-07 16:00:52 +0800171 return -ENODEV;
172 }
173
Peng Fand5c31832023-06-15 18:09:05 +0800174 msg.version = ELE_VERSION;
175 msg.tag = ELE_CMD_TAG;
Ye Lia61f2672021-08-07 16:00:52 +0800176 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +0800177 msg.command = ELE_FWD_LIFECYCLE_UP_REQ;
Ye Lia61f2672021-08-07 16:00:52 +0800178 msg.data[0] = life_cycle;
179
180 ret = misc_call(dev, false, &msg, size, &msg, size);
181 if (ret)
182 printf("Error: %s: ret %d, life_cycle 0x%x, response 0x%x\n",
183 __func__, ret, life_cycle, msg.data[0]);
184
185 if (response)
186 *response = msg.data[0];
187
Ye Li0db17f42021-08-07 16:00:41 +0800188 return ret;
189}
Ye Lif80a41b2021-08-07 16:00:54 +0800190
Peng Fand5c31832023-06-15 18:09:05 +0800191int ele_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *response)
Ye Lif80a41b2021-08-07 16:00:54 +0800192{
Peng Fand5c31832023-06-15 18:09:05 +0800193 struct udevice *dev = gd->arch.ele_dev;
194 int size = sizeof(struct ele_msg);
195 struct ele_msg msg;
Ye Lif80a41b2021-08-07 16:00:54 +0800196 int ret;
197
198 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800199 printf("ele dev is not initialized\n");
Ye Lif80a41b2021-08-07 16:00:54 +0800200 return -ENODEV;
201 }
202
203 if (!fuse_words) {
204 printf("Invalid parameters for fuse read\n");
205 return -EINVAL;
206 }
207
Peng Fan00e2e862024-10-06 08:30:02 +0800208 if (is_imx8ulp() && ((fuse_id != 1 && fuse_num != 1) || (fuse_id == 1 && fuse_num != 4))) {
Ye Lif80a41b2021-08-07 16:00:54 +0800209 printf("Invalid fuse number parameter\n");
210 return -EINVAL;
211 }
212
Peng Fand5c31832023-06-15 18:09:05 +0800213 msg.version = ELE_VERSION;
214 msg.tag = ELE_CMD_TAG;
Ye Lif80a41b2021-08-07 16:00:54 +0800215 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +0800216 msg.command = ELE_READ_FUSE_REQ;
Ye Lif80a41b2021-08-07 16:00:54 +0800217 msg.data[0] = fuse_id;
218
219 ret = misc_call(dev, false, &msg, size, &msg, size);
220 if (ret)
221 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
222 __func__, ret, fuse_id, msg.data[0]);
223
224 if (response)
225 *response = msg.data[0];
226
227 fuse_words[0] = msg.data[1];
Peng Fan00e2e862024-10-06 08:30:02 +0800228 if (fuse_id == 1 && is_imx8ulp()) {
Ye Lif80a41b2021-08-07 16:00:54 +0800229 /* OTP_UNIQ_ID */
230 fuse_words[1] = msg.data[2];
231 fuse_words[2] = msg.data[3];
232 fuse_words[3] = msg.data[4];
233 }
234
235 return ret;
236}
237
Peng Fand5c31832023-06-15 18:09:05 +0800238int ele_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response)
Ye Lif80a41b2021-08-07 16:00:54 +0800239{
Peng Fand5c31832023-06-15 18:09:05 +0800240 struct udevice *dev = gd->arch.ele_dev;
241 int size = sizeof(struct ele_msg);
242 struct ele_msg msg;
Ye Lif80a41b2021-08-07 16:00:54 +0800243 int ret;
244
245 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800246 printf("ele dev is not initialized\n");
Ye Lif80a41b2021-08-07 16:00:54 +0800247 return -ENODEV;
248 }
249
Peng Fand5c31832023-06-15 18:09:05 +0800250 msg.version = ELE_VERSION;
251 msg.tag = ELE_CMD_TAG;
Ye Lif80a41b2021-08-07 16:00:54 +0800252 msg.size = 3;
Ye Liebb2be52023-01-30 18:39:53 +0800253 msg.command = ELE_WRITE_FUSE_REQ;
Ye Lif80a41b2021-08-07 16:00:54 +0800254 msg.data[0] = (32 << 16) | (fuse_id << 5);
255 if (lock)
256 msg.data[0] |= (1 << 31);
257
258 msg.data[1] = fuse_val;
259
260 ret = misc_call(dev, false, &msg, size, &msg, size);
261 if (ret)
262 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
263 __func__, ret, fuse_id, msg.data[0]);
264
265 if (response)
266 *response = msg.data[0];
267
268 return ret;
269}
Clement Faure26386ae2022-04-06 14:30:19 +0800270
Peng Fand5c31832023-06-15 18:09:05 +0800271int ele_release_caam(u32 core_did, u32 *response)
Clement Faure26386ae2022-04-06 14:30:19 +0800272{
Peng Fand5c31832023-06-15 18:09:05 +0800273 struct udevice *dev = gd->arch.ele_dev;
274 int size = sizeof(struct ele_msg);
275 struct ele_msg msg;
Clement Faure26386ae2022-04-06 14:30:19 +0800276 int ret;
277
278 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800279 printf("ele dev is not initialized\n");
Clement Faure26386ae2022-04-06 14:30:19 +0800280 return -ENODEV;
281 }
282
Peng Fand5c31832023-06-15 18:09:05 +0800283 msg.version = ELE_VERSION;
284 msg.tag = ELE_CMD_TAG;
Clement Faure26386ae2022-04-06 14:30:19 +0800285 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +0800286 msg.command = ELE_RELEASE_CAAM_REQ;
Clement Faure26386ae2022-04-06 14:30:19 +0800287 msg.data[0] = core_did;
288
289 ret = misc_call(dev, false, &msg, size, &msg, size);
290 if (ret)
291 printf("Error: %s: ret %d, response 0x%x\n",
292 __func__, ret, msg.data[0]);
293
294 if (response)
295 *response = msg.data[0];
296
297 return ret;
298}
Ye Li0a917da2022-04-06 14:30:20 +0800299
Peng Fand5c31832023-06-15 18:09:05 +0800300int ele_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response)
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530301{
Peng Fand5c31832023-06-15 18:09:05 +0800302 struct udevice *dev = gd->arch.ele_dev;
303 int size = sizeof(struct ele_msg);
304 struct ele_msg msg;
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530305 int ret;
306
307 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800308 printf("ele dev is not initialized\n");
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530309 return -ENODEV;
310 }
311
312 if (!fw_version) {
313 printf("Invalid parameters for f/w version read\n");
314 return -EINVAL;
315 }
316
317 if (!sha1) {
318 printf("Invalid parameters for commit sha1\n");
319 return -EINVAL;
320 }
321
Peng Fand5c31832023-06-15 18:09:05 +0800322 msg.version = ELE_VERSION;
323 msg.tag = ELE_CMD_TAG;
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530324 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800325 msg.command = ELE_GET_FW_VERSION_REQ;
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530326
327 ret = misc_call(dev, false, &msg, size, &msg, size);
328 if (ret)
329 printf("Error: %s: ret %d, response 0x%x\n",
330 __func__, ret, msg.data[0]);
331
332 if (response)
333 *response = msg.data[0];
334
335 *fw_version = msg.data[1];
336 *sha1 = msg.data[2];
337
338 return ret;
339}
340
Peng Fand5c31832023-06-15 18:09:05 +0800341int ele_dump_buffer(u32 *buffer, u32 buffer_length)
Ye Li0a917da2022-04-06 14:30:20 +0800342{
Peng Fand5c31832023-06-15 18:09:05 +0800343 struct udevice *dev = gd->arch.ele_dev;
344 int size = sizeof(struct ele_msg);
345 struct ele_msg msg;
Ye Li0a917da2022-04-06 14:30:20 +0800346 int ret, i = 0;
347
348 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800349 printf("ele dev is not initialized\n");
Ye Li0a917da2022-04-06 14:30:20 +0800350 return -ENODEV;
351 }
352
Peng Fand5c31832023-06-15 18:09:05 +0800353 msg.version = ELE_VERSION;
354 msg.tag = ELE_CMD_TAG;
Ye Li0a917da2022-04-06 14:30:20 +0800355 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800356 msg.command = ELE_DUMP_DEBUG_BUFFER_REQ;
Ye Li0a917da2022-04-06 14:30:20 +0800357
358 ret = misc_call(dev, false, &msg, size, &msg, size);
359 if (ret) {
360 printf("Error: %s: ret %d, response 0x%x\n",
361 __func__, ret, msg.data[0]);
362
363 return ret;
364 }
365
366 if (buffer) {
367 buffer[i++] = *(u32 *)&msg; /* Need dump the response header */
368 for (; i < buffer_length && i < msg.size; i++)
369 buffer[i] = msg.data[i - 1];
370 }
371
372 return i;
373}
Peng Fancffe2b92022-07-26 16:40:52 +0800374
Peng Fand5c31832023-06-15 18:09:05 +0800375int ele_get_info(struct ele_get_info_data *info, u32 *response)
Peng Fancffe2b92022-07-26 16:40:52 +0800376{
Peng Fand5c31832023-06-15 18:09:05 +0800377 struct udevice *dev = gd->arch.ele_dev;
378 int size = sizeof(struct ele_msg);
379 struct ele_msg msg;
Peng Fancffe2b92022-07-26 16:40:52 +0800380 int ret;
381
382 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800383 printf("ele dev is not initialized\n");
Peng Fancffe2b92022-07-26 16:40:52 +0800384 return -ENODEV;
385 }
386
Peng Fand5c31832023-06-15 18:09:05 +0800387 msg.version = ELE_VERSION;
388 msg.tag = ELE_CMD_TAG;
Peng Fancffe2b92022-07-26 16:40:52 +0800389 msg.size = 4;
Ye Liebb2be52023-01-30 18:39:53 +0800390 msg.command = ELE_GET_INFO_REQ;
Peng Fancffe2b92022-07-26 16:40:52 +0800391 msg.data[0] = upper_32_bits((ulong)info);
392 msg.data[1] = lower_32_bits((ulong)info);
Peng Fand5c31832023-06-15 18:09:05 +0800393 msg.data[2] = sizeof(struct ele_get_info_data);
Peng Fancffe2b92022-07-26 16:40:52 +0800394
395 ret = misc_call(dev, false, &msg, size, &msg, size);
396 if (ret)
397 printf("Error: %s: ret %d, response 0x%x\n",
398 __func__, ret, msg.data[0]);
399
400 if (response)
401 *response = msg.data[0];
402
403 return ret;
404}
405
Peng Fand5c31832023-06-15 18:09:05 +0800406int ele_get_fw_status(u32 *status, u32 *response)
Peng Fancffe2b92022-07-26 16:40:52 +0800407{
Peng Fand5c31832023-06-15 18:09:05 +0800408 struct udevice *dev = gd->arch.ele_dev;
409 int size = sizeof(struct ele_msg);
410 struct ele_msg msg;
Peng Fancffe2b92022-07-26 16:40:52 +0800411 int ret;
412
413 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800414 printf("ele dev is not initialized\n");
Peng Fancffe2b92022-07-26 16:40:52 +0800415 return -ENODEV;
416 }
417
Peng Fand5c31832023-06-15 18:09:05 +0800418 msg.version = ELE_VERSION;
419 msg.tag = ELE_CMD_TAG;
Peng Fancffe2b92022-07-26 16:40:52 +0800420 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800421 msg.command = ELE_GET_FW_STATUS_REQ;
Peng Fancffe2b92022-07-26 16:40:52 +0800422
423 ret = misc_call(dev, false, &msg, size, &msg, size);
424 if (ret)
425 printf("Error: %s: ret %d, response 0x%x\n",
426 __func__, ret, msg.data[0]);
427
428 if (response)
429 *response = msg.data[0];
430
431 *status = msg.data[1] & 0xF;
432
433 return ret;
434}
Peng Fanf6ff1402022-07-26 16:40:53 +0800435
Peng Fand5c31832023-06-15 18:09:05 +0800436int ele_release_m33_trout(void)
Peng Fanf6ff1402022-07-26 16:40:53 +0800437{
Peng Fand5c31832023-06-15 18:09:05 +0800438 struct udevice *dev = gd->arch.ele_dev;
439 int size = sizeof(struct ele_msg);
440 struct ele_msg msg;
Peng Fanf6ff1402022-07-26 16:40:53 +0800441 int ret;
442
443 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800444 printf("ele dev is not initialized\n");
Peng Fanf6ff1402022-07-26 16:40:53 +0800445 return -ENODEV;
446 }
447
Peng Fand5c31832023-06-15 18:09:05 +0800448 msg.version = ELE_VERSION;
449 msg.tag = ELE_CMD_TAG;
Peng Fanf6ff1402022-07-26 16:40:53 +0800450 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800451 msg.command = ELE_ENABLE_RTC_REQ;
Peng Fanf6ff1402022-07-26 16:40:53 +0800452
453 ret = misc_call(dev, false, &msg, size, &msg, size);
454 if (ret)
455 printf("Error: %s: ret %d, response 0x%x\n",
456 __func__, ret, msg.data[0]);
457
458 return ret;
459}
Ye Li395bfd42023-01-30 18:39:50 +0800460
Peng Fand5c31832023-06-15 18:09:05 +0800461int ele_get_events(u32 *events, u32 *events_cnt, u32 *response)
Ye Li395bfd42023-01-30 18:39:50 +0800462{
Peng Fand5c31832023-06-15 18:09:05 +0800463 struct udevice *dev = gd->arch.ele_dev;
464 int size = sizeof(struct ele_msg);
465 struct ele_msg msg;
Ye Li395bfd42023-01-30 18:39:50 +0800466 int ret, i = 0;
467 u32 actual_events;
468
469 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800470 printf("ele dev is not initialized\n");
Ye Li395bfd42023-01-30 18:39:50 +0800471 return -ENODEV;
472 }
473
474 if (!events || !events_cnt || *events_cnt == 0) {
475 printf("Invalid parameters for %s\n", __func__);
476 return -EINVAL;
477 }
478
Peng Fand5c31832023-06-15 18:09:05 +0800479 msg.version = ELE_VERSION;
480 msg.tag = ELE_CMD_TAG;
Ye Li395bfd42023-01-30 18:39:50 +0800481 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800482 msg.command = ELE_GET_EVENTS_REQ;
Ye Li395bfd42023-01-30 18:39:50 +0800483
484 ret = misc_call(dev, false, &msg, size, &msg, size);
485 if (ret)
486 printf("Error: %s: ret %d, response 0x%x\n",
487 __func__, ret, msg.data[0]);
488
489 if (response)
490 *response = msg.data[0];
491
492 if (!ret) {
493 actual_events = msg.data[1] & 0xffff;
494 if (*events_cnt < actual_events)
495 actual_events = *events_cnt;
496
497 for (; i < actual_events; i++)
498 events[i] = msg.data[i + 2];
499
500 *events_cnt = actual_events;
501 }
502
503 return ret;
504}
Peng Fanc88036d2023-06-15 18:09:08 +0800505
Peng Fanaa70b852023-06-15 18:09:14 +0800506int ele_start_rng(void)
507{
508 struct udevice *dev = gd->arch.ele_dev;
509 int size = sizeof(struct ele_msg);
510 struct ele_msg msg;
511 int ret;
512
513 if (!dev) {
514 printf("ele dev is not initialized\n");
515 return -ENODEV;
516 }
517
518 msg.version = ELE_VERSION;
519 msg.tag = ELE_CMD_TAG;
520 msg.size = 1;
521 msg.command = ELE_START_RNG;
522
523 ret = misc_call(dev, false, &msg, size, &msg, size);
524 if (ret)
525 printf("Error: %s: ret %d, response 0x%x\n",
526 __func__, ret, msg.data[0]);
527
528 return ret;
529}
530
Mathieu Othacehec6143392024-08-26 12:07:07 +0200531int ele_derive_huk(u8 *key, size_t key_size, u8 *seed, size_t seed_size)
532{
533 struct udevice *dev = gd->arch.ele_dev;
534 struct ele_msg msg;
535 int msg_size = sizeof(struct ele_msg);
536 u8 *seed_aligned, *key_aligned;
537 int ret, size;
538
539 if (!dev) {
540 printf("ele dev is not initialized\n");
541 return -ENODEV;
542 }
543
544 if (key_size != 16 && key_size != 32) {
545 printf("key size can only be 16 or 32\n");
546 return -EINVAL;
547 }
548
549 if (seed_size >= (1U << 16) - 1) {
550 printf("seed size is too large\n");
551 return -EINVAL;
552 }
553
554 seed_aligned = memalign(ARCH_DMA_MINALIGN, seed_size);
555 if (!seed_aligned) {
556 printf("failed to alloc memory\n");
557 return -EINVAL;
558 }
559 memcpy(seed_aligned, seed, seed_size);
560
561 key_aligned = memalign(ARCH_DMA_MINALIGN, key_size);
562 if (!key_aligned) {
563 printf("failed to alloc memory\n");
564 ret = -EINVAL;
565 goto ret_seed;
566 }
567
568 size = ALIGN(seed_size, ARCH_DMA_MINALIGN);
569 flush_dcache_range((ulong)seed_aligned,
570 (ulong)seed_aligned + size);
571
572 size = ALIGN(key_size, ARCH_DMA_MINALIGN);
573 invalidate_dcache_range((ulong)key_aligned,
574 (ulong)key_aligned + size);
575
576 msg.version = ELE_VERSION;
577 msg.tag = ELE_CMD_TAG;
578 msg.size = 7;
579 msg.command = ELE_CMD_DERIVE_KEY;
580 msg.data[0] = upper_32_bits((ulong)key_aligned);
581 msg.data[1] = lower_32_bits((ulong)key_aligned);
582 msg.data[2] = upper_32_bits((ulong)seed_aligned);
583 msg.data[3] = lower_32_bits((ulong)seed_aligned);
584 msg.data[4] = seed_size << 16 | key_size;
585 msg.data[5] = compute_crc(&msg);
586
587 ret = misc_call(dev, false, &msg, msg_size, &msg, msg_size);
588 if (ret) {
589 printf("Error: %s: ret %d, response 0x%x\n",
590 __func__, ret, msg.data[0]);
591 goto ret_key;
592 }
593
594 invalidate_dcache_range((ulong)key_aligned,
595 (ulong)key_aligned + size);
596 memcpy(key, key_aligned, key_size);
597
598ret_key:
599 free(key_aligned);
600ret_seed:
601 free(seed_aligned);
602
603 return ret;
604}
605
Mathieu Othacehe8df8e592024-03-21 08:19:53 +0100606int ele_commit(u16 fuse_id, u32 *response, u32 *info_type)
607{
608 struct udevice *dev = gd->arch.ele_dev;
609 int size = sizeof(struct ele_msg);
610 struct ele_msg msg;
611 int ret = 0;
612
613 if (!dev) {
614 printf("ele dev is not initialized\n");
615 return -ENODEV;
616 }
617
618 msg.version = ELE_VERSION;
619 msg.tag = ELE_CMD_TAG;
620 msg.size = 2;
621 msg.command = ELE_COMMIT_REQ;
622 msg.data[0] = fuse_id;
623
624 ret = misc_call(dev, false, &msg, size, &msg, size);
625 if (ret)
626 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
627 __func__, ret, fuse_id, msg.data[0]);
628
629 if (response)
630 *response = msg.data[0];
631
632 if (info_type)
633 *info_type = msg.data[1];
634
635 return ret;
636}
637
Peng Fanc88036d2023-06-15 18:09:08 +0800638int ele_write_secure_fuse(ulong signed_msg_blk, u32 *response)
639{
640 struct udevice *dev = gd->arch.ele_dev;
641 int size = sizeof(struct ele_msg);
642 struct ele_msg msg;
643 int ret;
644
645 if (!dev) {
646 printf("ele dev is not initialized\n");
647 return -ENODEV;
648 }
649
650 msg.version = ELE_VERSION;
651 msg.tag = ELE_CMD_TAG;
652 msg.size = 3;
653 msg.command = ELE_WRITE_SECURE_FUSE_REQ;
654
655 msg.data[0] = upper_32_bits(signed_msg_blk);
656 msg.data[1] = lower_32_bits(signed_msg_blk);
657
658 ret = misc_call(dev, false, &msg, size, &msg, size);
659 if (ret)
660 printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n",
661 __func__, ret, msg.data[0], msg.data[1]);
662
663 if (response)
664 *response = msg.data[0];
665
666 return ret;
667}
668
669int ele_return_lifecycle_update(ulong signed_msg_blk, u32 *response)
670{
671 struct udevice *dev = gd->arch.ele_dev;
672 int size = sizeof(struct ele_msg);
673 struct ele_msg msg;
674 int ret;
675
676 if (!dev) {
677 printf("ele dev is not initialized\n");
678 return -ENODEV;
679 }
680
681 msg.version = ELE_VERSION;
682 msg.tag = ELE_CMD_TAG;
683 msg.size = 3;
684 msg.command = ELE_RET_LIFECYCLE_UP_REQ;
685
686 msg.data[0] = upper_32_bits(signed_msg_blk);
687 msg.data[1] = lower_32_bits(signed_msg_blk);
688
689 ret = misc_call(dev, false, &msg, size, &msg, size);
690 if (ret)
691 printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n",
692 __func__, ret, msg.data[0], msg.data[1]);
693
694 if (response)
695 *response = msg.data[0];
696
697 return ret;
698}
Peng Fan16426c82023-06-15 18:09:09 +0800699
700int ele_generate_dek_blob(u32 key_id, u32 src_paddr, u32 dst_paddr, u32 max_output_size)
701{
702 struct udevice *dev = gd->arch.ele_dev;
703 int size = sizeof(struct ele_msg);
704 struct ele_msg msg;
705 int ret;
706
707 if (!dev) {
708 printf("ele dev is not initialized\n");
709 return -ENODEV;
710 }
711
712 msg.version = ELE_VERSION;
713 msg.tag = ELE_CMD_TAG;
714 msg.size = 8;
715 msg.command = ELE_GENERATE_DEK_BLOB;
716 msg.data[0] = key_id;
717 msg.data[1] = 0x0;
718 msg.data[2] = src_paddr;
719 msg.data[3] = 0x0;
720 msg.data[4] = dst_paddr;
721 msg.data[5] = max_output_size;
722 msg.data[6] = compute_crc(&msg);
723
724 ret = misc_call(dev, false, &msg, size, &msg, size);
725 if (ret)
726 printf("Error: %s: ret 0x%x, response 0x%x\n",
727 __func__, ret, msg.data[0]);
728
729 return ret;
730}