uboot/arch/arm/mach-imx/hab.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2010-2015 Freescale Semiconductor, Inc.
   4 */
   5
   6#include <common.h>
   7#include <config.h>
   8#include <fuse.h>
   9#include <asm/io.h>
  10#include <asm/system.h>
  11#include <asm/arch/clock.h>
  12#include <asm/arch/sys_proto.h>
  13#include <asm/mach-imx/hab.h>
  14
  15#define ALIGN_SIZE              0x1000
  16#define MX6DQ_PU_IROM_MMU_EN_VAR        0x009024a8
  17#define MX6DLS_PU_IROM_MMU_EN_VAR       0x00901dd0
  18#define MX6SL_PU_IROM_MMU_EN_VAR        0x00900a18
  19#define IS_HAB_ENABLED_BIT \
  20        (is_soc_type(MXC_SOC_MX7ULP) ? 0x80000000 :     \
  21         (is_soc_type(MXC_SOC_MX7) ? 0x2000000 : 0x2))
  22
  23static int ivt_header_error(const char *err_str, struct ivt_header *ivt_hdr)
  24{
  25        printf("%s magic=0x%x length=0x%02x version=0x%x\n", err_str,
  26               ivt_hdr->magic, ivt_hdr->length, ivt_hdr->version);
  27
  28        return 1;
  29}
  30
  31static int verify_ivt_header(struct ivt_header *ivt_hdr)
  32{
  33        int result = 0;
  34
  35        if (ivt_hdr->magic != IVT_HEADER_MAGIC)
  36                result = ivt_header_error("bad magic", ivt_hdr);
  37
  38        if (be16_to_cpu(ivt_hdr->length) != IVT_TOTAL_LENGTH)
  39                result = ivt_header_error("bad length", ivt_hdr);
  40
  41        if (ivt_hdr->version != IVT_HEADER_V1 &&
  42            ivt_hdr->version != IVT_HEADER_V2)
  43                result = ivt_header_error("bad version", ivt_hdr);
  44
  45        return result;
  46}
  47
  48#if !defined(CONFIG_SPL_BUILD)
  49
  50#define MAX_RECORD_BYTES     (8*1024) /* 4 kbytes */
  51
  52struct record {
  53        uint8_t  tag;                                           /* Tag */
  54        uint8_t  len[2];                                        /* Length */
  55        uint8_t  par;                                           /* Version */
  56        uint8_t  contents[MAX_RECORD_BYTES];/* Record Data */
  57        bool     any_rec_flag;
  58};
  59
  60static char *rsn_str[] = {
  61                          "RSN = HAB_RSN_ANY (0x00)\n",
  62                          "RSN = HAB_ENG_FAIL (0x30)\n",
  63                          "RSN = HAB_INV_ADDRESS (0x22)\n",
  64                          "RSN = HAB_INV_ASSERTION (0x0C)\n",
  65                          "RSN = HAB_INV_CALL (0x28)\n",
  66                          "RSN = HAB_INV_CERTIFICATE (0x21)\n",
  67                          "RSN = HAB_INV_COMMAND (0x06)\n",
  68                          "RSN = HAB_INV_CSF (0x11)\n",
  69                          "RSN = HAB_INV_DCD (0x27)\n",
  70                          "RSN = HAB_INV_INDEX (0x0F)\n",
  71                          "RSN = HAB_INV_IVT (0x05)\n",
  72                          "RSN = HAB_INV_KEY (0x1D)\n",
  73                          "RSN = HAB_INV_RETURN (0x1E)\n",
  74                          "RSN = HAB_INV_SIGNATURE (0x18)\n",
  75                          "RSN = HAB_INV_SIZE (0x17)\n",
  76                          "RSN = HAB_MEM_FAIL (0x2E)\n",
  77                          "RSN = HAB_OVR_COUNT (0x2B)\n",
  78                          "RSN = HAB_OVR_STORAGE (0x2D)\n",
  79                          "RSN = HAB_UNS_ALGORITHM (0x12)\n",
  80                          "RSN = HAB_UNS_COMMAND (0x03)\n",
  81                          "RSN = HAB_UNS_ENGINE (0x0A)\n",
  82                          "RSN = HAB_UNS_ITEM (0x24)\n",
  83                          "RSN = HAB_UNS_KEY (0x1B)\n",
  84                          "RSN = HAB_UNS_PROTOCOL (0x14)\n",
  85                          "RSN = HAB_UNS_STATE (0x09)\n",
  86                          "RSN = INVALID\n",
  87                          NULL
  88};
  89
  90static char *sts_str[] = {
  91                          "STS = HAB_SUCCESS (0xF0)\n",
  92                          "STS = HAB_FAILURE (0x33)\n",
  93                          "STS = HAB_WARNING (0x69)\n",
  94                          "STS = INVALID\n",
  95                          NULL
  96};
  97
  98static char *eng_str[] = {
  99                          "ENG = HAB_ENG_ANY (0x00)\n",
 100                          "ENG = HAB_ENG_SCC (0x03)\n",
 101                          "ENG = HAB_ENG_RTIC (0x05)\n",
 102                          "ENG = HAB_ENG_SAHARA (0x06)\n",
 103                          "ENG = HAB_ENG_CSU (0x0A)\n",
 104                          "ENG = HAB_ENG_SRTC (0x0C)\n",
 105                          "ENG = HAB_ENG_DCP (0x1B)\n",
 106                          "ENG = HAB_ENG_CAAM (0x1D)\n",
 107                          "ENG = HAB_ENG_SNVS (0x1E)\n",
 108                          "ENG = HAB_ENG_OCOTP (0x21)\n",
 109                          "ENG = HAB_ENG_DTCP (0x22)\n",
 110                          "ENG = HAB_ENG_ROM (0x36)\n",
 111                          "ENG = HAB_ENG_HDCP (0x24)\n",
 112                          "ENG = HAB_ENG_RTL (0x77)\n",
 113                          "ENG = HAB_ENG_SW (0xFF)\n",
 114                          "ENG = INVALID\n",
 115                          NULL
 116};
 117
 118static char *ctx_str[] = {
 119                          "CTX = HAB_CTX_ANY(0x00)\n",
 120                          "CTX = HAB_CTX_FAB (0xFF)\n",
 121                          "CTX = HAB_CTX_ENTRY (0xE1)\n",
 122                          "CTX = HAB_CTX_TARGET (0x33)\n",
 123                          "CTX = HAB_CTX_AUTHENTICATE (0x0A)\n",
 124                          "CTX = HAB_CTX_DCD (0xDD)\n",
 125                          "CTX = HAB_CTX_CSF (0xCF)\n",
 126                          "CTX = HAB_CTX_COMMAND (0xC0)\n",
 127                          "CTX = HAB_CTX_AUT_DAT (0xDB)\n",
 128                          "CTX = HAB_CTX_ASSERT (0xA0)\n",
 129                          "CTX = HAB_CTX_EXIT (0xEE)\n",
 130                          "CTX = INVALID\n",
 131                          NULL
 132};
 133
 134static uint8_t hab_statuses[5] = {
 135        HAB_STS_ANY,
 136        HAB_FAILURE,
 137        HAB_WARNING,
 138        HAB_SUCCESS,
 139        -1
 140};
 141
 142static uint8_t hab_reasons[26] = {
 143        HAB_RSN_ANY,
 144        HAB_ENG_FAIL,
 145        HAB_INV_ADDRESS,
 146        HAB_INV_ASSERTION,
 147        HAB_INV_CALL,
 148        HAB_INV_CERTIFICATE,
 149        HAB_INV_COMMAND,
 150        HAB_INV_CSF,
 151        HAB_INV_DCD,
 152        HAB_INV_INDEX,
 153        HAB_INV_IVT,
 154        HAB_INV_KEY,
 155        HAB_INV_RETURN,
 156        HAB_INV_SIGNATURE,
 157        HAB_INV_SIZE,
 158        HAB_MEM_FAIL,
 159        HAB_OVR_COUNT,
 160        HAB_OVR_STORAGE,
 161        HAB_UNS_ALGORITHM,
 162        HAB_UNS_COMMAND,
 163        HAB_UNS_ENGINE,
 164        HAB_UNS_ITEM,
 165        HAB_UNS_KEY,
 166        HAB_UNS_PROTOCOL,
 167        HAB_UNS_STATE,
 168        -1
 169};
 170
 171static uint8_t hab_contexts[12] = {
 172        HAB_CTX_ANY,
 173        HAB_CTX_FAB,
 174        HAB_CTX_ENTRY,
 175        HAB_CTX_TARGET,
 176        HAB_CTX_AUTHENTICATE,
 177        HAB_CTX_DCD,
 178        HAB_CTX_CSF,
 179        HAB_CTX_COMMAND,
 180        HAB_CTX_AUT_DAT,
 181        HAB_CTX_ASSERT,
 182        HAB_CTX_EXIT,
 183        -1
 184};
 185
 186static uint8_t hab_engines[16] = {
 187        HAB_ENG_ANY,
 188        HAB_ENG_SCC,
 189        HAB_ENG_RTIC,
 190        HAB_ENG_SAHARA,
 191        HAB_ENG_CSU,
 192        HAB_ENG_SRTC,
 193        HAB_ENG_DCP,
 194        HAB_ENG_CAAM,
 195        HAB_ENG_SNVS,
 196        HAB_ENG_OCOTP,
 197        HAB_ENG_DTCP,
 198        HAB_ENG_ROM,
 199        HAB_ENG_HDCP,
 200        HAB_ENG_RTL,
 201        HAB_ENG_SW,
 202        -1
 203};
 204
 205static inline uint8_t get_idx(uint8_t *list, uint8_t tgt)
 206{
 207        uint8_t idx = 0;
 208        uint8_t element = list[idx];
 209        while (element != -1) {
 210                if (element == tgt)
 211                        return idx;
 212                element = list[++idx];
 213        }
 214        return -1;
 215}
 216
 217static void process_event_record(uint8_t *event_data, size_t bytes)
 218{
 219        struct record *rec = (struct record *)event_data;
 220
 221        printf("\n\n%s", sts_str[get_idx(hab_statuses, rec->contents[0])]);
 222        printf("%s", rsn_str[get_idx(hab_reasons, rec->contents[1])]);
 223        printf("%s", ctx_str[get_idx(hab_contexts, rec->contents[2])]);
 224        printf("%s", eng_str[get_idx(hab_engines, rec->contents[3])]);
 225}
 226
 227static void display_event(uint8_t *event_data, size_t bytes)
 228{
 229        uint32_t i;
 230
 231        if (!(event_data && bytes > 0))
 232                return;
 233
 234        for (i = 0; i < bytes; i++) {
 235                if (i == 0)
 236                        printf("\t0x%02x", event_data[i]);
 237                else if ((i % 8) == 0)
 238                        printf("\n\t0x%02x", event_data[i]);
 239                else
 240                        printf(" 0x%02x", event_data[i]);
 241        }
 242
 243        process_event_record(event_data, bytes);
 244}
 245
 246static int get_hab_status(void)
 247{
 248        uint32_t index = 0; /* Loop index */
 249        uint8_t event_data[128]; /* Event data buffer */
 250        size_t bytes = sizeof(event_data); /* Event size in bytes */
 251        enum hab_config config = 0;
 252        enum hab_state state = 0;
 253        hab_rvt_report_event_t *hab_rvt_report_event;
 254        hab_rvt_report_status_t *hab_rvt_report_status;
 255
 256        hab_rvt_report_event = (hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT;
 257        hab_rvt_report_status =
 258                        (hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS;
 259
 260        if (imx_hab_is_enabled())
 261                puts("\nSecure boot enabled\n");
 262        else
 263                puts("\nSecure boot disabled\n");
 264
 265        /* Check HAB status */
 266        if (hab_rvt_report_status(&config, &state) != HAB_SUCCESS) {
 267                printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
 268                       config, state);
 269
 270                /* Display HAB Error events */
 271                while (hab_rvt_report_event(HAB_FAILURE, index, event_data,
 272                                        &bytes) == HAB_SUCCESS) {
 273                        puts("\n");
 274                        printf("--------- HAB Event %d -----------------\n",
 275                               index + 1);
 276                        puts("event data:\n");
 277                        display_event(event_data, bytes);
 278                        puts("\n");
 279                        bytes = sizeof(event_data);
 280                        index++;
 281                }
 282        }
 283        /* Display message if no HAB events are found */
 284        else {
 285                printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
 286                       config, state);
 287                puts("No HAB Events Found!\n\n");
 288        }
 289        return 0;
 290}
 291
 292static int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc,
 293                         char * const argv[])
 294{
 295        if ((argc != 1)) {
 296                cmd_usage(cmdtp);
 297                return 1;
 298        }
 299
 300        get_hab_status();
 301
 302        return 0;
 303}
 304
 305static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc,
 306                                 char * const argv[])
 307{
 308        ulong   addr, length, ivt_offset;
 309        int     rcode = 0;
 310
 311        if (argc < 4)
 312                return CMD_RET_USAGE;
 313
 314        addr = simple_strtoul(argv[1], NULL, 16);
 315        length = simple_strtoul(argv[2], NULL, 16);
 316        ivt_offset = simple_strtoul(argv[3], NULL, 16);
 317
 318        rcode = imx_hab_authenticate_image(addr, length, ivt_offset);
 319        if (rcode == 0)
 320                rcode = CMD_RET_SUCCESS;
 321        else
 322                rcode = CMD_RET_FAILURE;
 323
 324        return rcode;
 325}
 326
 327static int do_hab_failsafe(cmd_tbl_t *cmdtp, int flag, int argc,
 328                           char * const argv[])
 329{
 330        hab_rvt_failsafe_t *hab_rvt_failsafe;
 331
 332        if (argc != 1) {
 333                cmd_usage(cmdtp);
 334                return 1;
 335        }
 336
 337        hab_rvt_failsafe = (hab_rvt_failsafe_t *)HAB_RVT_FAILSAFE;
 338        hab_rvt_failsafe();
 339
 340        return 0;
 341}
 342
 343static int do_authenticate_image_or_failover(cmd_tbl_t *cmdtp, int flag,
 344                                             int argc, char * const argv[])
 345{
 346        int ret = CMD_RET_FAILURE;
 347
 348        if (argc != 4) {
 349                ret = CMD_RET_USAGE;
 350                goto error;
 351        }
 352
 353        if (!imx_hab_is_enabled()) {
 354                printf("error: secure boot disabled\n");
 355                goto error;
 356        }
 357
 358        if (do_authenticate_image(NULL, flag, argc, argv) != CMD_RET_SUCCESS) {
 359                fprintf(stderr, "authentication fail -> %s %s %s %s\n",
 360                        argv[0], argv[1], argv[2], argv[3]);
 361                do_hab_failsafe(0, 0, 1, NULL);
 362        };
 363        ret = CMD_RET_SUCCESS;
 364error:
 365        return ret;
 366}
 367
 368U_BOOT_CMD(
 369                hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
 370                "display HAB status",
 371                ""
 372          );
 373
 374U_BOOT_CMD(
 375                hab_auth_img, 4, 0, do_authenticate_image,
 376                "authenticate image via HAB",
 377                "addr length ivt_offset\n"
 378                "addr - image hex address\n"
 379                "length - image hex length\n"
 380                "ivt_offset - hex offset of IVT in the image"
 381          );
 382
 383U_BOOT_CMD(
 384                hab_failsafe, CONFIG_SYS_MAXARGS, 1, do_hab_failsafe,
 385                "run BootROM failsafe routine",
 386                ""
 387          );
 388
 389U_BOOT_CMD(
 390                hab_auth_img_or_fail, 4, 0,
 391                do_authenticate_image_or_failover,
 392                "authenticate image via HAB on failure drop to USB BootROM mode",
 393                "addr length ivt_offset\n"
 394                "addr - image hex address\n"
 395                "length - image hex length\n"
 396                "ivt_offset - hex offset of IVT in the image"
 397          );
 398
 399#endif /* !defined(CONFIG_SPL_BUILD) */
 400
 401/* Get CSF Header length */
 402static int get_hab_hdr_len(struct hab_hdr *hdr)
 403{
 404        return (size_t)((hdr->len[0] << 8) + (hdr->len[1]));
 405}
 406
 407/* Check whether addr lies between start and
 408 * end and is within the length of the image
 409 */
 410static int chk_bounds(u8 *addr, size_t bytes, u8 *start, u8 *end)
 411{
 412        size_t csf_size = (size_t)((end + 1) - addr);
 413
 414        return (addr && (addr >= start) && (addr <= end) &&
 415                (csf_size >= bytes));
 416}
 417
 418/* Get Length of each command in CSF */
 419static int get_csf_cmd_hdr_len(u8 *csf_hdr)
 420{
 421        if (*csf_hdr == HAB_CMD_HDR)
 422                return sizeof(struct hab_hdr);
 423
 424        return get_hab_hdr_len((struct hab_hdr *)csf_hdr);
 425}
 426
 427/* Check if CSF is valid */
 428static bool csf_is_valid(struct ivt *ivt, ulong start_addr, size_t bytes)
 429{
 430        u8 *start = (u8 *)start_addr;
 431        u8 *csf_hdr;
 432        u8 *end;
 433
 434        size_t csf_hdr_len;
 435        size_t cmd_hdr_len;
 436        size_t offset = 0;
 437
 438        if (bytes != 0)
 439                end = start + bytes - 1;
 440        else
 441                end = start;
 442
 443        /* Verify if CSF pointer content is zero */
 444        if (!ivt->csf) {
 445                puts("Error: CSF pointer is NULL\n");
 446                return false;
 447        }
 448
 449        csf_hdr = (u8 *)ivt->csf;
 450
 451        /* Verify if CSF Header exist */
 452        if (*csf_hdr != HAB_CMD_HDR) {
 453                puts("Error: CSF header command not found\n");
 454                return false;
 455        }
 456
 457        csf_hdr_len = get_hab_hdr_len((struct hab_hdr *)csf_hdr);
 458
 459        /* Check if the CSF lies within the image bounds */
 460        if (!chk_bounds(csf_hdr, csf_hdr_len, start, end)) {
 461                puts("Error: CSF lies outside the image bounds\n");
 462                return false;
 463        }
 464
 465        do {
 466                struct hab_hdr *cmd;
 467
 468                cmd = (struct hab_hdr *)&csf_hdr[offset];
 469
 470                switch (cmd->tag) {
 471                case (HAB_CMD_WRT_DAT):
 472                        puts("Error: Deprecated write command found\n");
 473                        return false;
 474                case (HAB_CMD_CHK_DAT):
 475                        puts("Error: Deprecated check command found\n");
 476                        return false;
 477                case (HAB_CMD_SET):
 478                        if (cmd->par == HAB_PAR_MID) {
 479                                puts("Error: Deprecated Set MID command found\n");
 480                                return false;
 481                        }
 482                default:
 483                        break;
 484                }
 485
 486                cmd_hdr_len = get_csf_cmd_hdr_len(&csf_hdr[offset]);
 487                if (!cmd_hdr_len) {
 488                        puts("Error: Invalid command length\n");
 489                        return false;
 490                }
 491                offset += cmd_hdr_len;
 492
 493        } while (offset < csf_hdr_len);
 494
 495        return true;
 496}
 497
 498bool imx_hab_is_enabled(void)
 499{
 500        struct imx_sec_config_fuse_t *fuse =
 501                (struct imx_sec_config_fuse_t *)&imx_sec_config_fuse;
 502        uint32_t reg;
 503        int ret;
 504
 505        ret = fuse_read(fuse->bank, fuse->word, &reg);
 506        if (ret) {
 507                puts("\nSecure boot fuse read error\n");
 508                return ret;
 509        }
 510
 511        return (reg & IS_HAB_ENABLED_BIT) == IS_HAB_ENABLED_BIT;
 512}
 513
 514int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
 515                               uint32_t ivt_offset)
 516{
 517        uint32_t load_addr = 0;
 518        size_t bytes;
 519        uint32_t ivt_addr = 0;
 520        int result = 1;
 521        ulong start;
 522        hab_rvt_authenticate_image_t *hab_rvt_authenticate_image;
 523        hab_rvt_entry_t *hab_rvt_entry;
 524        hab_rvt_exit_t *hab_rvt_exit;
 525        hab_rvt_check_target_t *hab_rvt_check_target;
 526        struct ivt *ivt;
 527        struct ivt_header *ivt_hdr;
 528        enum hab_status status;
 529
 530        hab_rvt_authenticate_image =
 531                (hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE;
 532        hab_rvt_entry = (hab_rvt_entry_t *)HAB_RVT_ENTRY;
 533        hab_rvt_exit = (hab_rvt_exit_t *)HAB_RVT_EXIT;
 534        hab_rvt_check_target = (hab_rvt_check_target_t *)HAB_RVT_CHECK_TARGET;
 535
 536        if (!imx_hab_is_enabled()) {
 537                puts("hab fuse not enabled\n");
 538                return 0;
 539        }
 540
 541        printf("\nAuthenticate image from DDR location 0x%x...\n",
 542               ddr_start);
 543
 544        hab_caam_clock_enable(1);
 545
 546        /* Calculate IVT address header */
 547        ivt_addr = ddr_start + ivt_offset;
 548        ivt = (struct ivt *)ivt_addr;
 549        ivt_hdr = &ivt->hdr;
 550
 551        /* Verify IVT header bugging out on error */
 552        if (verify_ivt_header(ivt_hdr))
 553                goto hab_authentication_exit;
 554
 555        /* Verify IVT body */
 556        if (ivt->self != ivt_addr) {
 557                printf("ivt->self 0x%08x pointer is 0x%08x\n",
 558                       ivt->self, ivt_addr);
 559                goto hab_authentication_exit;
 560        }
 561
 562        /* Verify if IVT DCD pointer is NULL */
 563        if (ivt->dcd)
 564                puts("Warning: DCD pointer should be NULL\n");
 565
 566        start = ddr_start;
 567        bytes = image_size;
 568
 569        /* Verify CSF */
 570        if (!csf_is_valid(ivt, start, bytes))
 571                goto hab_authentication_exit;
 572
 573        if (hab_rvt_entry() != HAB_SUCCESS) {
 574                puts("hab entry function fail\n");
 575                goto hab_exit_failure_print_status;
 576        }
 577
 578        status = hab_rvt_check_target(HAB_TGT_MEMORY, (void *)ddr_start, bytes);
 579        if (status != HAB_SUCCESS) {
 580                printf("HAB check target 0x%08x-0x%08x fail\n",
 581                       ddr_start, ddr_start + bytes);
 582                goto hab_exit_failure_print_status;
 583        }
 584#ifdef DEBUG
 585        printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", ivt_offset, ivt_addr);
 586        printf("ivt entry = 0x%08x, dcd = 0x%08x, csf = 0x%08x\n", ivt->entry,
 587               ivt->dcd, ivt->csf);
 588        puts("Dumping IVT\n");
 589        print_buffer(ivt_addr, (void *)(ivt_addr), 4, 0x8, 0);
 590
 591        puts("Dumping CSF Header\n");
 592        print_buffer(ivt->csf, (void *)(ivt->csf), 4, 0x10, 0);
 593
 594#if  !defined(CONFIG_SPL_BUILD)
 595        get_hab_status();
 596#endif
 597
 598        puts("\nCalling authenticate_image in ROM\n");
 599        printf("\tivt_offset = 0x%x\n", ivt_offset);
 600        printf("\tstart = 0x%08lx\n", start);
 601        printf("\tbytes = 0x%x\n", bytes);
 602#endif
 603        /*
 604         * If the MMU is enabled, we have to notify the ROM
 605         * code, or it won't flush the caches when needed.
 606         * This is done, by setting the "pu_irom_mmu_enabled"
 607         * word to 1. You can find its address by looking in
 608         * the ROM map. This is critical for
 609         * authenticate_image(). If MMU is enabled, without
 610         * setting this bit, authentication will fail and may
 611         * crash.
 612         */
 613        /* Check MMU enabled */
 614        if (is_soc_type(MXC_SOC_MX6) && get_cr() & CR_M) {
 615                if (is_mx6dq()) {
 616                        /*
 617                         * This won't work on Rev 1.0.0 of
 618                         * i.MX6Q/D, since their ROM doesn't
 619                         * do cache flushes. don't think any
 620                         * exist, so we ignore them.
 621                         */
 622                        if (!is_mx6dqp())
 623                                writel(1, MX6DQ_PU_IROM_MMU_EN_VAR);
 624                } else if (is_mx6sdl()) {
 625                        writel(1, MX6DLS_PU_IROM_MMU_EN_VAR);
 626                } else if (is_mx6sl()) {
 627                        writel(1, MX6SL_PU_IROM_MMU_EN_VAR);
 628                }
 629        }
 630
 631        load_addr = (uint32_t)hab_rvt_authenticate_image(
 632                        HAB_CID_UBOOT,
 633                        ivt_offset, (void **)&start,
 634                        (size_t *)&bytes, NULL);
 635        if (hab_rvt_exit() != HAB_SUCCESS) {
 636                puts("hab exit function fail\n");
 637                load_addr = 0;
 638        }
 639
 640hab_exit_failure_print_status:
 641#if !defined(CONFIG_SPL_BUILD)
 642        get_hab_status();
 643#endif
 644
 645hab_authentication_exit:
 646
 647        if (load_addr != 0)
 648                result = 0;
 649
 650        return result;
 651}
 652