Files
2025-12-24 17:21:08 +09:00

197 lines
5.9 KiB
C

/*
* Copyright (c) 2018-2023 Renesas Electronics Corporation. All rights reserved.
*/
#include <stdio.h>
#include <rcar_def.h>
#include <scif.h>
#include <timer.h>
#include <log.h>
#include "d_armasm.h"
#include <image_load.h>
#include <loader_main.h>
#include <loader_main_common.h>
#include <cpu_on.h>
#include <emmc_def.h>
#include <emmc_boot.h>
#if (BOOT_MODE == SECURE)
#include "secure_boot.h"
#endif /* BOOT_MODE == SECURE */
/* Time analysis */
#if (1 == (MEASURE_TIME))
#include <scmt.h>
#include <scmt_checkpoint.h>
#else
#define scmt_wait_ticks(x)
#define store_time_checkpoint(x,y)
#define print_time_checkpoints(x)
#endif
#include <android_ab.h>
#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 */
}