aboutsummaryrefslogtreecommitdiff
path: root/board/thead
diff options
context:
space:
mode:
Diffstat (limited to 'board/thead')
-rw-r--r--board/thead/light-c910/Makefile1
-rw-r--r--board/thead/light-c910/boot.c2
-rw-r--r--board/thead/light-c910/clock_config.c2
-rw-r--r--board/thead/light-c910/light.c9
-rw-r--r--board/thead/light-c910/sbmeta/sbmeta.c296
-rw-r--r--board/thead/light-c910/sbmeta/sbmeta.h48
-rw-r--r--board/thead/light-c910/secimg_load.c6
7 files changed, 360 insertions, 4 deletions
diff --git a/board/thead/light-c910/Makefile b/board/thead/light-c910/Makefile
index 21e9649b..404b9c12 100644
--- a/board/thead/light-c910/Makefile
+++ b/board/thead/light-c910/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_THEAD_LIGHT_DIGITAL_SENSOR) += digital_sensor.o digital_sensor_test
obj-y += clock_config.o
obj-y += sec_check.o
obj-y += boot.o
+obj-y += sbmeta/sbmeta.o
ifndef CONFIG_TARGET_LIGHT_FPGA_FM_C910
obj-$(CONFIG_LPDDR) += $(DDR_SRC_PATH)/ddr_common_func.o
obj-$(CONFIG_LPDDR) += $(DDR_SRC_PATH)/common_lib.o
diff --git a/board/thead/light-c910/boot.c b/board/thead/light-c910/boot.c
index 24f3776f..8bc067a7 100644
--- a/board/thead/light-c910/boot.c
+++ b/board/thead/light-c910/boot.c
@@ -709,10 +709,12 @@ void sec_firmware_version_dump(void)
tf_ver_env = env_get_hex("tf_version", 0);
if ((tee_ver_env != tee_ver) && (tee_ver != 0)) {
env_set_hex("tee_version", tee_ver);
+ run_command("saveenv", 0);
}
if ((tf_ver_env != tf_ver) && (tf_ver != 0)) {
env_set_hex("tf_version", tf_ver);
+ run_command("saveenv", 0);
}
printf("\n\n");
diff --git a/board/thead/light-c910/clock_config.c b/board/thead/light-c910/clock_config.c
index f3ea3836..543eafeb 100644
--- a/board/thead/light-c910/clock_config.c
+++ b/board/thead/light-c910/clock_config.c
@@ -1306,7 +1306,7 @@ int clk_config(void)
#if defined (CONFIG_TARGET_LIGHT_FM_C910_VAL_ANT_DISCRETE) || defined (CONFIG_TARGET_LIGHT_FM_C910_BEAGLE) || defined (CONFIG_TARGET_LIGHT_FM_C910_B_REF) || defined (CONFIG_TARGET_LIGHT_FM_C910_VAL_ANT_REF) || defined (CONFIG_TARGET_LIGHT_FM_C910_B_POWER) || defined (CONFIG_TARGET_LIGHT_FM_C910_VAL_B) || defined (CONFIG_TARGET_LIGHT_FM_C910_LPI4A) || defined (CONFIG_TARGET_LIGHT_FM_C910_MILKV_MELES)
ap_multimedia_div_num_set(VI_MIPI_CSI0_DIV, 12); /* Input frquency: 2376MHZ */
- ap_multimedia_div_num_set(VI_ISP0_CORE_DIV, 15); /* Input frquency: 2376MHZ */
+ ap_multimedia_div_num_set(VI_ISP0_CORE_DIV, 12); /* Input frquency: 2376MHZ */
ap_multimedia_div_num_set(VI_ISP1_CORE_DIV, 12); /* Input frquency: 2376MHZ */
ap_multimedia_div_num_set(VI_ISP_RY_CORE_DIV, 12); /* Input frquency: 2376MHZ */
ap_multimedia_div_num_set(VO_DPU_CORE_DIV, 4); /* Input frquency: 2376MHZ */
diff --git a/board/thead/light-c910/light.c b/board/thead/light-c910/light.c
index 4f7f4b08..6a765400 100644
--- a/board/thead/light-c910/light.c
+++ b/board/thead/light-c910/light.c
@@ -32,6 +32,7 @@
#define GMAC1_APB3S_BADDR 0xffec004000
static uint64_t apb3s_baddr;
+extern int check_image_board_id(uint8_t *image_data);
typedef enum {
UART0_TXD = PAD_GRP_BASE_SET(SOC_PIN_AP_RIGHT_TOP),
@@ -2425,10 +2426,18 @@ static void light_usb_boot_check(void)
uchar env_enet1addr[6];
int env_ethaddr_flag,env_eth1addr_flag;
int boot_mode;
+ int ret = 0;
+
boot_mode = readl((void *)SOC_OM_ADDRBASE) & 0x7;
if (boot_mode & BIT(2))
return;
+ /*check board id of uboot image*/
+ ret = check_image_board_id((uint8_t*)SRAM_BASE_ADDR);
+ if (ret != 0) {
+ while(1);
+ }
+
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
env_set("usb_fastboot", "yes");
#endif
diff --git a/board/thead/light-c910/sbmeta/sbmeta.c b/board/thead/light-c910/sbmeta/sbmeta.c
new file mode 100644
index 00000000..6407ec7a
--- /dev/null
+++ b/board/thead/light-c910/sbmeta/sbmeta.c
@@ -0,0 +1,296 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021 Alibaba Group Holding Limited
+ */
+
+#include "sbmeta.h"
+
+#define NO_DEBUG 0
+#if NO_DEBUG
+#define print_info(fmt, args...)
+#else
+#define print_info(fmt, args...) printf(fmt, ##args)
+#endif
+
+#if CONFIG_IS_ENABLED(LIGHT_SEC_BOOT_WITH_VERIFY_VAL_A) || CONFIG_IS_ENABLED(LIGHT_SEC_BOOT_WITH_VERIFY_VAL_B) || CONFIG_IS_ENABLED(LIGHT_SEC_BOOT_WITH_VERIFY_LPI4A)
+#if CONFIG_IS_ENABLED(LIGHT_SEC_UPGRADE)
+/* digest_size corresponding to digest_scheme specified in sbmeta_info_t */
+static const int digest_size[] = {0, 20, 16, 28, 32, 48, 64, 32, 64};
+static const char* image_name_s[] = {
+ "dtb", "kernel", "tf", "aon", "rootfs", "tee", "uboot", "user"
+};
+
+static const uint32_t image_addrs[] = {
+ LIGHT_DTB_ADDR,
+ LIGHT_KERNEL_ADDR,
+ LIGHT_TF_FW_TMP_ADDR,
+ LIGHT_AON_FW_ADDR,
+ LIGHT_ROOTFS_ADDR,
+ LIGHT_TEE_FW_ADDR,
+ CONFIG_SYS_TEXT_BASE,
+};
+
+static int is_sbmeta_info(uint32_t entry_src_addr)
+{
+ uint32_t *buffer = (uint32_t *)entry_src_addr;
+
+ /* sbmeta_info_t entry should start with magic code 'S''B''M''T' */
+ if (*buffer != SBMETA_MAGIC) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int dump_sbmeta_info(sbmeta_info_t *sbmeta_info)
+{
+ if (sbmeta_info == NULL) {
+ return CMD_RET_FAILURE;
+ }
+
+ /* only support emmc now */
+ if (sbmeta_info->medium_type != 0) {
+ print_info("Error: medium type %s is not supported now\r\n");
+ return CMD_RET_FAILURE;
+ }
+
+ /* only support dtb, krlimg/tf, sbi, aon, rootfs, tee, uboot and user-defined type */
+ if (sbmeta_info->image_type > IMAGE_TYPE_NUM || sbmeta_info->image_type < 0) {
+ print_info("Error: image type is out of range\r\n");
+ return CMD_RET_FAILURE;
+ }
+
+ /* only support none, sha1, md5, sha224, sha256, sha384, sha512, sm3 and reserved scheme */
+ if (sbmeta_info->digest_scheme > DIGEST_TYPE_NUM || sbmeta_info->digest_scheme < 0) {
+ print_info("Error: digest type is out of range\r\n");
+ return CMD_RET_FAILURE;
+ }
+
+ /* only support none, rsa1024, rsa2048, ecc256, ecc160, sm2 and reserved scheme */
+ if (sbmeta_info->sign_scheme > SIGN_TYPE_NUM || sbmeta_info->sign_scheme < 0) {
+ print_info("Error: signature type is out of range\r\n");
+ return CMD_RET_FAILURE;
+ }
+
+ /* DTB, TF, TEE, Kernel will be loaded from default partitions specified in env */
+ if (sbmeta_info->image_type != T_ROOTFS && sbmeta_info->image_type != T_USER) {
+ print_info("Image has been loaded\r\n");
+ }
+
+ /* dump sbmeta_info_t */
+ print_info("image medium type: %d\n", sbmeta_info->medium_type);
+ print_info("image load part: mmc %d:%d\n", sbmeta_info->dev, sbmeta_info->part);
+ print_info("image type: %d \n", sbmeta_info->image_type);
+ print_info("image digest scheme: %d\n", sbmeta_info->digest_scheme);
+ print_info("image sign scheme: %d\n", sbmeta_info->sign_scheme);
+ print_info("image enable encryption: %s\n", sbmeta_info->isencrypted ? "en" : "dis");
+ print_info("image file name: %s\n", sbmeta_info->filename);
+ print_info("image digest:");
+ for (int i = 0; i < digest_size[sbmeta_info->digest_scheme]; i++) {
+ print_info("%02X", sbmeta_info->digest[i]);
+ }
+ print_info("\r\n");
+
+ return 0;
+}
+
+
+/* Verify image specified in sbmeta_info_t. The image has been loaded to memory before */
+static int sbmeta_verify_image(uint32_t image_load_addr, uint8_t image_type)
+{
+ uint32_t image_size = 0;
+ char *image_name = NULL;
+
+ /* check image_type to avoid array index out of bounds */
+ if (image_type > IMAGE_TYPE_NUM || image_type < 0) {
+ print_info("Error: image type is out of range\r\n");
+ return CMD_RET_FAILURE;
+ }
+ image_name = image_name_s[image_type];
+
+ /* if image has secure header, do verification. otherwise */
+ if (image_have_head(image_load_addr) == 1) {
+ /* check tee/tf version if needed */
+#ifdef LIGHT_IMG_VERSION_CHECK_IN_BOOT
+ if (image_type == T_TF) {
+ print_info("check TF version in boot \n");
+ if (check_tf_version_in_boot(LIGHT_TF_FW_TMP_ADDR) != 0) {
+ return CMD_RET_FAILURE;
+ }
+ }
+
+ if (image_type == T_TEE) {
+ print_info("check TEE version in boot \n");
+ if (check_tee_version_in_boot(LIGHT_TEE_FW_ADDR) != 0) {
+ return CMD_RET_FAILURE;
+ }
+ }
+#endif
+
+ /* start verifying images */
+ print_info("Process %s image verification ...\n", image_name);
+ dump_image_header_info(image_load_addr);
+ if (image_type == T_UBOOT) {
+ if (csi_sec_uboot_image_verify(image_load_addr, image_load_addr - PUBKEY_HEADER_SIZE) != 0) {
+ print_info("Image(%s) is verified fail, Please go to check!\n\n", image_name);
+ return CMD_RET_FAILURE;
+ }
+ } else {
+ if (csi_sec_custom_image_verify(image_load_addr, UBOOT_STAGE_ADDR) != 0) {
+ print_info("Image(%s) is verified fail, Please go to check!\n\n", image_name);
+ return CMD_RET_FAILURE;
+ }
+ }
+
+ image_size = get_image_size(image_load_addr);
+ print_info("%s image size: %d\n", image_name, image_size);
+ if (image_size < 0) {
+ print_info("GET %s image size error\n", image_name);
+ return CMD_RET_FAILURE;
+ }
+
+ /* move image headers always */
+ if (image_type == T_TF) {
+ memmove((void *)LIGHT_TF_FW_ADDR, (const void *)(image_load_addr + HEADER_SIZE), image_size);
+ } else {
+ memmove((void *)image_load_addr, (const void *)(image_load_addr + HEADER_SIZE), image_size);
+ }
+ } else {
+ /* TF should be moved to LIGHT_TF_FW_ADDR all the cases*/
+ if (image_type == T_TF) {
+ /* while image_size is unknown, reload the image */
+ run_command("ext4load mmc 0:3 0x0 trust_firmware.bin", 0);
+ }
+ }
+
+ return 0;
+}
+
+static int light_sbmetaboot(int argc, char *const argv[])
+{
+ int count = 0;
+ uint32_t sbmeta_size = 0;
+ uint32_t info_addr = 0;
+ uint32_t image_load_addr = 0;
+ char cmd[64] = {0};
+ char *image_name = NULL;
+ sbmeta_info_t *sbmeta_info = NULL;
+
+ /* Load sbmeta image to memory */
+ snprintf(cmd, sizeof(cmd), "ext4load mmc %x:%x 0x%p %s", SBMETA_DEV, SBMETA_PART, LIGHT_SBMETA_ADDR, SBMETA_FILENAME);
+ if (run_command(cmd, 0) != 0) {
+ /* if sbmeta doesn't exist, do secboot by default */
+ print_info("SBMETA doesn't exist, go to verify tf/tee\r\n");
+
+ /*
+ * Verify tf and tee by command secboot.
+ * Note that tf and tee has been loaded in "run bootcmd_load"
+ */
+ if (run_command("secboot", 0) != 0) {
+ return CMD_RET_FAILURE;
+ }
+
+ return 0;
+ }
+
+ /* initialize crypto algorithm interfaces */
+ if (csi_sec_init() != 0) {
+ return CMD_RET_FAILURE;
+ }
+
+ /* Check and verify sbmeta image */
+ if (image_have_head(LIGHT_SBMETA_ADDR) == 1) {
+ print_info("Process SBMETA image verification...\r\n");
+ dump_image_header_info(LIGHT_SBMETA_ADDR);
+ if (csi_sec_custom_image_verify(LIGHT_SBMETA_ADDR, UBOOT_STAGE_ADDR) != 0) {
+ print_info("SBMETA is verified fail, Please go to check!\r\n");
+ return CMD_RET_FAILURE;
+ }
+
+ sbmeta_size = get_image_size(LIGHT_SBMETA_ADDR);
+ print_info("sbmeta_size:%d\r\n", sbmeta_size);
+ if (sbmeta_size != SBMETA_SIZE) {
+ print_info("Error: SBMETA header is wrong! Size must equal to %d bytes!\r\n", SBMETA_SIZE);
+ return CMD_RET_FAILURE;
+ }
+ /* move image headers always */
+ memmove((void *)LIGHT_SBMETA_ADDR, (const void *)(LIGHT_SBMETA_ADDR + HEADER_SIZE), sbmeta_size);
+ } else {
+ /* if sbmeta image is not secure, reset */
+ print_info("Error: SBMETA image must be with signature\r\n");
+ return CMD_RET_FAILURE;
+ }
+
+ /* Parse sbmeta_info_t in image sbmeta, then load and verify specified images */
+ info_addr = LIGHT_SBMETA_ADDR;
+ for (count = 0; count < MAX_ENTRY_NUM; count++) {
+ if (is_sbmeta_info(info_addr) == 0) {
+ /* Dump and check sbmeta info */
+ sbmeta_info = (sbmeta_info_t*)info_addr;
+ if (dump_sbmeta_info(sbmeta_info) != 0) {
+ return CMD_RET_FAILURE;
+ }
+
+ image_name = image_name_s[sbmeta_info->image_type];
+ info_addr += ENTRY_SIZE;
+
+ /*
+ * If image_type != T_USER, load to address specified in light-c910.h;
+ * otherwise, load to user-specified address.
+ */
+ if (sbmeta_info->image_type != T_USER) {
+ image_load_addr = image_addrs[sbmeta_info->image_type];
+ } else {
+ image_load_addr = sbmeta_info->relocated_addr;
+ }
+
+ /*
+ * Load image specified in sbmeta info
+ * Note: only load images don't exist in env "bootcmd_load"
+ */
+ if (sbmeta_info->image_type == T_ROOTFS || sbmeta_info->image_type == T_USER) {
+ snprintf(cmd, sizeof(cmd), "ext4load mmc %x:%x %p %s", sbmeta_info->dev,
+ sbmeta_info->part, \
+ image_load_addr, sbmeta_info->filename);
+ if (run_command(cmd, 0) != 0) {
+ return CMD_RET_FAILURE;
+ }
+ }
+
+ /* Check and verify user-specified image */
+ if (sbmeta_verify_image(image_load_addr, sbmeta_info->image_type) != 0) {
+ return CMD_RET_FAILURE;
+ }
+ } else {
+ break;
+ }
+ }
+
+ /* if sbmeta didn't specify images, reset */
+ if (count == 0) {
+ print_info("Error: SBMETA doesn't specify any images!\r\n");
+ return CMD_RET_FAILURE;
+ }
+
+ /* Clear sbmeta buffer in memory */
+ memset((void *)LIGHT_SBMETA_ADDR, 0, PLAIN_SBMETA_TEXT);
+ return 0;
+}
+
+static int do_sbmetaboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ if (light_sbmetaboot(argc, argv) != 0) {
+ run_command("reset", 0);
+ return -1;
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ sbmetaboot, CONFIG_SYS_MAXARGS, 1, do_sbmetaboot,
+ "load and verify image sbmeta, then verify image files specified in sbmeta",
+ ""
+);
+#endif
+#endif
diff --git a/board/thead/light-c910/sbmeta/sbmeta.h b/board/thead/light-c910/sbmeta/sbmeta.h
new file mode 100644
index 00000000..4955d758
--- /dev/null
+++ b/board/thead/light-c910/sbmeta/sbmeta.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021 Alibaba Group Holding Limited
+ */
+
+#ifndef _LIGHT_SBMETA_H
+#define _LIGHT_SBMETA_H
+
+#include "common.h"
+#include "command.h"
+#include <asm/arch-thead/boot_mode.h>
+
+#define MAX_NAME_SIZE 32
+#define MAX_DIGEST_SIZE 64
+#define SBMETA_MAGIC 0x544D4253 /* = {'S', 'B', 'M', 'T'} */
+
+#if CONFIG_IS_ENABLED(LIGHT_SEC_BOOT_WITH_VERIFY_VAL_A) || CONFIG_IS_ENABLED(LIGHT_SEC_BOOT_WITH_VERIFY_VAL_B) || CONFIG_IS_ENABLED(LIGHT_SEC_BOOT_WITH_VERIFY_LPI4A)
+#define LIGHT_SBMETA_ADDR 0x10000000
+#endif
+#define SBMETA_DEV 0
+#define SBMETA_PART 6
+#define ENTRY_SIZE 128
+#define PLAIN_SBMETA_TEXT 4096
+#define SBMETA_SIZE 4736 /* 4K SMBETA image + 640 footer */
+#define MAX_ENTRY_NUM PLAIN_SBMETA_TEXT / ENTRY_SIZE /* 4K/128=32 */
+#define IMAGE_TYPE_NUM 7
+#define DIGEST_TYPE_NUM 8
+#define SIGN_TYPE_NUM 6
+#define T_USER 7
+#define SBMETA_FILENAME "sbmeta.bin"
+
+typedef struct {
+ int magiccode;
+ uint8_t dev;
+ uint8_t part;
+ uint8_t image_type;
+ uint8_t digest_scheme;
+ uint8_t sign_scheme;
+ uint8_t isencrypted;
+ uint8_t medium_type;
+ uint8_t reserve0;
+ char filename[MAX_NAME_SIZE];
+ uint8_t digest[MAX_DIGEST_SIZE];
+ uint32_t relocated_addr;
+ uint32_t reserved[4];
+} sbmeta_info_t;
+
+#endif
diff --git a/board/thead/light-c910/secimg_load.c b/board/thead/light-c910/secimg_load.c
index f5f1111e..49b8262d 100644
--- a/board/thead/light-c910/secimg_load.c
+++ b/board/thead/light-c910/secimg_load.c
@@ -15,7 +15,7 @@
#define RPMB_BLOCK_SIZE 256
#define RPMB_ROLLBACK_BLOCK_START 1
-#ifndef LIGHT_KDF_RPMB_KEYs
+#ifndef LIGHT_KDF_RPMB_KEY
static const unsigned char emmc_rpmb_key_sample[32] = {0x33, 0x22, 0x11, 0x00, 0x77, 0x66, 0x55, 0x44, \
0xbb, 0xaa, 0x99, 0x88, 0xff, 0xee, 0xdd, 0xcc, \
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
@@ -121,7 +121,7 @@ bool get_system_boot_type(void)
int lc = 0;
sboot_st_t sb_flag = SECURE_BOOT_DIS;
int ret = 0;
-
+# if 0
ret = csi_efuse_get_lc(&lc);
/* 0: LC_INIT, 1: LC_DEV, 2: LC_OEM, 3: LC_PRO */
if ((ret == 0) && (lc != 0)) {
@@ -134,7 +134,7 @@ bool get_system_boot_type(void)
csi_efuse_api_uninit();
}
-
+#endif
return btype;
}