264 lines
6.2 KiB
C
264 lines
6.2 KiB
C
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
|
/*
|
|
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <asm/io.h>
|
|
#include <malloc.h>
|
|
#include <errno.h>
|
|
#include <environment.h>
|
|
#include <fdt_support.h>
|
|
#include <cli.h>
|
|
#include <asm/cpu_id.h>
|
|
#include <generated/version_autogenerated.h>
|
|
#include <asm/arch/secure_apb.h>
|
|
#include <asm/arch/romboot.h>
|
|
|
|
#ifdef CONFIG_MISC_INIT_R
|
|
#define _AML_MISC_INTERRUPT_KEY 0x09
|
|
static int _aml_interrupt_key_pressed;
|
|
static int ctrli(void)
|
|
{
|
|
if (1/*gd->have_console*/) {
|
|
if (tstc()) {
|
|
int c = getc();
|
|
|
|
switch (c) {
|
|
case _AML_MISC_INTERRUPT_KEY:/* ^I - Control I */
|
|
_aml_interrupt_key_pressed = 1;
|
|
printf("Detect Ctrl I...\t\nInput yes to force stopped anyway:\t");
|
|
return 1;
|
|
default:
|
|
printf("Detect 0x%x\n", c);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int aml_misc_confirm_yesno(const int tm/*timeout in ms*/)
|
|
{
|
|
int i;
|
|
unsigned long ts;
|
|
char str_input[5];
|
|
|
|
_aml_interrupt_key_pressed = 0;
|
|
if (!ctrli()) {//not detect ctrl-I when bootup
|
|
return 0;
|
|
}
|
|
ts = get_timer(0);
|
|
|
|
for (i = 0; i < sizeof(str_input);) {
|
|
int c = 0;
|
|
|
|
while (!tstc()) {
|
|
if (get_timer(ts) >= tm) {
|
|
printf("Input timeout\n");
|
|
return 0;
|
|
}
|
|
}
|
|
c = getc();
|
|
if (i == 0 && c == _AML_MISC_INTERRUPT_KEY) {//drop first duplicated ctrlI
|
|
printf("Wait YES/y input\n");
|
|
continue;
|
|
}
|
|
putc(c);
|
|
str_input[i++] = c;
|
|
if (c == '\r')
|
|
break;
|
|
}
|
|
putc('\n');
|
|
if (strncmp(str_input, "y\r", 2) == 0 ||
|
|
strncmp(str_input, "Y\r", 2) == 0 ||
|
|
strncmp(str_input, "yes\r", 4) == 0 ||
|
|
strncmp(str_input, "YES\r", 4) == 0)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
int misc_init_r(void)
|
|
{
|
|
printf("board common misc_init\n");
|
|
#ifdef CONFIG_MDUMP_COMPRESS
|
|
extern void ramdump_init(void);
|
|
ramdump_init();
|
|
#endif
|
|
if (!aml_misc_confirm_yesno(5000))
|
|
return 0;
|
|
|
|
cli_init();
|
|
cli_loop();
|
|
panic("No CLI available");
|
|
return 0;
|
|
}
|
|
#endif // #ifdef CONFIG_MISC_INIT_R
|
|
|
|
#ifdef CONFIG_AB_UPDATE
|
|
#include <amlogic/aml_efuse.h>
|
|
#include <u-boot/sha256.h>
|
|
#include <asm/arch/bl31_apis.h>
|
|
#include <emmc_partitions.h>
|
|
#include <amlogic/storage_if.h>
|
|
|
|
int ab_mode(void)
|
|
{
|
|
printf("\nchoice A/B upgrade\n");
|
|
|
|
/********************************************************************
|
|
* 1. read partition of fip_a and fip_b ddr then verify two partition;
|
|
* 2. read env form "active_slot" to choice boot from which partition.
|
|
********************************************************************/
|
|
|
|
char *p_env = NULL;
|
|
unsigned int ret = 0;
|
|
unsigned char buff[32];
|
|
//extern void aml_u8_printf(void *pBuffer, int nSize);
|
|
|
|
run_command("run bcb_cmd", 0);
|
|
p_env = getenv("active_slot");
|
|
printf("p_env = %s\n", p_env);
|
|
|
|
if (IS_FEAT_BOOT_VERIFY()) {
|
|
/* verify partition of fi_a and fip_b */
|
|
printf("\nneed to verify part of a/b\n");
|
|
ret = store_read_ops((unsigned char *)"fip_a",
|
|
(unsigned char *)FIP_A_LOADADDR, 0, FIP_LOAD_SIZE + 0x400);
|
|
if (ret)
|
|
goto exit;
|
|
printf("\nread pass form part of a/b\n");
|
|
ret = aml_sec_boot_check(AML_D_P_IMG_DECRYPT,
|
|
FIP_A_LOADADDR, FIP_LOAD_SIZE + 0x400, GXB_IMG_DEC_ALL);
|
|
if (ret) {
|
|
printf("\nfip_a : Sig Check %d\n", ret);
|
|
goto exit;
|
|
}
|
|
|
|
ret = store_read_ops((unsigned char *)"fip_b",
|
|
(unsigned char *)FIP_B_LOADADDR, 0, FIP_LOAD_SIZE + 0x400);
|
|
if (ret)
|
|
goto exit;
|
|
ret = aml_sec_boot_check(AML_D_P_IMG_DECRYPT,
|
|
FIP_B_LOADADDR, FIP_LOAD_SIZE + 0x400, GXB_IMG_DEC_ALL);
|
|
if (ret) {
|
|
printf("\nfip_b : Sig Check %d\n", ret);
|
|
goto exit;
|
|
}
|
|
printf("\nfip_a and fip_b verify pass\n");
|
|
} else {
|
|
/* calculate SHA digest for fip_a and fip_b */
|
|
ret = store_read_ops((unsigned char *)"fip_a",
|
|
(unsigned char *)FIP_A_LOADADDR, 0, FIP_LOAD_SIZE);
|
|
if (ret)
|
|
goto exit;
|
|
|
|
sha256_csum_wd((unsigned char *)(FIP_A_LOADADDR),
|
|
(FIP_LOAD_SIZE - 32), (unsigned char *)buff, 0);
|
|
#ifdef DEBUG
|
|
printf("fip a buff sha is :\n");
|
|
aml_u8_printf((void *)buff, 0x20);
|
|
printf("fip a origin sha is :\n");
|
|
aml_u8_printf((void *)(FIP_A_LOADADDR + FIP_LOAD_SIZE - 32), 0x20);
|
|
#endif
|
|
if (memcmp(buff, (void *)(FIP_A_LOADADDR + FIP_LOAD_SIZE - 32), 32)) {
|
|
printf("FIP_A SHA NOT OK\n");
|
|
goto exit;
|
|
}
|
|
ret = store_read_ops((unsigned char *)"fip_b",
|
|
(unsigned char *)FIP_B_LOADADDR, 0, FIP_LOAD_SIZE);
|
|
if (ret)
|
|
goto exit;
|
|
sha256_csum_wd((unsigned char *)(FIP_B_LOADADDR),
|
|
(FIP_LOAD_SIZE - 32), (unsigned char *)buff, 0);
|
|
#ifdef DEBUG
|
|
printf("fip b buff sha is :\n");
|
|
aml_u8_printf((void *)buff, 0x20);
|
|
printf("fip b origin sha is :\n");
|
|
aml_u8_printf((void *)(FIP_B_LOADADDR + FIP_LOAD_SIZE - 32), 0x20);
|
|
#endif
|
|
if (memcmp(buff, (void *)(FIP_B_LOADADDR + FIP_LOAD_SIZE - 32), 32)) {
|
|
printf("FIP_B SHA NOT OK\n");
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
if (strcmp(p_env, "_a") == 0) {
|
|
printf("\nchoice fip A upgrade\n");
|
|
if (IS_FEAT_BOOT_VERIFY())
|
|
memmove((unsigned char *)CONFIG_SYS_TEXT_BASE,
|
|
(unsigned char *)FIP_A_LOADADDR + 0x200, FIP_LOAD_SIZE);
|
|
else
|
|
memmove((unsigned char *)CONFIG_SYS_TEXT_BASE,
|
|
(unsigned char *)FIP_A_LOADADDR, FIP_LOAD_SIZE);
|
|
} else if (strcmp(p_env, "_b") == 0) {
|
|
printf("\nset fip B upgrade\n");
|
|
if (IS_FEAT_BOOT_VERIFY())
|
|
memmove((unsigned char *)CONFIG_SYS_TEXT_BASE,
|
|
(unsigned char *)FIP_B_LOADADDR + 0x200, FIP_LOAD_SIZE);
|
|
else
|
|
memmove((unsigned char *)CONFIG_SYS_TEXT_BASE,
|
|
(unsigned char *)FIP_B_LOADADDR, FIP_LOAD_SIZE);
|
|
} else {
|
|
printf("Error (Need debug): active_slot(%s) is not ab mode\n", p_env);
|
|
goto exit;
|
|
}
|
|
|
|
unsigned long bl33_entry = CONFIG_SYS_TEXT_BASE;
|
|
/* run bl33 directly */
|
|
typedef unsigned long (*FUNC_TPL)(void);
|
|
printf("bl33 entry: 0x%lx\n", bl33_entry);
|
|
FUNC_TPL func_tpl = (FUNC_TPL)bl33_entry;
|
|
|
|
func_tpl();
|
|
|
|
exit:
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
static int board_get_bootid(void)
|
|
{
|
|
int boot_id = 0;
|
|
|
|
#if defined(P_AO_SEC_GP_CFG0)
|
|
boot_id = readl(P_AO_SEC_GP_CFG0) & 0xf;
|
|
#endif// #if defined(P_AO_SEC_GP_CFG0)
|
|
|
|
return boot_id;
|
|
}
|
|
|
|
void board_set_boot_source(void)
|
|
{
|
|
const char *source;
|
|
|
|
switch (board_get_bootid()) {
|
|
case BOOT_ID_EMMC:
|
|
source = "emmc";
|
|
break;
|
|
|
|
case BOOT_ID_NAND:
|
|
source = "nand";
|
|
break;
|
|
|
|
case BOOT_ID_SPI:
|
|
source = "spi";
|
|
break;
|
|
|
|
case BOOT_ID_SDCARD:
|
|
source = "sd";
|
|
break;
|
|
|
|
case BOOT_ID_USB:
|
|
source = "usb";
|
|
break;
|
|
|
|
default:
|
|
source = "unknown";
|
|
}
|
|
|
|
setenv("boot_source", source);
|
|
printf("%s, boot_source: %s\n", __func__, source);
|
|
}
|