1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2022 NXP 4 */ 5 6#include <common.h> 7#include <command.h> 8#include <errno.h> 9#include <imx_container.h> 10#include <asm/io.h> 11#include <asm/mach-imx/ele_api.h> 12#include <asm/mach-imx/sys_proto.h> 13#include <asm/arch-imx/cpu.h> 14#include <asm/arch/sys_proto.h> 15#include <console.h> 16#include <cpu_func.h> 17#include <asm/global_data.h> 18 19DECLARE_GLOBAL_DATA_PTR; 20 21#define IMG_CONTAINER_END_BASE (IMG_CONTAINER_BASE + 0xFFFFUL) 22 23#define AHAB_MAX_EVENTS 8 24 25static char *ele_ipc_str[] = { 26 "IPC = MU RTD (0x1)\n", 27 "IPC = MU APD (0x2)\n", 28 "IPC = INVALID\n", 29 NULL 30}; 31 32static char *ele_status_str[] = { 33 "STA = ELE_SUCCESS_IND (0xD6)\n", 34 "STA = ELE_FAILURE_IND (0x29)\n", 35 "STA = INVALID\n", 36 NULL 37}; 38 39static char *ele_cmd_str[] = { 40 "CMD = ELE_PING_REQ (0x01)\n", 41 "CMD = ELE_FW_AUTH_REQ (0x02)\n", 42 "CMD = ELE_RESTART_RST_TIMER_REQ (0x04)\n", 43 "CMD = ELE_DUMP_DEBUG_BUFFER_REQ (0x21)\n", 44 "CMD = ELE_OEM_CNTN_AUTH_REQ (0x87)\n", 45 "CMD = ELE_VERIFY_IMAGE_REQ (0x88)\n", 46 "CMD = ELE_RELEASE_CONTAINER_REQ (0x89)\n", 47 "CMD = ELE_WRITE_SECURE_FUSE_REQ (0x91)\n", 48 "CMD = ELE_FWD_LIFECYCLE_UP_REQ (0x95)\n", 49 "CMD = ELE_READ_FUSE_REQ (0x97)\n", 50 "CMD = ELE_GET_FW_VERSION_REQ (0x9D)\n", 51 "CMD = ELE_RET_LIFECYCLE_UP_REQ (0xA0)\n", 52 "CMD = ELE_GET_EVENTS_REQ (0xA2)\n", 53 "CMD = ELE_ENABLE_PATCH_REQ (0xC3)\n", 54 "CMD = ELE_RELEASE_RDC_REQ (0xC4)\n", 55 "CMD = ELE_GET_FW_STATUS_REQ (0xC5)\n", 56 "CMD = ELE_ENABLE_OTFAD_REQ (0xC6)\n", 57 "CMD = ELE_RESET_REQ (0xC7)\n", 58 "CMD = ELE_UPDATE_OTP_CLKDIV_REQ (0xD0)\n", 59 "CMD = ELE_POWER_DOWN_REQ (0xD1)\n", 60 "CMD = ELE_ENABLE_APC_REQ (0xD2)\n", 61 "CMD = ELE_ENABLE_RTC_REQ (0xD3)\n", 62 "CMD = ELE_DEEP_POWER_DOWN_REQ (0xD4)\n", 63 "CMD = ELE_STOP_RST_TIMER_REQ (0xD5)\n", 64 "CMD = ELE_WRITE_FUSE_REQ (0xD6)\n", 65 "CMD = ELE_RELEASE_CAAM_REQ (0xD7)\n", 66 "CMD = ELE_RESET_A35_CTX_REQ (0xD8)\n", 67 "CMD = ELE_MOVE_TO_UNSECURED_REQ (0xD9)\n", 68 "CMD = ELE_GET_INFO_REQ (0xDA)\n", 69 "CMD = ELE_ATTEST_REQ (0xDB)\n", 70 "CMD = ELE_RELEASE_PATCH_REQ (0xDC)\n", 71 "CMD = ELE_OTP_SEQ_SWITH_REQ (0xDD)\n", 72 "CMD = INVALID\n", 73 NULL 74}; 75 76static char *ele_ind_str[] = { 77 "IND = ELE_ROM_PING_FAILURE_IND (0x0A)\n", 78 "IND = ELE_FW_PING_FAILURE_IND (0x1A)\n", 79 "IND = ELE_BAD_SIGNATURE_FAILURE_IND (0xF0)\n", 80 "IND = ELE_BAD_HASH_FAILURE_IND (0xF1)\n", 81 "IND = ELE_INVALID_LIFECYCLE_IND (0xF2)\n", 82 "IND = ELE_PERMISSION_DENIED_FAILURE_IND (0xF3)\n", 83 "IND = ELE_INVALID_MESSAGE_FAILURE_IND (0xF4)\n", 84 "IND = ELE_BAD_VALUE_FAILURE_IND (0xF5)\n", 85 "IND = ELE_BAD_FUSE_ID_FAILURE_IND (0xF6)\n", 86 "IND = ELE_BAD_CONTAINER_FAILURE_IND (0xF7)\n", 87 "IND = ELE_BAD_VERSION_FAILURE_IND (0xF8)\n", 88 "IND = ELE_INVALID_KEY_FAILURE_IND (0xF9)\n", 89 "IND = ELE_BAD_KEY_HASH_FAILURE_IND (0xFA)\n", 90 "IND = ELE_NO_VALID_CONTAINER_FAILURE_IND (0xFB)\n", 91 "IND = ELE_BAD_CERTIFICATE_FAILURE_IND (0xFC)\n", 92 "IND = ELE_BAD_UID_FAILURE_IND (0xFD)\n", 93 "IND = ELE_BAD_MONOTONIC_COUNTER_FAILURE_IND (0xFE)\n", 94 "IND = ELE_MUST_SIGNED_FAILURE_IND (0xE0)\n", 95 "IND = ELE_NO_AUTHENTICATION_FAILURE_IND (0xEE)\n", 96 "IND = ELE_BAD_SRK_SET_FAILURE_IND (0xEF)\n", 97 "IND = ELE_UNALIGNED_PAYLOAD_FAILURE_IND (0xA6)\n", 98 "IND = ELE_WRONG_SIZE_FAILURE_IND (0xA7)\n", 99 "IND = ELE_ENCRYPTION_FAILURE_IND (0xA8)\n", 100 "IND = ELE_DECRYPTION_FAILURE_IND (0xA9)\n", 101 "IND = ELE_OTP_PROGFAIL_FAILURE_IND (0xAA)\n", 102 "IND = ELE_OTP_LOCKED_FAILURE_IND (0xAB)\n", 103 "IND = ELE_OTP_INVALID_IDX_FAILURE_IND (0xAD)\n", 104 "IND = ELE_TIME_OUT_FAILURE_IND (0xB0)\n", 105 "IND = ELE_BAD_PAYLOAD_FAILURE_IND (0xB1)\n", 106 "IND = ELE_WRONG_ADDRESS_FAILURE_IND (0xB4)\n", 107 "IND = ELE_DMA_FAILURE_IND (0xB5)\n", 108 "IND = ELE_DISABLED_FEATURE_FAILURE_IND (0xB6)\n", 109 "IND = ELE_MUST_ATTEST_FAILURE_IND (0xB7)\n", 110 "IND = ELE_RNG_NOT_STARTED_FAILURE_IND (0xB8)\n", 111 "IND = ELE_CRC_ERROR_IND (0xB9)\n", 112 "IND = ELE_AUTH_SKIPPED_OR_FAILED_FAILURE_IND (0xBB)\n", 113 "IND = ELE_INCONSISTENT_PAR_FAILURE_IND (0xBC)\n", 114 "IND = ELE_RNG_INST_FAILURE_FAILURE_IND (0xBD)\n", 115 "IND = ELE_LOCKED_REG_FAILURE_IND (0xBE)\n", 116 "IND = ELE_BAD_ID_FAILURE_IND (0xBF)\n", 117 "IND = ELE_INVALID_OPERATION_FAILURE_IND (0xC0)\n", 118 "IND = ELE_NON_SECURE_STATE_FAILURE_IND (0xC1)\n", 119 "IND = ELE_MSG_TRUNCATED_IND (0xC2)\n", 120 "IND = ELE_BAD_IMAGE_NUM_FAILURE_IND (0xC3)\n", 121 "IND = ELE_BAD_IMAGE_ADDR_FAILURE_IND (0xC4)\n", 122 "IND = ELE_BAD_IMAGE_PARAM_FAILURE_IND (0xC5)\n", 123 "IND = ELE_BAD_IMAGE_TYPE_FAILURE_IND (0xC6)\n", 124 "IND = ELE_CORRUPTED_SRK_FAILURE_IND (0xD0)\n", 125 "IND = ELE_OUT_OF_MEMORY_IND (0xD1)\n", 126 "IND = ELE_CSTM_FAILURE_IND (0xCF)\n", 127 "IND = ELE_OLD_VERSION_FAILURE_IND (0xCE)\n", 128 "IND = ELE_WRONG_BOOT_MODE_FAILURE_IND (0xCD)\n", 129 "IND = ELE_APC_ALREADY_ENABLED_FAILURE_IND (0xCB)\n", 130 "IND = ELE_RTC_ALREADY_ENABLED_FAILURE_IND (0xCC)\n", 131 "IND = ELE_ABORT_IND (0xFF)\n", 132 "IND = INVALID\n", 133 NULL 134}; 135 136static u8 ele_cmd[] = { 137 ELE_PING_REQ, 138 ELE_FW_AUTH_REQ, 139 ELE_RESTART_RST_TIMER_REQ, 140 ELE_DUMP_DEBUG_BUFFER_REQ, 141 ELE_OEM_CNTN_AUTH_REQ, 142 ELE_VERIFY_IMAGE_REQ, 143 ELE_RELEASE_CONTAINER_REQ, 144 ELE_WRITE_SECURE_FUSE_REQ, 145 ELE_FWD_LIFECYCLE_UP_REQ, 146 ELE_READ_FUSE_REQ, 147 ELE_GET_FW_VERSION_REQ, 148 ELE_RET_LIFECYCLE_UP_REQ, 149 ELE_GET_EVENTS_REQ, 150 ELE_ENABLE_PATCH_REQ, 151 ELE_RELEASE_RDC_REQ, 152 ELE_GET_FW_STATUS_REQ, 153 ELE_ENABLE_OTFAD_REQ, 154 ELE_RESET_REQ, 155 ELE_UPDATE_OTP_CLKDIV_REQ, 156 ELE_POWER_DOWN_REQ, 157 ELE_ENABLE_APC_REQ, 158 ELE_ENABLE_RTC_REQ, 159 ELE_DEEP_POWER_DOWN_REQ, 160 ELE_STOP_RST_TIMER_REQ, 161 ELE_WRITE_FUSE_REQ, 162 ELE_RELEASE_CAAM_REQ, 163 ELE_RESET_A35_CTX_REQ, 164 ELE_MOVE_TO_UNSECURED_REQ, 165 ELE_GET_INFO_REQ, 166 ELE_ATTEST_REQ, 167 ELE_RELEASE_PATCH_REQ, 168 ELE_OTP_SEQ_SWITH_REQ 169}; 170 171static u8 ele_ind[] = { 172 ELE_ROM_PING_FAILURE_IND, 173 ELE_FW_PING_FAILURE_IND, 174 ELE_BAD_SIGNATURE_FAILURE_IND, 175 ELE_BAD_HASH_FAILURE_IND, 176 ELE_INVALID_LIFECYCLE_IND, 177 ELE_PERMISSION_DENIED_FAILURE_IND, 178 ELE_INVALID_MESSAGE_FAILURE_IND, 179 ELE_BAD_VALUE_FAILURE_IND, 180 ELE_BAD_FUSE_ID_FAILURE_IND, 181 ELE_BAD_CONTAINER_FAILURE_IND, 182 ELE_BAD_VERSION_FAILURE_IND, 183 ELE_INVALID_KEY_FAILURE_IND, 184 ELE_BAD_KEY_HASH_FAILURE_IND, 185 ELE_NO_VALID_CONTAINER_FAILURE_IND, 186 ELE_BAD_CERTIFICATE_FAILURE_IND, 187 ELE_BAD_UID_FAILURE_IND, 188 ELE_BAD_MONOTONIC_COUNTER_FAILURE_IND, 189 ELE_MUST_SIGNED_FAILURE_IND, 190 ELE_NO_AUTHENTICATION_FAILURE_IND, 191 ELE_BAD_SRK_SET_FAILURE_IND, 192 ELE_UNALIGNED_PAYLOAD_FAILURE_IND, 193 ELE_WRONG_SIZE_FAILURE_IND, 194 ELE_ENCRYPTION_FAILURE_IND, 195 ELE_DECRYPTION_FAILURE_IND, 196 ELE_OTP_PROGFAIL_FAILURE_IND, 197 ELE_OTP_LOCKED_FAILURE_IND, 198 ELE_OTP_INVALID_IDX_FAILURE_IND, 199 ELE_TIME_OUT_FAILURE_IND, 200 ELE_BAD_PAYLOAD_FAILURE_IND, 201 ELE_WRONG_ADDRESS_FAILURE_IND, 202 ELE_DMA_FAILURE_IND, 203 ELE_DISABLED_FEATURE_FAILURE_IND, 204 ELE_MUST_ATTEST_FAILURE_IND, 205 ELE_RNG_NOT_STARTED_FAILURE_IND, 206 ELE_CRC_ERROR_IND, 207 ELE_AUTH_SKIPPED_OR_FAILED_FAILURE_IND, 208 ELE_INCONSISTENT_PAR_FAILURE_IND, 209 ELE_RNG_INST_FAILURE_FAILURE_IND, 210 ELE_LOCKED_REG_FAILURE_IND, 211 ELE_BAD_ID_FAILURE_IND, 212 ELE_INVALID_OPERATION_FAILURE_IND, 213 ELE_NON_SECURE_STATE_FAILURE_IND, 214 ELE_MSG_TRUNCATED_IND, 215 ELE_BAD_IMAGE_NUM_FAILURE_IND, 216 ELE_BAD_IMAGE_ADDR_FAILURE_IND, 217 ELE_BAD_IMAGE_PARAM_FAILURE_IND, 218 ELE_BAD_IMAGE_TYPE_FAILURE_IND, 219 ELE_CORRUPTED_SRK_FAILURE_IND, 220 ELE_OUT_OF_MEMORY_IND, 221 ELE_CSTM_FAILURE_IND, 222 ELE_OLD_VERSION_FAILURE_IND, 223 ELE_WRONG_BOOT_MODE_FAILURE_IND, 224 ELE_APC_ALREADY_ENABLED_FAILURE_IND, 225 ELE_RTC_ALREADY_ENABLED_FAILURE_IND, 226 ELE_ABORT_IND 227}; 228 229static u8 ele_ipc[] = { 230 ELE_IPC_MU_RTD, 231 ELE_IPC_MU_APD 232}; 233 234static u8 ele_status[] = { 235 ELE_SUCCESS_IND, 236 ELE_FAILURE_IND 237}; 238 239static inline u32 get_idx(u8 *list, u8 tgt, u32 size) 240{ 241 u32 i; 242 243 for (i = 0; i < size; i++) { 244 if (list[i] == tgt) 245 return i; 246 } 247 248 return i; /* last str is invalid */ 249} 250 251static void display_ahab_auth_ind(u32 event) 252{ 253 u8 resp_ind = (event >> 8) & 0xff; 254 255 printf("%s\n", ele_ind_str[get_idx(ele_ind, resp_ind, ARRAY_SIZE(ele_ind))]); 256} 257 258int ahab_auth_cntr_hdr(struct container_hdr *container, u16 length) 259{ 260 int err; 261 u32 resp; 262 263 memcpy((void *)IMG_CONTAINER_BASE, (const void *)container, 264 ALIGN(length, CONFIG_SYS_CACHELINE_SIZE)); 265 266 flush_dcache_range(IMG_CONTAINER_BASE, 267 IMG_CONTAINER_BASE + ALIGN(length, CONFIG_SYS_CACHELINE_SIZE) - 1); 268 269 err = ele_auth_oem_ctnr(IMG_CONTAINER_BASE, &resp); 270 if (err) { 271 printf("Authenticate container hdr failed, return %d, resp 0x%x\n", 272 err, resp); 273 display_ahab_auth_ind(resp); 274 } 275 276 return err; 277} 278 279int ahab_auth_release(void) 280{ 281 int err; 282 u32 resp; 283 284 err = ele_release_container(&resp); 285 if (err) { 286 printf("Error: release container failed, resp 0x%x!\n", resp); 287 display_ahab_auth_ind(resp); 288 } 289 290 return err; 291} 292 293int ahab_verify_cntr_image(struct boot_img_t *img, int image_index) 294{ 295 int err; 296 u32 resp; 297 298 err = ele_verify_image(image_index, &resp); 299 if (err) { 300 printf("Authenticate img %d failed, return %d, resp 0x%x\n", 301 image_index, err, resp); 302 display_ahab_auth_ind(resp); 303 304 return -EIO; 305 } 306 307 return 0; 308} 309 310static inline bool check_in_dram(ulong addr) 311{ 312 int i; 313 struct bd_info *bd = gd->bd; 314 315 for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) { 316 if (bd->bi_dram[i].size) { 317 if (addr >= bd->bi_dram[i].start && 318 addr < (bd->bi_dram[i].start + bd->bi_dram[i].size)) 319 return true; 320 } 321 } 322 323 return false; 324} 325 326int authenticate_os_container(ulong addr) 327{ 328 struct container_hdr *phdr; 329 int i, ret = 0; 330 int err; 331 u16 length; 332 struct boot_img_t *img; 333 unsigned long s, e; 334 335 if (addr % 4) { 336 puts("Error: Image's address is not 4 byte aligned\n"); 337 return -EINVAL; 338 } 339 340 if (!check_in_dram(addr)) { 341 puts("Error: Image's address is invalid\n"); 342 return -EINVAL; 343 } 344 345 phdr = (struct container_hdr *)addr; 346 if (!valid_container_hdr(phdr)) { 347 printf("Error: Wrong container header\n"); 348 return -EFAULT; 349 } 350 351 if (!phdr->num_images) { 352 printf("Error: Wrong container, no image found\n"); 353 return -EFAULT; 354 } 355 356 length = phdr->length_lsb + (phdr->length_msb << 8); 357 358 debug("container length %u\n", length); 359 360 err = ahab_auth_cntr_hdr(phdr, length); 361 if (err) { 362 ret = -EIO; 363 goto exit; 364 } 365 366 debug("Verify images\n"); 367 368 /* Copy images to dest address */ 369 for (i = 0; i < phdr->num_images; i++) { 370 img = (struct boot_img_t *)(addr + 371 sizeof(struct container_hdr) + 372 i * sizeof(struct boot_img_t)); 373 374 debug("img %d, dst 0x%x, src 0x%lx, size 0x%x\n", 375 i, (uint32_t)img->dst, img->offset + addr, img->size); 376 377 memcpy((void *)img->dst, (const void *)(img->offset + addr), 378 img->size); 379 380 s = img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1); 381 e = ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE) - 1; 382 383 flush_dcache_range(s, e); 384 385 ret = ahab_verify_cntr_image(img, i); 386 if (ret) 387 goto exit; 388 } 389 390exit: 391 debug("ahab_auth_release, 0x%x\n", ret); 392 ahab_auth_release(); 393 394 return ret; 395} 396 397static int do_authenticate(struct cmd_tbl *cmdtp, int flag, int argc, 398 char *const argv[]) 399{ 400 ulong addr; 401 402 if (argc < 2) 403 return CMD_RET_USAGE; 404 405 addr = hextoul(argv[1], NULL); 406 407 printf("Authenticate OS container at 0x%lx\n", addr); 408 409 if (authenticate_os_container(addr)) 410 return CMD_RET_FAILURE; 411 412 return CMD_RET_SUCCESS; 413} 414 415static void display_life_cycle(u32 lc) 416{ 417 printf("Lifecycle: 0x%08X, ", lc); 418 switch (lc) { 419 case 0x1: 420 printf("BLANK\n\n"); 421 break; 422 case 0x2: 423 printf("FAB\n\n"); 424 break; 425 case 0x4: 426 printf("NXP Provisioned\n\n"); 427 break; 428 case 0x8: 429 printf("OEM Open\n\n"); 430 break; 431 case 0x20: 432 printf("OEM closed\n\n"); 433 break; 434 case 0x40: 435 printf("Field Return OEM\n\n"); 436 break; 437 case 0x80: 438 printf("Field Return NXP\n\n"); 439 break; 440 case 0x100: 441 printf("OEM Locked\n\n"); 442 break; 443 case 0x200: 444 printf("BRICKED\n\n"); 445 break; 446 default: 447 printf("Unknown\n\n"); 448 break; 449 } 450} 451 452static int confirm_close(void) 453{ 454 puts("Warning: Please ensure your sample is in NXP closed state, " 455 "OEM SRK hash has been fused, \n" 456 " and you are able to boot a signed image successfully " 457 "without any SECO events reported.\n" 458 " If not, your sample will be unrecoverable.\n" 459 "\nReally perform this operation? <y/N>\n"); 460 461 if (confirm_yesno()) 462 return 1; 463 464 puts("Ahab close aborted\n"); 465 return 0; 466} 467 468static int do_ahab_close(struct cmd_tbl *cmdtp, int flag, int argc, 469 char *const argv[]) 470{ 471 int err; 472 u32 resp; 473 u32 lc; 474 475 if (!confirm_close()) 476 return -EACCES; 477 478 lc = readl(FSB_BASE_ADDR + 0x41c); 479 lc &= 0x3ff; 480 481 if (lc != 0x8) { 482 puts("Current lifecycle is NOT OEM open, can't move to OEM closed\n"); 483 display_life_cycle(lc); 484 return -EPERM; 485 } 486 487 err = ele_forward_lifecycle(8, &resp); 488 if (err != 0) { 489 printf("Error in forward lifecycle to OEM closed\n"); 490 return -EIO; 491 } 492 493 printf("Change to OEM closed successfully\n"); 494 495 return 0; 496} 497 498int ahab_dump(void) 499{ 500 u32 buffer[32]; 501 int ret, i = 0; 502 503 do { 504 ret = ele_dump_buffer(buffer, 32); 505 if (ret < 0) { 506 printf("Error in dump AHAB log\n"); 507 return -EIO; 508 } 509 510 if (ret == 1) 511 break; 512 for (i = 0; i < ret; i++) 513 printf("0x%x\n", buffer[i]); 514 } while (ret >= 21); 515 516 return 0; 517} 518 519static int do_ahab_dump(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 520{ 521 return ahab_dump(); 522} 523 524static void display_event(u32 event) 525{ 526 printf("\n\t0x%08x\n", event); 527 printf("\t%s", ele_ipc_str[get_idx(ele_ipc, 528 (event >> 24) & 0xFF, ARRAY_SIZE(ele_ipc))]); 529 printf("\t%s", ele_cmd_str[get_idx(ele_cmd, 530 (event >> 16) & 0xFF, ARRAY_SIZE(ele_cmd))]); 531 printf("\t%s", ele_ind_str[get_idx(ele_ind, 532 (event >> 8) & 0xFF, ARRAY_SIZE(ele_ind))]); 533 printf("\t%s", ele_status_str[get_idx(ele_status, 534 event & 0xFF, ARRAY_SIZE(ele_status))]); 535} 536 537static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 538{ 539 u32 lc, i; 540 u32 events[AHAB_MAX_EVENTS]; 541 u32 cnt = AHAB_MAX_EVENTS; 542 int ret; 543 544 lc = readl(FSB_BASE_ADDR + 0x41c); 545 lc &= 0x3ff; 546 547 display_life_cycle(lc); 548 549 ret = ele_get_events(events, &cnt, NULL); 550 if (ret) { 551 printf("Get ELE EVENTS error %d\n", ret); 552 return CMD_RET_FAILURE; 553 } 554 555 if (!cnt) { 556 puts("\n\tNo Events Found!\n"); 557 return 0; 558 } 559 560 for (i = 0; i < cnt; i++) 561 display_event(events[i]); 562 563 return 0; 564} 565 566static int do_sec_fuse_prog(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 567{ 568 ulong addr; 569 u32 header, response; 570 571 if (argc < 2) 572 return CMD_RET_USAGE; 573 574 addr = hextoul(argv[1], NULL); 575 header = *(u32 *)addr; 576 577 if ((header & 0xff0000ff) != 0x89000000) { 578 printf("Wrong Signed message block format, header 0x%x\n", header); 579 return CMD_RET_FAILURE; 580 } 581 582 header = (header & 0xffff00) >> 8; 583 584 printf("Signed Message block at 0x%lx, size 0x%x\n", addr, header); 585 flush_dcache_range(addr, addr + header - 1); 586 587 if (ele_write_secure_fuse(addr, &response)) { 588 printf("Program secure fuse failed, response 0x%x\n", response); 589 return CMD_RET_FAILURE; 590 } 591 592 printf("Program secure fuse completed, response 0x%x\n", response); 593 594 return CMD_RET_SUCCESS; 595} 596 597static int do_ahab_return_lifecycle(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 598{ 599 ulong addr; 600 u32 header, response; 601 602 if (argc < 2) 603 return CMD_RET_USAGE; 604 605 addr = hextoul(argv[1], NULL); 606 header = *(u32 *)addr; 607 608 if ((header & 0xff0000ff) != 0x89000000) { 609 printf("Wrong Signed message block format, header 0x%x\n", header); 610 return CMD_RET_FAILURE; 611 } 612 613 header = (header & 0xffff00) >> 8; 614 615 printf("Signed Message block at 0x%lx, size 0x%x\n", addr, header); 616 flush_dcache_range(addr, addr + header - 1); 617 618 if (ele_return_lifecycle_update(addr, &response)) { 619 printf("Return lifecycle failed, response 0x%x\n", response); 620 return CMD_RET_FAILURE; 621 } 622 623 printf("Return lifecycle completed, response 0x%x\n", response); 624 625 return CMD_RET_SUCCESS; 626} 627 628static int do_ahab_commit(struct cmd_tbl *cmdtp, int flag, int argc, 629 char *const argv[]) 630{ 631 u32 index; 632 u32 resp; 633 u32 info_type; 634 635 if (argc < 2) 636 return CMD_RET_USAGE; 637 638 index = simple_strtoul(argv[1], NULL, 16); 639 printf("Commit index is 0x%x\n", index); 640 641 if (ele_commit(index, &resp, &info_type)) { 642 printf("Error in AHAB commit\n"); 643 return -EIO; 644 } 645 646 printf("Ahab commit succeeded. Information type is 0x%x\n", info_type); 647 648 return 0; 649} 650 651U_BOOT_CMD(auth_cntr, CONFIG_SYS_MAXARGS, 1, do_authenticate, 652 "autenticate OS container via AHAB", 653 "addr\n" 654 "addr - OS container hex address\n" 655); 656 657U_BOOT_CMD(ahab_close, CONFIG_SYS_MAXARGS, 1, do_ahab_close, 658 "Change AHAB lifecycle to OEM closed", 659 "" 660); 661 662U_BOOT_CMD(ahab_dump, CONFIG_SYS_MAXARGS, 1, do_ahab_dump, 663 "Dump AHAB log for debug", 664 "" 665); 666 667U_BOOT_CMD(ahab_status, CONFIG_SYS_MAXARGS, 1, do_ahab_status, 668 "display AHAB lifecycle only", 669 "" 670); 671 672U_BOOT_CMD(ahab_sec_fuse_prog, CONFIG_SYS_MAXARGS, 1, do_sec_fuse_prog, 673 "Program secure fuse via signed message block", 674 "addr\n" 675 "addr - Signed message block for secure fuse\n" 676); 677 678U_BOOT_CMD(ahab_return_lifecycle, CONFIG_SYS_MAXARGS, 1, do_ahab_return_lifecycle, 679 "Return lifecycle to OEM field return via signed message block", 680 "addr\n" 681 "addr - Return lifecycle message block signed by OEM SRK\n" 682); 683 684U_BOOT_CMD(ahab_commit, CONFIG_SYS_MAXARGS, 1, do_ahab_commit, 685 "commit into the fuses any new SRK revocation and FW version information\n" 686 "that have been found into the NXP (ELE FW) and OEM containers", 687 "" 688); 689