/* * Copyright (c) 2018-2023 Renesas Electronics Corporation. All rights reserved. */ #include #include #include #include #include #include "d_armasm.h" #include #include #include #include #include #include #if (BOOT_MODE == SECURE) #include "secure_boot.h" #endif /* BOOT_MODE == SECURE */ /* Time analysis */ #if (1 == (MEASURE_TIME)) #include #include #else #define scmt_wait_ticks(x) #define store_time_checkpoint(x,y) #define print_time_checkpoints(x) #endif #include #define _SECURE_BOOT_MARK (0x41DFFFF8U) #define IS_SECURE_BOOT NORMAL_BOOT #define OS_LOAD_FAIL (0xBAADF00DU) extern const uint8_t __RO_START__[1]; extern const uint8_t __STACKS_END__[1]; extern const char build_message[]; void Main(void) { uint32_t ca_load_num; /* number of load for CA program */ uint32_t loop; uint32_t reg; /* store register value */ int slot = 0; __attribute__((unused))const char *str; #if (BOOT_MODE == SECURE) uint32_t bootmode; /* store boot mode */ #endif /* BOOT_MODE == SECURE */ LOAD_INFO li[MAX_PLACED]; #if (RCAR_LSI != RCAR_V4H) #error "RCAR_V4H only" #endif #if (1 == (MEASURE_TIME)) scmt_module_start(); store_time_checkpoint("loader_main", 0); #endif /***************************************************************************** * Initialize Hardware *****************************************************************************/ /* ip_control/ip_init() */ scif_init(); import_mmc_drv_obj(); store_time_checkpoint("emmc_initialize", 0); /***************************************************************************** * Output boot message *****************************************************************************/ NOTICE("CA76 Loader Program Rev.%s\n", IPL_VERSION); NOTICE("%s\n", build_message); /* Get PRR */ reg = mem_read32(PRR); switch (reg & PRR_PRODUCT_MASK) { case PRR_PRODUCT_V4H: str = "V4H"; break; default: str = "unknown"; break; } NOTICE("PRR is R-Car %s Ver.%d.%d\n", str, ((int)(reg & PRR_MAJOR_MASK) >> PRR_MAJOR_SHIFT) + PRR_MAJOR_OFFSET, (int)(reg & PRR_MINOR_MASK)); store_time_checkpoint("init_done", 0); /***************************************************************************** * Load Certficate *****************************************************************************/ /* Load content certificate */ ca_load_num = mem_read32(CONTENT_CERT_DEST_ADDR); /* Get load information */ load_init(li, ca_load_num); #if (BOOT_MODE == SECURE) secureboot_init(); /* LCS judgement for secure boot */ bootmode = judge_bootmode(); if (NORMAL_BOOT != bootmode) { /* Content cert certification */ secureboot_verify(li, CA_OPTIONAL_ID, CA_OPTIONAL_ID + ca_load_num); store_time_checkpoint("verify_cert_done", 0); #ifdef MOBIS_PRK3 /* because of SECURE_BOOT == 0x0, we use NORMAL_BOOT as secure boot flag */ mem_write32(_SECURE_BOOT_MARK, IS_SECURE_BOOT); #endif } #endif /* BOOT_MODE == SECURE */ /***************************************************************************** * Load CA Program#2--#8 *****************************************************************************/ reg = mem_read32(AB_INFO_FLAG_ADDR); if (reg & AB_INFO_SELECT_2nd) slot = 1; NOTICE("slot: %d\n", slot); load_update_part_num(li, ca_load_num, slot); /* Start loading CA Program#n image */ for (loop = 0U; loop < ca_load_num; loop++) { #ifdef MOBIS_PRK3 if (loop == (CA_BL2_ID - CA_OPTIONAL_ID)) continue; #endif /* Loading start */ load_image(&li[CA_OPTIONAL_ID + loop]); store_time_checkpoint("load_CA_#_done", li[CA_OPTIONAL_ID + loop].image_size); #if (BOOT_MODE == SECURE) /* Decryption image and Image certification */ if (NORMAL_BOOT != bootmode) { #ifdef MOBIS_PRK3 if (loop == (CA_QNX_OS_ID - CA_OPTIONAL_ID)) { int ret = secureboot_image(&li[CA_OPTIONAL_ID + loop], 0); if (ret != 0) { ERROR("secureboot_image failed for %s\n", li[CA_OPTIONAL_ID + loop].name); mem_write32(_SECURE_BOOT_MARK, OS_LOAD_FAIL); } } else #endif secureboot_image(&li[CA_OPTIONAL_ID + loop], 1); store_time_checkpoint("verify_CA_#_done", 0); } #endif /* BOOT_MODE == SECURE */ } /* Set Secure Monitor parameter */ smoni_set_param(li[CA_OPTIONAL_ID].boot_addr, /* BL31 */ li[CA_OPTIONAL_ID + 1U].boot_addr, /* U-Boot */ li[CA_OPTIONAL_ID + 2U].boot_addr); /* TEE-OS */ /***************************************************************************** * Exit Hardware *****************************************************************************/ EMMC_ERROR_CODE result = EMMC_ERR; result = emmc_terminate(); if(EMMC_SUCCESS != result) { ERROR("ip_release error (emmc_terminate).\n"); panic; } NOTICE("Load finish.(CA76 Loader)\n"); /***************************************************************************** * Jump to BL31 *****************************************************************************/ void (*bl31_func)(void); bl31_func = (void (*)(void))(uintptr_t)li[CA_OPTIONAL_ID].boot_addr; store_time_checkpoint("Jump to BL31", 0); print_time_checkpoints(); #if !defined(BE_QUIET) && (LOG_LEVEL < LOG_NOTICE) log_printf("%s\n", build_message); #if (BOOT_MODE == SECURE) if (NORMAL_BOOT != bootmode) { log_printf("Secure boot(CA76 Loader)\n"); } else { log_printf("Normal boot(CA76 Loader)\n"); } #else log_printf("Boot(CA76 Loader)\n"); #endif #endif bl31_func(); /* Jump to BL31 */ }