1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright 2020, 2023 NXP 4 * 5 */ 6 7#include <common.h> 8#include <hang.h> 9#include <malloc.h> 10#include <asm/io.h> 11#include <dm.h> 12#include <asm/mach-imx/ele_api.h> 13#include <misc.h> 14 15DECLARE_GLOBAL_DATA_PTR; 16 17static u32 compute_crc(const struct ele_msg *msg) 18{ 19 u32 crc = 0; 20 size_t i = 0; 21 u32 *data = (u32 *)msg; 22 23 for (i = 0; i < (msg->size - 1); i++) 24 crc ^= data[i]; 25 26 return crc; 27} 28 29int ele_release_rdc(u8 core_id, u8 xrdc, u32 *response) 30{ 31 struct udevice *dev = gd->arch.ele_dev; 32 int size = sizeof(struct ele_msg); 33 struct ele_msg msg; 34 int ret; 35 36 if (!dev) { 37 printf("ele dev is not initialized\n"); 38 return -ENODEV; 39 } 40 41 msg.version = ELE_VERSION; 42 msg.tag = ELE_CMD_TAG; 43 msg.size = 2; 44 msg.command = ELE_RELEASE_RDC_REQ; 45 switch (xrdc) { 46 case 0: 47 msg.data[0] = (0x74 << 8) | core_id; 48 break; 49 case 1: 50 msg.data[0] = (0x78 << 8) | core_id; 51 break; 52 case 2: 53 msg.data[0] = (0x82 << 8) | core_id; 54 break; 55 case 3: 56 msg.data[0] = (0x86 << 8) | core_id; 57 break; 58 default: 59 printf("Error: wrong xrdc index %u\n", xrdc); 60 return -EINVAL; 61 } 62 63 ret = misc_call(dev, false, &msg, size, &msg, size); 64 if (ret) 65 printf("Error: %s: ret %d, core id %u, response 0x%x\n", 66 __func__, ret, core_id, msg.data[0]); 67 68 if (response) 69 *response = msg.data[0]; 70 71 return ret; 72} 73 74int ele_auth_oem_ctnr(ulong ctnr_addr, u32 *response) 75{ 76 struct udevice *dev = gd->arch.ele_dev; 77 int size = sizeof(struct ele_msg); 78 struct ele_msg msg; 79 int ret; 80 81 if (!dev) { 82 printf("ele dev is not initialized\n"); 83 return -ENODEV; 84 } 85 86 msg.version = ELE_VERSION; 87 msg.tag = ELE_CMD_TAG; 88 msg.size = 3; 89 msg.command = ELE_OEM_CNTN_AUTH_REQ; 90 msg.data[0] = upper_32_bits(ctnr_addr); 91 msg.data[1] = lower_32_bits(ctnr_addr); 92 93 ret = misc_call(dev, false, &msg, size, &msg, size); 94 if (ret) 95 printf("Error: %s: ret %d, cntr_addr 0x%lx, response 0x%x\n", 96 __func__, ret, ctnr_addr, msg.data[0]); 97 98 if (response) 99 *response = msg.data[0]; 100 101 return ret; 102} 103 104int ele_release_container(u32 *response) 105{ 106 struct udevice *dev = gd->arch.ele_dev; 107 int size = sizeof(struct ele_msg); 108 struct ele_msg msg; 109 int ret; 110 111 if (!dev) { 112 printf("ele dev is not initialized\n"); 113 return -ENODEV; 114 } 115 116 msg.version = ELE_VERSION; 117 msg.tag = ELE_CMD_TAG; 118 msg.size = 1; 119 msg.command = ELE_RELEASE_CONTAINER_REQ; 120 121 ret = misc_call(dev, false, &msg, size, &msg, size); 122 if (ret) 123 printf("Error: %s: ret %d, response 0x%x\n", 124 __func__, ret, msg.data[0]); 125 126 if (response) 127 *response = msg.data[0]; 128 129 return ret; 130} 131 132int ele_verify_image(u32 img_id, u32 *response) 133{ 134 struct udevice *dev = gd->arch.ele_dev; 135 int size = sizeof(struct ele_msg); 136 struct ele_msg msg; 137 int ret; 138 139 if (!dev) { 140 printf("ele dev is not initialized\n"); 141 return -ENODEV; 142 } 143 144 msg.version = ELE_VERSION; 145 msg.tag = ELE_CMD_TAG; 146 msg.size = 2; 147 msg.command = ELE_VERIFY_IMAGE_REQ; 148 msg.data[0] = 1 << img_id; 149 150 ret = misc_call(dev, false, &msg, size, &msg, size); 151 if (ret) 152 printf("Error: %s: ret %d, img_id %u, response 0x%x\n", 153 __func__, ret, img_id, msg.data[0]); 154 155 if (response) 156 *response = msg.data[0]; 157 158 return ret; 159} 160 161int ele_forward_lifecycle(u16 life_cycle, u32 *response) 162{ 163 struct udevice *dev = gd->arch.ele_dev; 164 int size = sizeof(struct ele_msg); 165 struct ele_msg msg; 166 int ret; 167 168 if (!dev) { 169 printf("ele dev is not initialized\n"); 170 return -ENODEV; 171 } 172 173 msg.version = ELE_VERSION; 174 msg.tag = ELE_CMD_TAG; 175 msg.size = 2; 176 msg.command = ELE_FWD_LIFECYCLE_UP_REQ; 177 msg.data[0] = life_cycle; 178 179 ret = misc_call(dev, false, &msg, size, &msg, size); 180 if (ret) 181 printf("Error: %s: ret %d, life_cycle 0x%x, response 0x%x\n", 182 __func__, ret, life_cycle, msg.data[0]); 183 184 if (response) 185 *response = msg.data[0]; 186 187 return ret; 188} 189 190int ele_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *response) 191{ 192 struct udevice *dev = gd->arch.ele_dev; 193 int size = sizeof(struct ele_msg); 194 struct ele_msg msg; 195 int ret; 196 197 if (!dev) { 198 printf("ele dev is not initialized\n"); 199 return -ENODEV; 200 } 201 202 if (!fuse_words) { 203 printf("Invalid parameters for fuse read\n"); 204 return -EINVAL; 205 } 206 207 if ((fuse_id != 1 && fuse_num != 1) || 208 (fuse_id == 1 && fuse_num != 4)) { 209 printf("Invalid fuse number parameter\n"); 210 return -EINVAL; 211 } 212 213 msg.version = ELE_VERSION; 214 msg.tag = ELE_CMD_TAG; 215 msg.size = 2; 216 msg.command = ELE_READ_FUSE_REQ; 217 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]; 228 if (fuse_id == 1) { 229 /* 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 238int ele_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response) 239{ 240 struct udevice *dev = gd->arch.ele_dev; 241 int size = sizeof(struct ele_msg); 242 struct ele_msg msg; 243 int ret; 244 245 if (!dev) { 246 printf("ele dev is not initialized\n"); 247 return -ENODEV; 248 } 249 250 msg.version = ELE_VERSION; 251 msg.tag = ELE_CMD_TAG; 252 msg.size = 3; 253 msg.command = ELE_WRITE_FUSE_REQ; 254 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} 270 271int ele_release_caam(u32 core_did, u32 *response) 272{ 273 struct udevice *dev = gd->arch.ele_dev; 274 int size = sizeof(struct ele_msg); 275 struct ele_msg msg; 276 int ret; 277 278 if (!dev) { 279 printf("ele dev is not initialized\n"); 280 return -ENODEV; 281 } 282 283 msg.version = ELE_VERSION; 284 msg.tag = ELE_CMD_TAG; 285 msg.size = 2; 286 msg.command = ELE_RELEASE_CAAM_REQ; 287 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} 299 300int ele_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response) 301{ 302 struct udevice *dev = gd->arch.ele_dev; 303 int size = sizeof(struct ele_msg); 304 struct ele_msg msg; 305 int ret; 306 307 if (!dev) { 308 printf("ele dev is not initialized\n"); 309 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 322 msg.version = ELE_VERSION; 323 msg.tag = ELE_CMD_TAG; 324 msg.size = 1; 325 msg.command = ELE_GET_FW_VERSION_REQ; 326 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 341int ele_dump_buffer(u32 *buffer, u32 buffer_length) 342{ 343 struct udevice *dev = gd->arch.ele_dev; 344 int size = sizeof(struct ele_msg); 345 struct ele_msg msg; 346 int ret, i = 0; 347 348 if (!dev) { 349 printf("ele dev is not initialized\n"); 350 return -ENODEV; 351 } 352 353 msg.version = ELE_VERSION; 354 msg.tag = ELE_CMD_TAG; 355 msg.size = 1; 356 msg.command = ELE_DUMP_DEBUG_BUFFER_REQ; 357 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} 374 375int ele_get_info(struct ele_get_info_data *info, u32 *response) 376{ 377 struct udevice *dev = gd->arch.ele_dev; 378 int size = sizeof(struct ele_msg); 379 struct ele_msg msg; 380 int ret; 381 382 if (!dev) { 383 printf("ele dev is not initialized\n"); 384 return -ENODEV; 385 } 386 387 msg.version = ELE_VERSION; 388 msg.tag = ELE_CMD_TAG; 389 msg.size = 4; 390 msg.command = ELE_GET_INFO_REQ; 391 msg.data[0] = upper_32_bits((ulong)info); 392 msg.data[1] = lower_32_bits((ulong)info); 393 msg.data[2] = sizeof(struct ele_get_info_data); 394 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 406int ele_get_fw_status(u32 *status, u32 *response) 407{ 408 struct udevice *dev = gd->arch.ele_dev; 409 int size = sizeof(struct ele_msg); 410 struct ele_msg msg; 411 int ret; 412 413 if (!dev) { 414 printf("ele dev is not initialized\n"); 415 return -ENODEV; 416 } 417 418 msg.version = ELE_VERSION; 419 msg.tag = ELE_CMD_TAG; 420 msg.size = 1; 421 msg.command = ELE_GET_FW_STATUS_REQ; 422 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} 435 436int ele_release_m33_trout(void) 437{ 438 struct udevice *dev = gd->arch.ele_dev; 439 int size = sizeof(struct ele_msg); 440 struct ele_msg msg; 441 int ret; 442 443 if (!dev) { 444 printf("ele dev is not initialized\n"); 445 return -ENODEV; 446 } 447 448 msg.version = ELE_VERSION; 449 msg.tag = ELE_CMD_TAG; 450 msg.size = 1; 451 msg.command = ELE_ENABLE_RTC_REQ; 452 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} 460 461int ele_get_events(u32 *events, u32 *events_cnt, u32 *response) 462{ 463 struct udevice *dev = gd->arch.ele_dev; 464 int size = sizeof(struct ele_msg); 465 struct ele_msg msg; 466 int ret, i = 0; 467 u32 actual_events; 468 469 if (!dev) { 470 printf("ele dev is not initialized\n"); 471 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 479 msg.version = ELE_VERSION; 480 msg.tag = ELE_CMD_TAG; 481 msg.size = 1; 482 msg.command = ELE_GET_EVENTS_REQ; 483 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} 505 506int 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 531int ele_commit(u16 fuse_id, u32 *response, u32 *info_type) 532{ 533 struct udevice *dev = gd->arch.ele_dev; 534 int size = sizeof(struct ele_msg); 535 struct ele_msg msg; 536 int ret = 0; 537 538 if (!dev) { 539 printf("ele dev is not initialized\n"); 540 return -ENODEV; 541 } 542 543 msg.version = ELE_VERSION; 544 msg.tag = ELE_CMD_TAG; 545 msg.size = 2; 546 msg.command = ELE_COMMIT_REQ; 547 msg.data[0] = fuse_id; 548 549 ret = misc_call(dev, false, &msg, size, &msg, size); 550 if (ret) 551 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n", 552 __func__, ret, fuse_id, msg.data[0]); 553 554 if (response) 555 *response = msg.data[0]; 556 557 if (info_type) 558 *info_type = msg.data[1]; 559 560 return ret; 561} 562 563int ele_write_secure_fuse(ulong signed_msg_blk, u32 *response) 564{ 565 struct udevice *dev = gd->arch.ele_dev; 566 int size = sizeof(struct ele_msg); 567 struct ele_msg msg; 568 int ret; 569 570 if (!dev) { 571 printf("ele dev is not initialized\n"); 572 return -ENODEV; 573 } 574 575 msg.version = ELE_VERSION; 576 msg.tag = ELE_CMD_TAG; 577 msg.size = 3; 578 msg.command = ELE_WRITE_SECURE_FUSE_REQ; 579 580 msg.data[0] = upper_32_bits(signed_msg_blk); 581 msg.data[1] = lower_32_bits(signed_msg_blk); 582 583 ret = misc_call(dev, false, &msg, size, &msg, size); 584 if (ret) 585 printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n", 586 __func__, ret, msg.data[0], msg.data[1]); 587 588 if (response) 589 *response = msg.data[0]; 590 591 return ret; 592} 593 594int ele_return_lifecycle_update(ulong signed_msg_blk, u32 *response) 595{ 596 struct udevice *dev = gd->arch.ele_dev; 597 int size = sizeof(struct ele_msg); 598 struct ele_msg msg; 599 int ret; 600 601 if (!dev) { 602 printf("ele dev is not initialized\n"); 603 return -ENODEV; 604 } 605 606 msg.version = ELE_VERSION; 607 msg.tag = ELE_CMD_TAG; 608 msg.size = 3; 609 msg.command = ELE_RET_LIFECYCLE_UP_REQ; 610 611 msg.data[0] = upper_32_bits(signed_msg_blk); 612 msg.data[1] = lower_32_bits(signed_msg_blk); 613 614 ret = misc_call(dev, false, &msg, size, &msg, size); 615 if (ret) 616 printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n", 617 __func__, ret, msg.data[0], msg.data[1]); 618 619 if (response) 620 *response = msg.data[0]; 621 622 return ret; 623} 624 625int ele_generate_dek_blob(u32 key_id, u32 src_paddr, u32 dst_paddr, u32 max_output_size) 626{ 627 struct udevice *dev = gd->arch.ele_dev; 628 int size = sizeof(struct ele_msg); 629 struct ele_msg msg; 630 int ret; 631 632 if (!dev) { 633 printf("ele dev is not initialized\n"); 634 return -ENODEV; 635 } 636 637 msg.version = ELE_VERSION; 638 msg.tag = ELE_CMD_TAG; 639 msg.size = 8; 640 msg.command = ELE_GENERATE_DEK_BLOB; 641 msg.data[0] = key_id; 642 msg.data[1] = 0x0; 643 msg.data[2] = src_paddr; 644 msg.data[3] = 0x0; 645 msg.data[4] = dst_paddr; 646 msg.data[5] = max_output_size; 647 msg.data[6] = compute_crc(&msg); 648 649 ret = misc_call(dev, false, &msg, size, &msg, size); 650 if (ret) 651 printf("Error: %s: ret 0x%x, response 0x%x\n", 652 __func__, ret, msg.data[0]); 653 654 return ret; 655} 656