diff options
author | thead_admin <occ_thead@service.alibaba.com> | 2023-12-24 02:32:03 +0000 |
---|---|---|
committer | Han Gao/Revy/Rabenda <rabenda.cn@gmail.com> | 2024-01-22 15:55:16 +0800 |
commit | abe41ba65eb27b7680aa59627501d68b90a8419a (patch) | |
tree | 57c08314c8a961834d87f4bfb7d07d287ebd8423 | |
parent | 3e564f9f0c0db3eaef002815596b0bb35063ecc7 (diff) |
Linux_SDK_V1.4.2
Signed-off-by: thead_admin <occ_thead@service.alibaba.com>
41 files changed, 3126 insertions, 228 deletions
diff --git a/arch/riscv/cpu/c9xx/Makefile b/arch/riscv/cpu/c9xx/Makefile index dab292c1..45b9d785 100644 --- a/arch/riscv/cpu/c9xx/Makefile +++ b/arch/riscv/cpu/c9xx/Makefile @@ -6,3 +6,4 @@ obj-y += dram.o obj-y += cpu.o +obj-y += feature.o diff --git a/arch/riscv/cpu/c9xx/feature.c b/arch/riscv/cpu/c9xx/feature.c new file mode 100644 index 00000000..57c8c098 --- /dev/null +++ b/arch/riscv/cpu/c9xx/feature.c @@ -0,0 +1,114 @@ +#include <common.h> +#include <asm/types.h> +#include <asm/asm.h> +#include <asm/csr.h> + +void setup_features(void) +{ + unsigned int i, cpu_type, cpu_ver; + unsigned long version[8]; + + for (i = 0; i < 8; i++) + version[i] = csr_read(CSR_MCPUID); + + cpu_type = (version[0] >> 18) & 0xf; + cpu_ver = (version[1] >> 12) & 0xffff; + + /* + * Warning: CSR_MCCR2 contains an L2 cache latency setting, + * you need to confirm it by your own soc design. + */ + switch (cpu_type) { + case 0x3: + if (cpu_ver >= 0x1080 && cpu_ver <= 0x10bf) { //1.2.0~1.2.x + csr_write(CSR_MCCR2, 0xe0010009); + csr_write(CSR_MXSTATUS, 0x638000); + csr_write(CSR_MHINT, 0x6e30c); + csr_write(CSR_MHCR, 0x1ff); + } else if (cpu_ver == 0x10ca) { //1.3.10 + csr_write(CSR_MSMPR, 0x1); + csr_write(CSR_MCCR2, 0xe2490009); + csr_write(CSR_MXSTATUS, 0x638000); + csr_write(CSR_MHINT, 0x66e30c); + csr_write(CSR_MHCR, 0x17f); + csr_write(CSR_MHINT2, 0x420000); + csr_write(CSR_MHINT4, 0x410); + } else if (cpu_ver >= 0x1100 && cpu_ver <= 0x113f) { //1.4.0~1.4.x + csr_write(CSR_MSMPR, 0x1); + csr_write(CSR_MCCR2, 0xe2490009); + csr_write(CSR_MXSTATUS, 0x638000); + csr_write(CSR_MHINT, 0x16e30c); + csr_write(CSR_MHCR, 0x1ff); + } else if (cpu_ver >= 0x1140 && cpu_ver <= 0x117f) { //1.5.0~1.5.x + csr_write(CSR_MSMPR, 0x1); + csr_write(CSR_MCCR2, 0xe2490009); + csr_write(CSR_MXSTATUS, 0x638000); + csr_write(CSR_MHINT, 0xe6e30c); + csr_write(CSR_MHINT2, 0x180); + csr_write(CSR_MHCR, 0x1ff); + } else if (cpu_ver >= 0x1180 && cpu_ver <= 0x1183) { //1.6.0~1.6.3 + csr_write(CSR_MSMPR, 0x1); + csr_write(CSR_MCCR2, 0xe249000b); + csr_write(CSR_MXSTATUS, 0x638000); + csr_write(CSR_MHINT, 0x1ee30c); + csr_write(CSR_MHINT2, 0x180); + csr_write(CSR_MHCR, 0x1ff); + } else if (cpu_ver >= 0x1184 && cpu_ver <= 0x123f) { //1.6.4~1.8.x + csr_write(CSR_MSMPR, 0x1); + csr_write(CSR_MCCR2, 0xe249000b); + csr_write(CSR_MXSTATUS, 0x638000); + csr_write(CSR_MHINT, 0x1ee30c); + csr_write(CSR_MHINT2, 0x180); + csr_write(CSR_MHCR, 0x11ff); + } else if (cpu_ver >= 0x2000 && cpu_ver <= 0xffff) { //2.0.0~ + csr_write(CSR_MSMPR, 0x1); + csr_write(CSR_MCCR2, 0xe249000b); + csr_write(CSR_MXSTATUS, 0x438000); + csr_write(CSR_MHINT, 0x31ea32c); + csr_write(CSR_MHINT2, 0x180); + csr_write(CSR_MHCR, 0x11ff); + } else { + while(1); + } + break; + case 0x4: + if (cpu_ver >= 0x1002 && cpu_ver <= 0xffff) { + csr_write(CSR_MHCR, 0x17f); + csr_write(CSR_MXSTATUS, 0x638000); + csr_write(CSR_MHINT, 0x650c); + } else { + while(1); + } + break; + case 0x5: + if (cpu_ver >= 0x0000 && cpu_ver <= 0x0007) { //0.0.0~0.0.7 + csr_write(CSR_MSMPR, 0x1); + csr_write(CSR_MCCR2, 0xe0420008); + csr_write(CSR_MXSTATUS, 0x638000); + csr_write(CSR_MHINT, 0x2c50c); + csr_write(CSR_MHCR, 0x11ff); + } else if (cpu_ver >= 0x0040 && cpu_ver <= 0xffff) { //0.1.0~ + csr_write(CSR_MSMPR, 0x1); + csr_write(CSR_MCCR2, 0xa042000a); + csr_write(CSR_MXSTATUS, 0x438000); + csr_write(CSR_MHINT, 0x21aa10c); + csr_write(CSR_MHCR, 0x10011ff); + } else { + while(1); + } + break; + case 0x6: + if (cpu_ver >= 0x0) { + csr_write(CSR_MSMPR, 0x1); + csr_write(CSR_MCCR2, 0xA042000A); + csr_write(CSR_MXSTATUS, 0x638001); + csr_write(CSR_MHINT, 0x3A1AA10C); + csr_write(CSR_MHCR, 0x10011BF); + } else { + while(1); + } + break; + default: + while(1); + } +} diff --git a/arch/riscv/cpu/mtrap.S b/arch/riscv/cpu/mtrap.S index 5b7ab92d..83e1107a 100644 --- a/arch/riscv/cpu/mtrap.S +++ b/arch/riscv/cpu/mtrap.S @@ -104,3 +104,45 @@ trap_entry: LREG x2, 2 * REGBYTES(sp) addi sp, sp, 32 * REGBYTES MODE_PREFIX(ret) + + /* trap secondary_entry */ + .align 10 + .global secondary_entry +secondary_entry: + /* + * Clear L1 cache & BTB & BHT ... + */ + li t0, 0x70013 + csrw CSR_MCOR, t0 + + /* + * Enable cache coherency + */ + li t0, 1 + csrw CSR_MSMPR, t0 + + /* + *Prepare percpu stack + */ + csrr t0, mhartid + li t1, 0x100 + mul t1, t1, t0 + lla sp, stacks + add sp, sp, t1 + + /* + * Call C routine + */ + call setup_features + call next_stage + + /* + * Never get here, dead loop + */ + j . + + .align 10 +stacks: + .rept 0x1000 + .long + .endr diff --git a/arch/riscv/dts/light-a-val.dts b/arch/riscv/dts/light-a-val.dts index 227f5a29..96ca43a6 100644 --- a/arch/riscv/dts/light-a-val.dts +++ b/arch/riscv/dts/light-a-val.dts @@ -306,8 +306,8 @@ spi-max-frequency = <100000000>; #address-cells = <1>; #size-cells = <0>; - flash@0 { - compatible = "jedec,spi-nor"; + tpm@0{ + compatible = "z32h330tc,z32h330tc-spi"; reg = <0>; spi-max-frequency = <40000000>; }; diff --git a/arch/riscv/include/asm/arch-thead/boot_mode.h b/arch/riscv/include/asm/arch-thead/boot_mode.h index ca4217fd..b56cafd3 100644 --- a/arch/riscv/include/asm/arch-thead/boot_mode.h +++ b/arch/riscv/include/asm/arch-thead/boot_mode.h @@ -34,7 +34,9 @@ typedef enum image_type { T_ROOTFS = 4, T_TF = 2, T_TEE = 5, - T_UBOOT = 6 + T_UBOOT = 6, + T_USER = 7, + T_SBMETA = 8, } img_type_t; static const char header_magic[4] = {'T', 'H', 'E', 'D'}; diff --git a/arch/riscv/include/asm/arch-thead/light-reset.h b/arch/riscv/include/asm/arch-thead/light-reset.h new file mode 100644 index 00000000..44aa993c --- /dev/null +++ b/arch/riscv/include/asm/arch-thead/light-reset.h @@ -0,0 +1,17 @@ +#ifndef __LIGHT_RESET_H__ +#define __LIGHT_RESET_H__ + +#define APSYS_RSTGEN_BASE 0xFFEF014000 +#define REG_C910_SWRST (APSYS_RSTGEN_BASE + 0x4) +#define APSYS_REG_BASE 0xFFEF018000 +#define REG_C910_CORE0_RVBA_L (APSYS_REG_BASE + 0x50) +#define REG_C910_CORE0_RVBA_H (APSYS_REG_BASE + 0x54) +#define REG_C910_CORE1_RVBA_L (APSYS_REG_BASE + 0x58) +#define REG_C910_CORE1_RVBA_H (APSYS_REG_BASE + 0x5C) +#define REG_C910_CORE2_RVBA_L (APSYS_REG_BASE + 0x60) +#define REG_C910_CORE2_RVBA_H (APSYS_REG_BASE + 0x64) +#define REG_C910_CORE3_RVBA_L (APSYS_REG_BASE + 0x68) +#define REG_C910_CORE3_RVBA_H (APSYS_REG_BASE + 0x6C) +#define REG_PLIC_DELEGATE 0xffd81ffffc + +#endif /* __LIGHT_RESET_H__ */ diff --git a/arch/riscv/include/asm/atomic.h b/arch/riscv/include/asm/atomic.h new file mode 100644 index 00000000..b79e1f89 --- /dev/null +++ b/arch/riscv/include/asm/atomic.h @@ -0,0 +1,53 @@ +#ifndef _ASM_RISCV_ATOMIC_H +#define _ASM_RISCV_ATOMIC_H + +#include <linux/types.h> +#include <asm/barrier.h> + +typedef struct { + volatile long counter; +} atomic_t; + +#define ATOMIC_INIT(_lptr, val) (_lptr)->counter = (val) + +#define ATOMIC_INITIALIZER(val) \ + { \ + .counter = (val), \ + } + +long atomic_read(atomic_t *atom) +{ + long ret = atom->counter; + rmb(); + return ret; +} + +void atomic_write(atomic_t *atom, long value) +{ + atom->counter = value; + wmb(); +} + +long atomic_add_return(atomic_t *atom, long value) +{ + long ret; +#if __SIZEOF_LONG__ == 4 + __asm__ __volatile__(" amoadd.w.aqrl %1, %2, %0" + : "+A"(atom->counter), "=r"(ret) + : "r"(value) + : "memory"); +#elif __SIZEOF_LONG__ == 8 + __asm__ __volatile__(" amoadd.d.aqrl %1, %2, %0" + : "+A"(atom->counter), "=r"(ret) + : "r"(value) + : "memory"); +#endif + return ret + value; +} + +long atomic_sub_return(atomic_t *atom, long value) +{ + return atomic_add_return(atom, -value); +} + +#endif /* _ASM_RISCV_ATOMIC_H */ diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index dd5601b0..c0e17996 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -104,15 +104,23 @@ #define CSR_CYCLEH 0xc80 #define CSR_TIMEH 0xc81 #define CSR_INSTRETH 0xc82 +#define CSR_MVENDORID 0xf11 +#define CSR_MARCHID 0xf12 +#define CSR_MIMPID 0xf13 #define CSR_MHARTID 0xf14 +#define CSR_MCPUID 0xfc0 -#define CSR_SMPEN 0x7f3 -#define CSR_MTEE 0x7f4 +#define CSR_SMPEN 0x7f3 +#define CSR_MTEE 0x7f4 #define CSR_MCOR 0x7c2 #define CSR_MHCR 0x7c1 #define CSR_MCCR2 0x7c3 #define CSR_MHINT 0x7c5 +#define CSR_MHINT2 0x7cc +#define CSR_MHINT3 0x7cd +#define CSR_MHINT4 0x7ce #define CSR_MXSTATUS 0x7c0 +#define CSR_MSMPR 0x7f3 #define CSR_PLIC_BASE 0xfc1 #define sync_is() asm volatile (".long 0x01b0000b") diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index 942a1174..837154d6 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -14,7 +14,11 @@ #include <opensbi.h> #include <asm/byteorder.h> #include <asm/csr.h> +#include <asm/io.h> #include <asm/smp.h> +#include <asm/barrier.h> +#include <asm/atomic.h> +#include <asm/arch-thead/light-reset.h> #include <dm/device.h> #include <dm/root.h> #include <u-boot/zlib.h> @@ -22,6 +26,12 @@ DECLARE_GLOBAL_DATA_PTR; static struct fw_dynamic_info opensbi_info; +static atomic_t _harts_count = ATOMIC_INITIALIZER(3); +static ulong _load_start; +static ulong _dtb_addr; +static ulong _dyn_info_addr; + +extern void secondary_entry(); __weak void board_quiesce_devices(void) { @@ -81,6 +91,58 @@ static void boot_prep_linux(bootm_headers_t *images) } } +void next_stage(void) +{ + void (*next_entry)(unsigned long arg0,unsigned long arg1,unsigned long arg2); + + next_entry = (void (*))(_load_start); + ulong hartid = csr_read(CSR_MHARTID); + + atomic_sub_return(&_harts_count, 1); + /* + * set $a0 = hartid + * set $a1 = $dtb_addr + * set $a2 = $dyn_info_addr + */ + next_entry(hartid, _dtb_addr , _dyn_info_addr); +} + +bool has_reset_sample(ulong dtb_addr) +{ + int node_offset; + node_offset = fdt_path_offset(dtb_addr, "/soc/reset-sample"); + if (node_offset < 0) { + printf("## fdt has no reset_sample\n"); + return false; + } else { + printf("## fdt has reset_sample\n"); + return true; + } +} + +static void reset_sample(void) +{ + ulong addr; + uint addr_l, addr_h; + + // RESET ADDR + addr = (unsigned long)(void *)secondary_entry; + addr_h = (uint)(addr >> 32); + addr_l = (uint)(addr & 0xFFFFFFFF); + // writel(addr_h, (volatile void *)REG_C910_CORE0_RVBA_H); + // writel(addr_l, (volatile void *)REG_C910_CORE0_RVBA_L); + writel(addr_h, (volatile void *)REG_C910_CORE1_RVBA_H); + writel(addr_l, (volatile void *)REG_C910_CORE1_RVBA_L); + writel(addr_h, (volatile void *)REG_C910_CORE2_RVBA_H); + writel(addr_l, (volatile void *)REG_C910_CORE2_RVBA_L); + writel(addr_h, (volatile void *)REG_C910_CORE3_RVBA_H); + writel(addr_l, (volatile void *)REG_C910_CORE3_RVBA_L); + + // RESET + writel(0x1F, (volatile void *)REG_C910_SWRST); + writel(0x1, (volatile void *)REG_PLIC_DELEGATE); +} + static void boot_jump_linux(bootm_headers_t *images, int flag) { void (*kernel)(ulong hart, void *dtb, struct fw_dynamic_info *p); @@ -98,12 +160,25 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) announce_and_cleanup(fake); - opensbi_info.magic = FW_DYNAMIC_INFO_MAGIC_VALUE; - opensbi_info.version = 0x1; - opensbi_info.next_addr = images->os.start; - opensbi_info.next_mode = FW_DYNAMIC_INFO_NEXT_MODE_S; - opensbi_info.options = 0; - opensbi_info.boot_hart = 0; + _load_start = kernel; + _dtb_addr = images->ft_addr; + _dyn_info_addr = (ulong)&opensbi_info; + if (!has_reset_sample(_dtb_addr)) { + opensbi_info.magic = FW_DYNAMIC_INFO_MAGIC_VALUE; + opensbi_info.version = 0x2; + opensbi_info.next_addr = images->os.start; + opensbi_info.next_mode = FW_DYNAMIC_INFO_NEXT_MODE_S; + opensbi_info.options = 0; + opensbi_info.boot_hart = 0; + reset_sample(); + } else { + opensbi_info.magic = FW_DYNAMIC_INFO_MAGIC_VALUE; + opensbi_info.version = 0x1; + opensbi_info.next_addr = images->os.start; + opensbi_info.next_mode = FW_DYNAMIC_INFO_NEXT_MODE_S; + opensbi_info.options = 0; + opensbi_info.boot_hart = 0; + } if (!fake) { if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) { diff --git a/board/thead/light-c910/Kconfig b/board/thead/light-c910/Kconfig index abac54f3..e860e293 100644 --- a/board/thead/light-c910/Kconfig +++ b/board/thead/light-c910/Kconfig @@ -66,6 +66,10 @@ config LIGHT_ANDROID_BOOT_IMAGE_VAL_LPI4A bool "light board-lpi4a android image" default n +config LIGHT_ANDROID_BOOT_IMAGE_ANT_REF + bool "light board ant ref android image" + default n + config LIGHT_SEC_BOOT_WITH_VERIFY_VAL_A bool "light board-a security boot with verification" default n @@ -248,10 +252,11 @@ config DDR_LP4_2133_SINGLERANK help Enabling this will support lpddr4 2133 singlerank configuration. -config DDR_ROW16 - bool "LPDDR4/4X 17-bit row address support" +config DDR_DDP + bool "LPDDR4/4X Dual Die Package support" help - Enabling this will support ddr 17-bit row address (16:0). + Enabling this will support ddr Dual Die Package configuration. + e.g. to support 8GB ddr device with 17-bit row address (16:0) config DDR_H32_MODE bool "LPDDR4/4X 32bit mode configuration" diff --git a/board/thead/light-c910/board.c b/board/thead/light-c910/board.c index 6ebbbb59..7d705b48 100644 --- a/board/thead/light-c910/board.c +++ b/board/thead/light-c910/board.c @@ -10,6 +10,8 @@ #include <usb.h> #include <cpu_func.h> #include <asm/gpio.h> +#include <abuf.h> +#include "sec_library.h" #ifdef CONFIG_USB_DWC3 static struct dwc3_device dwc3_device_data = { @@ -51,9 +53,11 @@ int g_dnl_board_usb_cable_connected(void) #define C906_RST_ADDR_L 0xfffff48048 #define C906_RST_ADDR_H 0xfffff4804C + #define C906_START_ADDRESS_L 0x32000000 #define C906_START_ADDRESS_H 0x00 #define C910_C906_START_ADDRESS 0x0032000000 + #define C906_CPR_IPCG_ADDRESS 0xFFCB000010 #define C906_IOCTL_GPIO_SEL_ADDRESS 0xFFCB01D000 #define C906_IOCTL_AF_SELH_ADDRESS 0xFFCB01D008 @@ -140,4 +144,48 @@ int misc_init_r(void) light_c910_set_gpio_output_high(); return 0; -}
\ No newline at end of file +} + +#ifdef CONFIG_BOARD_RNG_SEED +const char pre_gen_seed[128] = {211, 134, 226, 116, 1, 13, 224, 196, 88, 213, 188, 219, 128, 41, 231, 228, 129, 123, 173, 234, 219, 79, 152, 154, 169, 27, 183, 166, 52, 21, 118, 7, 155, 89, 124, 156, 102, 92, 96, 190, 49, 28, 154, 177, 69, 129, 149, 199, 253, 66, 177, 216, 146, 73, 114, 59, 100, 41, 225, 152, 62, 88, 160, 217, 177, 28, 117, 23, 120, 213, 213, 169, 242, 111, 90, 55, 241, 239, 254, 238, 50, 175, 198, 196, 248, 56, 255, 92, 97, 224, 245, 160, 56, 149, 121, 233, 177, 239, 0, 41, 196, 214, 210, 182, 69, 44, 238, 54, 27, 236, 36, 77, 156, 234, 17, 148, 34, 16, 241, 132, 241, 230, 36, 41, 123, 157, 19, 44}; +/* Use hardware rng to seed Linux random. */ +int board_rng_seed(struct abuf *buf) +{ + size_t len = 128; + uint8_t *data = NULL; + int sc_err = SC_FAIL; + + /* abuf is working up in asynchronization mode, so the memory usage for random data storage must + be allocated first. */ + data = malloc(len); + if (!data) { + printf("Fail to allocate memory, using pre-defined entropy\n"); + return -1; + } + +#if defined(CONFIG_AVB_HW_ENGINE_ENABLE) + /* We still use pre-define entropy data in case hardware random engine does not work */ + sc_err = csi_sec_library_init(); + if (sc_err != SC_OK) { + printf("Fail to initialize sec library, using pre-defined entropy\n"); + goto _err; + } + + sc_err = sc_rng_get_random_bytes(data, len); + if (sc_err != SC_OK) { + printf("Fail to retrieve random data, using pre-defined entropy\n"); + goto _err; + } + + abuf_init_set(buf, data, len); + return 0; + +_err: +#endif + /* use pre-defined random data in case of the random engine is disable */ + memcpy(data, pre_gen_seed, len); + abuf_init_set(buf, data, len); + + return 0; +} +#endif diff --git a/board/thead/light-c910/boot.c b/board/thead/light-c910/boot.c index 8bc067a7..645f1e37 100644 --- a/board/thead/light-c910/boot.c +++ b/board/thead/light-c910/boot.c @@ -31,7 +31,7 @@ //#define LIGHT_IMG_VERSION_CHECK_IN_BOOT 1 /* the sample rpmb key is only used for testing */ -#ifndef LIGHT_KDF_RPMB_KEY +#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, \ @@ -110,7 +110,7 @@ func_exit: } #endif -int csi_rpmb_write_access_key(void) +int csi_rpmb_write_access_key(void) { #ifdef LIGHT_KDF_RPMB_KEY unsigned long *temp_rpmb_key_addr = NULL; @@ -162,7 +162,7 @@ int csi_tf_get_image_version(unsigned int *ver) if (ret == 0) { *ver = (blkdata[16] << 8) + blkdata[17]; } - + return ret; } @@ -179,9 +179,9 @@ int csi_tf_set_image_version(unsigned int ver) blkdata[17] = ver & 0xFF; /* tf version reside in RPMB block#0, offset#16*/ -#ifndef LIGHT_KDF_RPMB_KEY +#ifndef LIGHT_KDF_RPMB_KEY temp_rpmb_key_addr = (unsigned long *)emmc_rpmb_key_sample; -#else +#else uint8_t kdf_rpmb_key[32]; uint32_t kdf_rpmb_key_length = 0; int ret = 0; @@ -245,9 +245,9 @@ int csi_tee_set_image_version(unsigned int ver) blkdata[1] = ver & 0xFF; /* tf version reside in RPMB block#0, offset#16*/ -#ifndef LIGHT_KDF_RPMB_KEY +#ifndef LIGHT_KDF_RPMB_KEY temp_rpmb_key_addr = (unsigned long *)emmc_rpmb_key_sample; -#else +#else uint8_t kdf_rpmb_key[32]; uint32_t kdf_rpmb_key_length = 0; int ret = 0; @@ -268,6 +268,57 @@ int csi_tee_set_upgrade_version(void) return csi_tee_set_image_version(upgrade_image_version); } +int csi_sbmeta_get_image_version(unsigned int *ver) +{ + char runcmd[64] = {0}; + unsigned char blkdata[256]; + int ret = 0; + + /* sbmeta version reside in RPMB block#0, offset#48*/ + sprintf(runcmd, "mmc rpmb read 0x%lx 0 1", (unsigned long)blkdata); + ret = run_command(runcmd, 0); + if (ret == 0) { + *ver = (blkdata[48] << 8) + blkdata[49]; + } + + return ret; +} + +int csi_sbmeta_set_image_version(unsigned int ver) +{ + char runcmd[64] = {0}; + unsigned char blkdata[256]; + unsigned long *temp_rpmb_key_addr = NULL; + + /* sbmeta version reside in RPMB block#0, offset#48*/ + sprintf(runcmd, "mmc rpmb read 0x%lx 0 1", (unsigned long)blkdata); + run_command(runcmd, 0); + blkdata[48] = (ver & 0xFF00) >> 8; + blkdata[49] = ver & 0xFF; + /* sbmeta version reside in RPMB block#0, offset#48*/ +#ifndef LIGHT_KDF_RPMB_KEY + temp_rpmb_key_addr = (unsigned long *)emmc_rpmb_key_sample; +#else + uint8_t kdf_rpmb_key[32]; + uint32_t kdf_rpmb_key_length = 0; + int ret = 0; + ret = csi_kdf_gen_hmac_key(kdf_rpmb_key, &kdf_rpmb_key_length); + if (ret != 0) { + return -1; + } + temp_rpmb_key_addr = (unsigned long *)kdf_rpmb_key; +#endif + sprintf(runcmd, "mmc rpmb write 0x%lx 0 1 0x%lx", (unsigned long)blkdata, (unsigned long)temp_rpmb_key_addr); + run_command(runcmd, 0); + + return 0; +} + +int csi_sbmeta_set_upgrade_version(void) +{ + return csi_sbmeta_set_image_version(upgrade_image_version); +} + int csi_uboot_get_image_version(unsigned int *ver) { #ifdef LIGHT_UBOOT_VERSION_IN_ENV @@ -476,6 +527,33 @@ int check_tee_version_in_boot(unsigned long tee_addr) return 0; } +int check_sbmeta_version_in_boot(unsigned long sbmeta_addr) +{ + int ret = 0; + unsigned int img_version = 0; + unsigned int expected_img_version = 0; + + img_version = get_image_version(sbmeta_addr); + if (img_version == 0) { + printf("get sbmeta image version fail\n"); + return -1; + } + + ret = csi_sbmeta_get_image_version(&expected_img_version); + if (ret != 0) { + printf("Get sbmeta expected img version fail\n"); + return -1; + } + + ret = check_image_version_rule(img_version, expected_img_version); + if (ret != 0) { + printf("Image version breaks the rule\n"); + return -1; + } + + return 0; +} + int light_vimage(int argc, char *const argv[]) { int ret = 0; @@ -483,14 +561,14 @@ int light_vimage(int argc, char *const argv[]) unsigned int new_img_version = 0; unsigned int cur_img_version = 0; char imgname[32] = {0}; - - if (argc < 3) + + if (argc < 3) return CMD_RET_USAGE; - + /* Parse input parameters */ vimage_addr = simple_strtoul(argv[1], NULL, 16); strcpy(imgname, argv[2]); - + /* Retrieve desired information from image header */ new_img_version = get_image_version(vimage_addr); if (new_img_version == 0) { @@ -524,13 +602,20 @@ int light_vimage(int argc, char *const argv[]) printf("Get kernel img version fail\n"); return CMD_RET_FAILURE; } - } else if (strcmp(imgname, UBOOT_PART_NAME) == 0) { + } else if (strcmp(imgname, SBMETA_PART_NAME) == 0){ + + ret = csi_sbmeta_get_image_version(&cur_img_version); + if (ret != 0) { + printf("Get sbmeta img version fail\n"); + return CMD_RET_FAILURE; + } + } else if (strcmp(imgname, UBOOT_PART_NAME) == 0) { ret = csi_uboot_get_image_version(&cur_img_version); if (ret != 0) { printf("Get uboot img version fail\n"); return CMD_RET_FAILURE; - } - + } + // Check uboot maximization version > 64 if (((new_img_version & 0xFF00) >> 8) > UBOOT_MAX_VER) { printf("UBOOT Image version has reached to max-version\n"); @@ -578,6 +663,11 @@ int light_vimage(int argc, char *const argv[]) if (ret != 0) { return CMD_RET_FAILURE; } + } else if (strcmp(imgname, SBMETA_PART_NAME) == 0) { + ret = verify_customer_image(T_SBMETA, vimage_addr); + if (ret != 0) { + return CMD_RET_FAILURE; + } } else { printf("Error: unknow image name\n"); return CMD_RET_FAILURE; @@ -698,15 +788,19 @@ void sec_firmware_version_dump(void) unsigned int tf_ver = 0; unsigned int tee_ver = 0; unsigned int uboot_ver = 0; + unsigned int sbmeta_ver = 0; unsigned int tf_ver_env = 0; unsigned int tee_ver_env = 0; + unsigned int sbmeta_ver_env = 0; csi_uboot_get_image_version(&uboot_ver); csi_tf_get_image_version(&tf_ver); csi_tee_get_image_version(&tee_ver); + csi_sbmeta_get_image_version(&sbmeta_ver); /* Keep sync with version in RPMB, the Following version could be leveraged by OTA client */ tee_ver_env = env_get_hex("tee_version", 0); tf_ver_env = env_get_hex("tf_version", 0); + sbmeta_ver_env = env_get_hex("sbmeta_version", 0); if ((tee_ver_env != tee_ver) && (tee_ver != 0)) { env_set_hex("tee_version", tee_ver); run_command("saveenv", 0); @@ -717,11 +811,17 @@ void sec_firmware_version_dump(void) run_command("saveenv", 0); } + if ((sbmeta_ver_env != sbmeta_ver) && (sbmeta_ver != 0)) { + env_set_hex("sbmeta_version", sbmeta_ver); + run_command("saveenv", 0); + } + printf("\n\n"); printf("Secure Firmware image version info: \n"); printf("uboot Firmware v%d.0\n", (uboot_ver & 0xff00) >> 8); printf("Trust Firmware v%d.%d\n", (tf_ver & 0xff00) >> 8, tf_ver & 0xff); printf("TEE OS v%d.%d\n", (tee_ver & 0xff00) >> 8, tee_ver & 0xff); + printf("SBMETA v%d.%d\n", (sbmeta_ver & 0xff00) >> 8, sbmeta_ver & 0xff); printf("\n\n"); } @@ -738,13 +838,11 @@ void sec_upgrade_thread(void) sec_upgrade_flag = env_get_hex("sec_upgrade_mode", 0); if (sec_upgrade_flag == 0) return; - printf("bootstrap: sec_upgrade_flag: %x\n", sec_upgrade_flag); if (sec_upgrade_flag == TF_SEC_UPGRADE_FLAG) { - /* STEP 1: read upgrade image (trust_firmware.bin) from stash partition */ printf("read upgrade image (trust_firmware.bin) from stash partition \n"); - sprintf(runcmd, "ext4load mmc 0:5 0x%p trust_firmware.bin", (void *)temp_addr); + sprintf(runcmd, "ext4load mmc 0:4 0x%p trust_firmware.bin", (void *)temp_addr); printf("runcmd:%s\n", runcmd); ret = run_command(runcmd, 0); if (ret != 0) { @@ -805,7 +903,7 @@ _upgrade_tf_exit: /* STEP 1: read upgrade image (tee.bin) from stash partition */ printf("read upgrade image (tee.bin) from stash partition \n"); - sprintf(runcmd, "ext4load mmc 0:5 0x%p tee.bin", (void *)temp_addr); + sprintf(runcmd, "ext4load mmc 0:4 0x%p tee.bin", (void *)temp_addr); printf("runcmd:%s\n", runcmd); ret = run_command(runcmd, 0); if (ret != 0) { @@ -815,7 +913,7 @@ _upgrade_tf_exit: /* Fetch the total file size after read out operation end */ upgrade_file_size = env_get_hex("filesize", 0); printf("TEE upgrade file size: %d\n", upgrade_file_size); - + /*store image to temp buffer as temp_addr may be decrypted*/ image_malloc_buffer = malloc(upgrade_file_size); if ( image_malloc_buffer == NULL ) { @@ -835,8 +933,8 @@ _upgrade_tf_exit: } /* STEP 3: update tee partition */ - printf("read upgrade image (tee.bin) into tf partition \n"); - sprintf(runcmd, "ext4write mmc 0:4 0x%p /tee.bin 0x%x", (void *)image_buffer, upgrade_file_size); + printf("read upgrade image (tee.bin) into sbmeta partition \n"); + sprintf(runcmd, "ext4write mmc 0:3 0x%p /tee.bin 0x%x", (void *)image_buffer, upgrade_file_size); printf("runcmd:%s\n", runcmd); ret = run_command(runcmd, 0); if (ret != 0) { @@ -857,12 +955,73 @@ _upgrade_tee_exit: run_command("env set sec_upgrade_mode 0", 0); run_command("saveenv", 0); run_command("reset", 0); - + + if ( image_malloc_buffer != NULL ) { + free(image_malloc_buffer); + image_malloc_buffer = NULL; + } + } else if (sec_upgrade_flag == SBMETA_SEC_UPGRADE_FLAG) { + + /* STEP 1: read upgrade image (sbmeta.bin) from stash partition */ + printf("read upgrade image (sbmeta.bin) from stash partition \n"); + sprintf(runcmd, "ext4load mmc 0:4 0x%p sbmeta.bin", (void *)temp_addr); + printf("runcmd:%s\n", runcmd); + ret = run_command(runcmd, 0); + if (ret != 0) { + printf("SBMETA Upgrade process is terminated due to some reason\n"); + goto _upgrade_sbmeta_exit; + } + /* Fetch the total file size after read out operation end */ + upgrade_file_size = env_get_hex("filesize", 0); + printf("SBMETA upgrade file size: %d\n", upgrade_file_size); + + /*store image to temp buffer as temp_addr may be decrypted*/ + image_malloc_buffer = malloc(upgrade_file_size); + if ( image_malloc_buffer == NULL ) { + image_buffer = (uint8_t*)temp_addr + upgrade_file_size; + } else { + image_buffer = image_malloc_buffer; + } + memcpy(image_buffer, (void*)temp_addr, upgrade_file_size); + + /* STEP 2: verify its authentiticy here */ + sprintf(runcmd, "vimage 0x%p sbmeta", (void *)temp_addr); + printf("runcmd:%s\n", runcmd); + ret = run_command(runcmd, 0); + if (ret != 0) { + printf("SBMETA Image verification fail and upgrade process terminates\n"); + goto _upgrade_sbmeta_exit; + } + + /* STEP 3: update sbmeta partition */ + printf("read upgrade image (SBMETA.bin) into sbmeta partition \n"); + sprintf(runcmd, "ext4write mmc 0:3 0x%p /sbmeta.bin 0x%x", (void *)image_buffer, upgrade_file_size); + printf("runcmd:%s\n", runcmd); + ret = run_command(runcmd, 0); + if (ret != 0) { + printf("SBMETA upgrade process is terminated due to some reason\n"); + goto _upgrade_sbmeta_exit; + } + + /* STEP 4: update sbmeta version */ + ret = csi_sbmeta_set_upgrade_version(); + if (ret != 0) { + printf("Set sbmeta upgrade version fail\n"); + goto _upgrade_sbmeta_exit; + } + + printf("\n\nSBMETA image ugprade process is successful\n\n"); +_upgrade_sbmeta_exit: + /* set secure upgrade flag to 0 that indicate upgrade over */ + run_command("env set sec_upgrade_mode 0", 0); + run_command("saveenv", 0); + run_command("reset", 0); + if ( image_malloc_buffer != NULL ) { free(image_malloc_buffer); image_malloc_buffer = NULL; } - } else if (sec_upgrade_flag == UBOOT_SEC_UPGRADE_FLAG) { + } else if (sec_upgrade_flag == UBOOT_SEC_UPGRADE_FLAG) { unsigned int block_cnt; struct blk_desc *dev_desc; const unsigned long uboot_temp_addr=0x80000000; @@ -871,7 +1030,7 @@ _upgrade_tee_exit: /* STEP 1: read upgrade image (u-boot-with-spl.bin) from stash partition */ printf("read upgrade image (u-boot-with-spl.bin) from stash partition \n"); - sprintf(runcmd, "ext4load mmc 0:5 0x%p u-boot-with-spl.bin", (void *)temp_addr); + sprintf(runcmd, "ext4load mmc 0:4 0x%p u-boot-with-spl.bin", (void *)temp_addr); printf("runcmd:%s\n", runcmd); ret = run_command(runcmd, 0); if (ret != 0) { diff --git a/board/thead/light-c910/light.c b/board/thead/light-c910/light.c index 6a765400..7e93d308 100644 --- a/board/thead/light-c910/light.c +++ b/board/thead/light-c910/light.c @@ -1575,7 +1575,7 @@ static void light_iopin_init(void) light_pin_mux(CLK_OUT_2, 0); light_pin_cfg(CLK_OUT_2, PIN_SPEED_NORMAL, PIN_PU, 2); light_pin_mux(CLK_OUT_3, 0); - light_pin_cfg(CLK_OUT_3, PIN_SPEED_NORMAL, PIN_PU, 2); + light_pin_cfg(CLK_OUT_3, PIN_SPEED_NORMAL, PIN_PU, 2); // light_pin_mux(GPIO1_21,3); light_pin_mux(GPIO1_22, 3); @@ -1595,7 +1595,7 @@ static void light_iopin_init(void) light_pin_cfg(GPIO1_30, PIN_SPEED_NORMAL, PIN_PN, 2); ///<DBB2LEDDRIVER_EN light_pin_cfg(UART0_TXD, PIN_SPEED_NORMAL, PIN_PN, 2); - light_pin_cfg(UART0_RXD, PIN_SPEED_NORMAL, PIN_PN, 2); + light_pin_cfg(UART0_RXD, PIN_SPEED_NORMAL, PIN_PN, 2); /*ap-pdmux on righ/top*/ // light_pin_mux(QSPI0_SCLK,3); ///NC @@ -2432,10 +2432,10 @@ static void light_usb_boot_check(void) if (boot_mode & BIT(2)) return; - /*check board id of uboot image*/ + /*check board id of uboot image*/ ret = check_image_board_id((uint8_t*)SRAM_BASE_ADDR); if (ret != 0) { - while(1); + while(1); } #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG diff --git a/board/thead/light-c910/lpddr4/src/ddr_common_func.c b/board/thead/light-c910/lpddr4/src/ddr_common_func.c index 40276f6e..a9073310 100644 --- a/board/thead/light-c910/lpddr4/src/ddr_common_func.c +++ b/board/thead/light-c910/lpddr4/src/ddr_common_func.c @@ -14,7 +14,7 @@ unsigned long get_ddr_density() { #ifdef CONFIG_DDR_DUAL_RANK mul = 2; #endif -#ifdef CONFIG_DDR_ROW16 +#ifdef CONFIG_DDR_DDP mul *= 2; #endif #ifdef CONFIG_DDR_H32_MODE @@ -876,7 +876,7 @@ if(bits==64) { #endif wr(ADDRMAP0,0x0004001f); // +2 if(rank_num==2) { -#ifdef CONFIG_DDR_ROW16 +#ifdef CONFIG_DDR_DDP wr(ADDRMAP0,0x00040019);//16GB #else wr(ADDRMAP0,0x00040018);//8GB @@ -888,7 +888,7 @@ if(bits==64) { wr(ADDRMAP4,0x00001f1f); //col b11~ col b10 wr(ADDRMAP5,0x080f0808); //row_b11 row b2_10 row b1 row b0 +6 wr(ADDRMAP6,0x08080808); -#ifdef CONFIG_DDR_ROW16 +#ifdef CONFIG_DDR_DDP wr(ADDRMAP7,0x00000f08); #else wr(ADDRMAP7,0x00000f0f); diff --git a/board/thead/light-c910/lpddr4/src/lpddr4_init.c b/board/thead/light-c910/lpddr4/src/lpddr4_init.c index 68123980..0c5ba407 100755 --- a/board/thead/light-c910/lpddr4/src/lpddr4_init.c +++ b/board/thead/light-c910/lpddr4/src/lpddr4_init.c @@ -26,11 +26,993 @@ void lpddr4_init(enum DDR_TYPE type, int rank_num, int speed, enum DDR_BITWIDTH lp4_phy_train1d2d(type, speed, bits); + dwc_ddrphy_phyinit_regInterface(); + ctrl_en(bits); enable_axi_port(0x1f); - + enable_auto_refresh(); lpddr4_auto_selref(); } + +static const uint32_t RetRegList_addr[934] = +{ + 0x1005f, + 0x1015f, + 0x1105f, + 0x1115f, + 0x1205f, + 0x1215f, + 0x1305f, + 0x1315f, + 0x55, + 0x1055, + 0x2055, + 0x3055, + 0x4055, + 0x5055, + 0x200c5, + 0x2002e, + 0x90204, + 0x20024, + 0x2003a, + 0x2007d, + 0x2007c, + 0x20056, + 0x1004d, + 0x1014d, + 0x1104d, + 0x1114d, + 0x1204d, + 0x1214d, + 0x1304d, + 0x1314d, + 0x10049, + 0x10149, + 0x11049, + 0x11149, + 0x12049, + 0x12149, + 0x13049, + 0x13149, + 0x43, + 0x1043, + 0x2043, + 0x3043, + 0x4043, + 0x5043, + 0x20018, + 0x20075, + 0x20050, + 0x2009b, + 0x20008, + 0x20088, + 0x200b2, + 0x10043, + 0x10143, + 0x11043, + 0x11143, + 0x12043, + 0x12143, + 0x13043, + 0x13143, + 0x200fa, + 0x20019, + 0x200f0, + 0x200f1, + 0x200f2, + 0x200f3, + 0x200f4, + 0x200f5, + 0x200f6, + 0x200f7, + 0x20025, + 0x2002d, + 0x20021, + 0x2002c, + 0xd0000, + 0x90000, + 0x90001, + 0x90002, + 0x90003, + 0x90004, + 0x90005, + 0x90029, + 0x9002a, + 0x9002b, + 0x9002c, + 0x9002d, + 0x9002e, + 0x9002f, + 0x90030, + 0x90031, + 0x90032, + 0x90033, + 0x90034, + 0x90035, + 0x90036, + 0x90037, + 0x90038, + 0x90039, + 0x9003a, + 0x9003b, + 0x9003c, + 0x9003d, + 0x9003e, + 0x9003f, + 0x90040, + 0x90041, + 0x90042, + 0x90043, + 0x90044, + 0x90045, + 0x90046, + 0x90047, + 0x90048, + 0x90049, + 0x9004a, + 0x9004b, + 0x9004c, + 0x9004d, + 0x9004e, + 0x9004f, + 0x90050, + 0x90051, + 0x90052, + 0x90053, + 0x90054, + 0x90055, + 0x90056, + 0x90057, + 0x90058, + 0x90059, + 0x9005a, + 0x9005b, + 0x9005c, + 0x9005d, + 0x9005e, + 0x9005f, + 0x90060, + 0x90061, + 0x90062, + 0x90063, + 0x90064, + 0x90065, + 0x90066, + 0x90067, + 0x90068, + 0x90069, + 0x9006a, + 0x9006b, + 0x9006c, + 0x9006d, + 0x9006e, + 0x9006f, + 0x90070, + 0x90071, + 0x90072, + 0x90073, + 0x90074, + 0x90075, + 0x90076, + 0x90077, + 0x90078, + 0x90079, + 0x9007a, + 0x9007b, + 0x9007c, + 0x9007d, + 0x9007e, + 0x9007f, + 0x90080, + 0x90081, + 0x90082, + 0x90083, + 0x90084, + 0x90085, + 0x90086, + 0x90087, + 0x90088, + 0x90089, + 0x9008a, + 0x9008b, + 0x9008c, + 0x9008d, + 0x9008e, + 0x9008f, + 0x90090, + 0x90091, + 0x90092, + 0x90093, + 0x90094, + 0x90095, + 0x90096, + 0x90097, + 0x90098, + 0x90099, + 0x9009a, + 0x9009b, + 0x9009c, + 0x9009d, + 0x9009e, + 0x9009f, + 0x900a0, + 0x900a1, + 0x900a2, + 0x900a3, + 0x40000, + 0x40020, + 0x40040, + 0x40060, + 0x40001, + 0x40021, + 0x40041, + 0x40061, + 0x40002, + 0x40022, + 0x40042, + 0x40062, + 0x40003, + 0x40023, + 0x40043, + 0x40063, + 0x40004, + 0x40024, + 0x40044, + 0x40064, + 0x40005, + 0x40025, + 0x40045, + 0x40065, + 0x40006, + 0x40026, + 0x40046, + 0x40066, + 0x40007, + 0x40027, + 0x40047, + 0x40067, + 0x40008, + 0x40028, + 0x40048, + 0x40068, + 0x40009, + 0x40029, + 0x40049, + 0x40069, + 0x4000a, + 0x4002a, + 0x4004a, + 0x4006a, + 0x4000b, + 0x4002b, + 0x4004b, + 0x4006b, + 0x4000c, + 0x4002c, + 0x4004c, + 0x4006c, + 0x4000d, + 0x4002d, + 0x4004d, + 0x4006d, + 0x4000e, + 0x4002e, + 0x4004e, + 0x4006e, + 0x4000f, + 0x4002f, + 0x4004f, + 0x4006f, + 0x40010, + 0x40030, + 0x40050, + 0x40070, + 0x40011, + 0x40031, + 0x40051, + 0x40071, + 0x40012, + 0x40032, + 0x40052, + 0x40072, + 0x40013, + 0x40033, + 0x40053, + 0x40073, + 0x40014, + 0x40034, + 0x40054, + 0x40074, + 0x40015, + 0x40035, + 0x40055, + 0x40075, + 0x40016, + 0x40036, + 0x40056, + 0x40076, + 0x40017, + 0x40037, + 0x40057, + 0x40077, + 0x40018, + 0x40038, + 0x40058, + 0x40078, + 0x40019, + 0x40039, + 0x40059, + 0x40079, + 0x4001a, + 0x4003a, + 0x4005a, + 0x4007a, + 0x900a4, + 0x900a5, + 0x900a6, + 0x900a7, + 0x900a8, + 0x900a9, + 0x900aa, + 0x900ab, + 0x900ac, + 0x900ad, + 0x900ae, + 0x900af, + 0x900b0, + 0x900b1, + 0x900b2, + 0x900b3, + 0x900b4, + 0x900b5, + 0x900b6, + 0x900b7, + 0x900b8, + 0x900b9, + 0x900ba, + 0x900bb, + 0x900bc, + 0x900bd, + 0x900be, + 0x900bf, + 0x900c0, + 0x900c1, + 0x900c2, + 0x900c3, + 0x900c4, + 0x900c5, + 0x900c6, + 0x900c7, + 0x900c8, + 0x900c9, + 0x900ca, + 0x900cb, + 0x900cc, + 0x900cd, + 0x900ce, + 0x900cf, + 0x900d0, + 0x900d1, + 0x900d2, + 0x900d3, + 0x900d4, + 0x900d5, + 0x900d6, + 0x900d7, + 0x900d8, + 0x900d9, + 0x900da, + 0x900db, + 0x900dc, + 0x900dd, + 0x900de, + 0x900df, + 0x900e0, + 0x900e1, + 0x900e2, + 0x900e3, + 0x900e4, + 0x900e5, + 0x900e6, + 0x900e7, + 0x900e8, + 0x900e9, + 0x900ea, + 0x900eb, + 0x900ec, + 0x900ed, + 0x900ee, + 0x900ef, + 0x900f0, + 0x900f1, + 0x900f2, + 0x900f3, + 0x900f4, + 0x900f5, + 0x900f6, + 0x900f7, + 0x900f8, + 0x900f9, + 0x900fa, + 0x900fb, + 0x900fc, + 0x900fd, + 0x900fe, + 0x900ff, + 0x90100, + 0x90101, + 0x90102, + 0x90103, + 0x90104, + 0x90105, + 0x90106, + 0x90107, + 0x90108, + 0x90109, + 0x9010a, + 0x9010b, + 0x9010c, + 0x9010d, + 0x9010e, + 0x9010f, + 0x90110, + 0x90111, + 0x90112, + 0x90113, + 0x90114, + 0x90115, + 0x90116, + 0x90117, + 0x90118, + 0x90119, + 0x9011a, + 0x9011b, + 0x9011c, + 0x9011d, + 0x9011e, + 0x9011f, + 0x90120, + 0x90121, + 0x90122, + 0x90123, + 0x90124, + 0x90125, + 0x90126, + 0x90127, + 0x90128, + 0x90129, + 0x9012a, + 0x9012b, + 0x9012c, + 0x9012d, + 0x9012e, + 0x9012f, + 0x90130, + 0x90131, + 0x90132, + 0x90133, + 0x90134, + 0x90135, + 0x90136, + 0x90137, + 0x90138, + 0x90139, + 0x9013a, + 0x9013b, + 0x9013c, + 0x9013d, + 0x9013e, + 0x9013f, + 0x90140, + 0x90141, + 0x90142, + 0x90143, + 0x90144, + 0x90145, + 0x90146, + 0x90147, + 0x90148, + 0x90149, + 0x9014a, + 0x9014b, + 0x9014c, + 0x9014d, + 0x9014e, + 0x9014f, + 0x90150, + 0x90151, + 0x90152, + 0x90153, + 0x90154, + 0x90155, + 0x90156, + 0x90157, + 0x90158, + 0x90159, + 0x9015a, + 0x9015b, + 0x9015c, + 0x9015d, + 0x9015e, + 0x9015f, + 0x90160, + 0x90161, + 0x90162, + 0x90163, + 0x90164, + 0x90165, + 0x90166, + 0x90167, + 0x90168, + 0x90169, + 0x9016a, + 0x9016b, + 0x9016c, + 0x9016d, + 0x9016e, + 0x9016f, + 0x90170, + 0x90171, + 0x90172, + 0x90173, + 0x90174, + 0x90175, + 0x90176, + 0x90177, + 0x90178, + 0x90179, + 0x9017a, + 0x9017b, + 0x9017c, + 0x9017d, + 0x9017e, + 0x9017f, + 0x90180, + 0x90181, + 0x90006, + 0x90007, + 0x90008, + 0x90009, + 0x9000a, + 0x9000b, + 0xd00e7, + 0x90017, + 0x9001f, + 0x90026, + 0x400d0, + 0x400d1, + 0x400d2, + 0x400d3, + 0x400d4, + 0x400d5, + 0x400d6, + 0x400d7, + 0x200be, + 0x2000b, + 0x2000c, + 0x2000d, + 0x2000e, + 0x9000c, + 0x9000d, + 0x9000e, + 0x9000f, + 0x90010, + 0x90011, + 0x90012, + 0x90013, + 0x20010, + 0x20011, + 0x40080, + 0x40081, + 0x40082, + 0x40083, + 0x40084, + 0x40085, + 0x400fd, + 0x10011, + 0x10012, + 0x10013, + 0x10018, + 0x10002, + 0x100b2, + 0x101b4, + 0x102b4, + 0x103b4, + 0x104b4, + 0x105b4, + 0x106b4, + 0x107b4, + 0x108b4, + 0x11011, + 0x11012, + 0x11013, + 0x11018, + 0x11002, + 0x110b2, + 0x111b4, + 0x112b4, + 0x113b4, + 0x114b4, + 0x115b4, + 0x116b4, + 0x117b4, + 0x118b4, + 0x12011, + 0x12012, + 0x12013, + 0x12018, + 0x12002, + 0x120b2, + 0x121b4, + 0x122b4, + 0x123b4, + 0x124b4, + 0x125b4, + 0x126b4, + 0x127b4, + 0x128b4, + 0x13011, + 0x13012, + 0x13013, + 0x13018, + 0x13002, + 0x130b2, + 0x131b4, + 0x132b4, + 0x133b4, + 0x134b4, + 0x135b4, + 0x136b4, + 0x137b4, + 0x138b4, + 0x20089, + 0xc0080, + 0x200cb, + 0x10068, + 0x10069, + 0x10168, + 0x10169, + 0x10268, + 0x10269, + 0x10368, + 0x10369, + 0x10468, + 0x10469, + 0x10568, + 0x10569, + 0x10668, + 0x10669, + 0x10768, + 0x10769, + 0x10868, + 0x10869, + 0x100aa, + 0x10062, + 0x10001, + 0x100a0, + 0x100a1, + 0x100a2, + 0x100a3, + 0x100a4, + 0x100a5, + 0x100a6, + 0x100a7, + 0x11068, + 0x11069, + 0x11168, + 0x11169, + 0x11268, + 0x11269, + 0x11368, + 0x11369, + 0x11468, + 0x11469, + 0x11568, + 0x11569, + 0x11668, + 0x11669, + 0x11768, + 0x11769, + 0x11868, + 0x11869, + 0x110aa, + 0x11062, + 0x11001, + 0x110a0, + 0x110a1, + 0x110a2, + 0x110a3, + 0x110a4, + 0x110a5, + 0x110a6, + 0x110a7, + 0x12068, + 0x12069, + 0x12168, + 0x12169, + 0x12268, + 0x12269, + 0x12368, + 0x12369, + 0x12468, + 0x12469, + 0x12568, + 0x12569, + 0x12668, + 0x12669, + 0x12768, + 0x12769, + 0x12868, + 0x12869, + 0x120aa, + 0x12062, + 0x12001, + 0x120a0, + 0x120a1, + 0x120a2, + 0x120a3, + 0x120a4, + 0x120a5, + 0x120a6, + 0x120a7, + 0x13068, + 0x13069, + 0x13168, + 0x13169, + 0x13268, + 0x13269, + 0x13368, + 0x13369, + 0x13468, + 0x13469, + 0x13568, + 0x13569, + 0x13668, + 0x13669, + 0x13768, + 0x13769, + 0x13868, + 0x13869, + 0x130aa, + 0x13062, + 0x13001, + 0x130a0, + 0x130a1, + 0x130a2, + 0x130a3, + 0x130a4, + 0x130a5, + 0x130a6, + 0x130a7, + 0x80, + 0x1080, + 0x2080, + 0x3080, + 0x4080, + 0x5080, + 0x10020, + 0x10080, + 0x10081, + 0x100d0, + 0x100d1, + 0x1008c, + 0x1008d, + 0x10180, + 0x10181, + 0x101d0, + 0x101d1, + 0x1018c, + 0x1018d, + 0x100c0, + 0x100c1, + 0x101c0, + 0x101c1, + 0x102c0, + 0x102c1, + 0x103c0, + 0x103c1, + 0x104c0, + 0x104c1, + 0x105c0, + 0x105c1, + 0x106c0, + 0x106c1, + 0x107c0, + 0x107c1, + 0x108c0, + 0x108c1, + 0x100ae, + 0x100af, + 0x11020, + 0x11080, + 0x11081, + 0x110d0, + 0x110d1, + 0x1108c, + 0x1108d, + 0x11180, + 0x11181, + 0x111d0, + 0x111d1, + 0x1118c, + 0x1118d, + 0x110c0, + 0x110c1, + 0x111c0, + 0x111c1, + 0x112c0, + 0x112c1, + 0x113c0, + 0x113c1, + 0x114c0, + 0x114c1, + 0x115c0, + 0x115c1, + 0x116c0, + 0x116c1, + 0x117c0, + 0x117c1, + 0x118c0, + 0x118c1, + 0x110ae, + 0x110af, + 0x12020, + 0x12080, + 0x12081, + 0x120d0, + 0x120d1, + 0x1208c, + 0x1208d, + 0x12180, + 0x12181, + 0x121d0, + 0x121d1, + 0x1218c, + 0x1218d, + 0x120c0, + 0x120c1, + 0x121c0, + 0x121c1, + 0x122c0, + 0x122c1, + 0x123c0, + 0x123c1, + 0x124c0, + 0x124c1, + 0x125c0, + 0x125c1, + 0x126c0, + 0x126c1, + 0x127c0, + 0x127c1, + 0x128c0, + 0x128c1, + 0x120ae, + 0x120af, + 0x13020, + 0x13080, + 0x13081, + 0x130d0, + 0x130d1, + 0x1308c, + 0x1308d, + 0x13180, + 0x13181, + 0x131d0, + 0x131d1, + 0x1318c, + 0x1318d, + 0x130c0, + 0x130c1, + 0x131c0, + 0x131c1, + 0x132c0, + 0x132c1, + 0x133c0, + 0x133c1, + 0x134c0, + 0x134c1, + 0x135c0, + 0x135c1, + 0x136c0, + 0x136c1, + 0x137c0, + 0x137c1, + 0x138c0, + 0x138c1, + 0x130ae, + 0x130af, + 0x90201, + 0x90202, + 0x90203, + 0x90205, + 0x90206, + 0x90207, + 0x90208, + 0x20020, + 0x20077, + 0x20072, + 0x20073, + 0x400c0, + 0x10040, + 0x10140, + 0x10240, + 0x10340, + 0x10440, + 0x10540, + 0x10640, + 0x10740, + 0x10840, + 0x11040, + 0x11140, + 0x11240, + 0x11340, + 0x11440, + 0x11540, + 0x11640, + 0x11740, + 0x11840, + 0x12040, + 0x12140, + 0x12240, + 0x12340, + 0x12440, + 0x12540, + 0x12640, + 0x12740, + 0x12840, + 0x13040, + 0x13140, + 0x13240, + 0x13340, + 0x13440, + 0x13540, + 0x13640, + 0x13740, + 0x13840, +}; + +typedef struct Reg_Addr_Val { + uint32_t Address; ///< register address + uint16_t Value0; ///< register value phy0 + uint16_t Value1; ///< register value phy1 +} Reg_Addr_Val_t; + +typedef struct Reg_Addr_Value { + uint32_t reg_num; + Reg_Addr_Val_t reg[0]; +} Reg_Addr_Value_t; + +int NumRegSaved = 934; ///< Current Number of registers saved. +#define SRAM_E902_BASEADDR 0xFFFFEF8000 +#define DDR_PHY_REG_SAVEADDR (SRAM_E902_BASEADDR + 0xDF00) +Reg_Addr_Value_t *pRetRegList = (Reg_Addr_Value_t *)DDR_PHY_REG_SAVEADDR; + +int dwc_ddrphy_phyinit_regInterface() { + ddr_phy_reg_wr(0xd0000, 0x0); + ddr_phy_reg_wr(0xc0080, 0x3); + pRetRegList->reg_num = NumRegSaved; + // go through all the tracked registers, issue a register read and place + // the result in the data structure for future recovery. + int regIndx = 0; + uint16_t data; + for (regIndx = 0; regIndx < NumRegSaved; regIndx++) + { + data = ddr_phy0_reg_rd(RetRegList_addr[regIndx]); + pRetRegList->reg[regIndx].Value0 = data; + pRetRegList->reg[regIndx].Address = RetRegList_addr[regIndx]; + } +#ifndef CONFIG_DDR_H32_MODE + for (regIndx = 0; regIndx < NumRegSaved; regIndx++) + { + data = ddr_phy1_reg_rd(RetRegList_addr[regIndx]); + pRetRegList->reg[regIndx].Value1 = data; + } +#endif + ddr_phy_reg_wr(0xc0080, 0x2); + ddr_phy_reg_wr(0xd0000, 0x1); + return 1; +} diff --git a/board/thead/light-c910/sbmeta/sbmeta.c b/board/thead/light-c910/sbmeta/sbmeta.c index 6407ec7a..047696c1 100644 --- a/board/thead/light-c910/sbmeta/sbmeta.c +++ b/board/thead/light-c910/sbmeta/sbmeta.c @@ -4,23 +4,42 @@ */ #include "sbmeta.h" +#include "sec_crypto_sha.h" + +#define LOGLEVEL_ERROR 1 +#define LOGLEVEL_INFO 2 +#define LOGLEVEL_DEBUG 3 +#define SBMETA_LOGLEVEL 1 +#define trace_printer(level, fmt,...) printf("%s"fmt, level, ##__VA_ARGS__) +#if (SBMETA_LOGLEVEL < 1) +#define EMSG(...) +#else +#define EMSG(fmt, args...) trace_printer("error: ", fmt, ##args) +#endif + +#if (SBMETA_LOGLEVEL < 2) +#define IMSG(...) +#else +#define IMSG(fmt, args...) trace_printer("info: ", fmt, ##args) +#endif -#define NO_DEBUG 0 -#if NO_DEBUG -#define print_info(fmt, args...) +#if (SBMETA_LOGLEVEL < 3) +#define DMSG(...) #else -#define print_info(fmt, args...) printf(fmt, ##args) +#define DMSG(fmt, args...) trace_printer("", 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 int digest_size[] = {0, 20, 16, 28, 32, 48, 64, 32}; static const char* image_name_s[] = { "dtb", "kernel", "tf", "aon", "rootfs", "tee", "uboot", "user" }; +/* index to get sc_sha_mode_t value */ +static const int sha_idx2ctl[] = {0, 1, 8, 3, 2, 5, 4, 9}; -static const uint32_t image_addrs[] = { +static const unsigned long image_addrs[] = { LIGHT_DTB_ADDR, LIGHT_KERNEL_ADDR, LIGHT_TF_FW_TMP_ADDR, @@ -30,13 +49,29 @@ static const uint32_t image_addrs[] = { CONFIG_SYS_TEXT_BASE, }; +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 checksum_scheme; + char filename[MAX_NAME_SIZE]; + uint8_t digest[MAX_DIGEST_SIZE]; + uint32_t relocated_addr; + uint32_t reserved[4]; +} sbmeta_info_t; + static int is_sbmeta_info(uint32_t entry_src_addr) { - uint32_t *buffer = (uint32_t *)entry_src_addr; + uint32_t *buffer = (uint32_t *)(uintptr_t)entry_src_addr; /* sbmeta_info_t entry should start with magic code 'S''B''M''T' */ if (*buffer != SBMETA_MAGIC) { - return -1; + return CMD_RET_FAILURE; } return 0; @@ -47,113 +82,211 @@ 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"); + EMSG("medium type %d is not supported now\r\n", sbmeta_info->medium_type); 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"); + EMSG("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"); + EMSG("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"); + EMSG("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"); + IMSG("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:"); + DMSG("image medium type: %d\n", sbmeta_info->medium_type); + DMSG("image load part: mmc %d:%d\n", sbmeta_info->dev, sbmeta_info->part); + DMSG("image type: %d \n", sbmeta_info->image_type); + DMSG("image digest scheme: %d\n", sbmeta_info->digest_scheme); + DMSG("image sign scheme: %d\n", sbmeta_info->sign_scheme); + DMSG("image enable encryption: %s\n", sbmeta_info->isencrypted ? "en" : "dis"); + DMSG("image file name: %s\n", sbmeta_info->filename); + DMSG("image digest:"); for (int i = 0; i < digest_size[sbmeta_info->digest_scheme]; i++) { - print_info("%02X", sbmeta_info->digest[i]); + DMSG("%02X", sbmeta_info->digest[i]); } - print_info("\r\n"); - + DMSG("\r\n"); + DMSG("\n\n"); + return 0; } +static int sbmeta_field_verify(sbmeta_info_t *sbmeta_info, unsigned long img_src_addr) +{ + uint8_t digest_scheme = 0; + uint8_t sign_scheme = 0; + uint8_t is_encrypted = 0; + img_header_t *phead = NULL; + + if (sbmeta_info == NULL) { + return CMD_RET_FAILURE; + } + + /* if image has secure header, check with sbmeta field */ + if (image_have_head(img_src_addr)) { + phead = (img_header_t *)img_src_addr; + digest_scheme = phead->digest_scheme; + sign_scheme = phead->signature_scheme; + is_encrypted = (phead->option_flag & 0x2) >> 1; + } + + if (sbmeta_info->digest_scheme != digest_scheme) { + EMSG("digest type %d is not expected: %d\r\n", digest_scheme, sbmeta_info->digest_scheme); + return CMD_RET_FAILURE; + } + + /* only support none, rsa1024, rsa2048, ecc256, ecc160, sm2 and reserved scheme */ + if (sbmeta_info->sign_scheme != sign_scheme) { + EMSG("signature type %d is not expected: %d\r\n", sign_scheme, sbmeta_info->sign_scheme); + return CMD_RET_FAILURE; + } + + if (sbmeta_info->isencrypted != is_encrypted) { + EMSG("encryption %d is not expected: %d\r\n", is_encrypted, sbmeta_info->isencrypted); + return CMD_RET_FAILURE; + } + + return 0; +} + +static int check_digest(uint8_t *buffer, uint32_t buffer_size, uint8_t digest_scheme, uint8_t *digest) +{ + uint32_t len = 0; + uint8_t sum[64]; + sc_sha_t sha; + sc_sha_context_t ctx; + int mode = 0; + + if (!buffer || digest_scheme > DIGEST_TYPE_NUM) { + EMSG("wrong parameter\r\n"); + return CMD_RET_FAILURE; + } + + if (digest_scheme == 0) { + return 0; + } + mode = sha_idx2ctl[digest_scheme]; + + if (sc_sha_init(&sha, 0) != 0) { + EMSG("sha initialize failed\r\n"); + return CMD_RET_FAILURE; + } + + if (sc_sha_start(&sha, &ctx, mode) != 0) { + EMSG("sha start failed\r\n"); + return CMD_RET_FAILURE; + } + + if (sc_sha_update(&sha, &ctx, buffer, buffer_size) != 0) { + EMSG("sha update failed\r\n"); + return CMD_RET_FAILURE; + } + + if (sc_sha_finish(&sha, &ctx, sum, &len) != 0) { + EMSG("sha finish failed\r\n"); + return CMD_RET_FAILURE; + } + + sc_sha_uninit(&sha); + + /* check digest value */ + if (memcmp(digest, sum, len) != 0) { + EMSG("check digest failed\r\n"); + return CMD_RET_FAILURE; + } + + 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) +static int sbmeta_verify_image(uint32_t image_load_addr, sbmeta_info_t *sbmeta_info) { uint32_t image_size = 0; - char *image_name = NULL; - + const char *image_name; + uint8_t image_type = sbmeta_info->image_type; + uint8_t checksum_scheme = sbmeta_info->checksum_scheme; + uint8_t *digest = sbmeta_info->digest; + uint8_t is_encrypted = sbmeta_info->isencrypted; + uint32_t security_level = env_get_hex("sbmeta_security_level", 3); + uint32_t filesize = 0; + char buf[64] = {0}; + /* 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"); + EMSG("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 */ + /* check tee/tf version if needed */ #ifdef LIGHT_IMG_VERSION_CHECK_IN_BOOT + if (image_have_head(image_load_addr) == 1) { if (image_type == T_TF) { - print_info("check TF version in boot \n"); + IMSG("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"); + IMSG("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; - } + /* start verifying images */ + IMSG("Process %s image verification ...\n", image_name); + if (security_level == 3 || is_encrypted != 0) { + if (verify_customer_image(image_type, image_load_addr) != 0) { + return CMD_RET_FAILURE; + } + } else if (security_level == 2) { + if (memcmp(digest, buf, 64) == 0) { + EMSG("sbmeta info doesn't specify digest value in security level 2\r\n"); + return CMD_RET_FAILURE; } - + + snprintf(buf, sizeof(buf), "ext4size mmc %x:%x %s", sbmeta_info->dev, sbmeta_info->part, sbmeta_info->filename); + if (run_command(buf, 0) != 0) { + EMSG("get file size error\r\n"); + return CMD_RET_FAILURE; + } + + filesize = env_get_hex("filesize", 0); + if (check_digest((uint8_t *)(uintptr_t)image_load_addr, filesize, checksum_scheme, digest) != 0) { + return CMD_RET_FAILURE; + } + } + + /* move image headers always */ + if (image_have_head(image_load_addr) == 1) { image_size = get_image_size(image_load_addr); - print_info("%s image size: %d\n", image_name, image_size); + IMSG("%s image size: %d\n", image_name, image_size); if (image_size < 0) { - print_info("GET %s image size error\n", image_name); + EMSG("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); + memmove((void *)(uintptr_t)LIGHT_TF_FW_ADDR, (const void *)(uintptr_t)(image_load_addr + HEADER_SIZE), image_size); } else { - memmove((void *)image_load_addr, (const void *)(image_load_addr + HEADER_SIZE), image_size); + memmove((void *)(uintptr_t)image_load_addr, (const void *)(uintptr_t)(image_load_addr + HEADER_SIZE), image_size); } } else { /* TF should be moved to LIGHT_TF_FW_ADDR all the cases*/ @@ -173,14 +306,13 @@ static int light_sbmetaboot(int argc, char *const argv[]) 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); + snprintf(cmd, sizeof(cmd), "ext4load mmc $mmcdev:%x 0x%p %s", SBMETA_PART, (void *)(uintptr_t)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"); + IMSG("SBMETA doesn't exist, go to verify tf/tee\r\n"); /* * Verify tf and tee by command secboot. @@ -200,24 +332,29 @@ static int light_sbmetaboot(int argc, char *const argv[]) /* 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"); +#ifdef LIGHT_IMG_VERSION_CHECK_IN_BOOT + IMSG("check SBMETA version in boot \n"); + ret = check_sbmeta_version_in_boot(LIGHT_SBMETA_ADDR); + if (ret != 0) { + return CMD_RET_FAILURE; + } +#endif + IMSG("Process SBMETA image verification...\r\n"); + if (verify_customer_image(T_SBMETA, LIGHT_SBMETA_ADDR) != 0) { return CMD_RET_FAILURE; } sbmeta_size = get_image_size(LIGHT_SBMETA_ADDR); - print_info("sbmeta_size:%d\r\n", sbmeta_size); + IMSG("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); + EMSG("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"); + IMSG("SBMETA image must be with signature\r\n"); return CMD_RET_FAILURE; } @@ -226,12 +363,11 @@ static int light_sbmetaboot(int argc, char *const argv[]) 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; + sbmeta_info = (sbmeta_info_t *)(uintptr_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; /* @@ -251,14 +387,18 @@ static int light_sbmetaboot(int argc, char *const argv[]) 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); + (void *)(uintptr_t)image_load_addr, sbmeta_info->filename); if (run_command(cmd, 0) != 0) { return CMD_RET_FAILURE; } } + if (sbmeta_field_verify(sbmeta_info, image_load_addr) != 0) { + return CMD_RET_FAILURE; + } + /* Check and verify user-specified image */ - if (sbmeta_verify_image(image_load_addr, sbmeta_info->image_type) != 0) { + if (sbmeta_verify_image(image_load_addr, sbmeta_info) != 0) { return CMD_RET_FAILURE; } } else { @@ -268,7 +408,7 @@ static int light_sbmetaboot(int argc, char *const argv[]) /* if sbmeta didn't specify images, reset */ if (count == 0) { - print_info("Error: SBMETA doesn't specify any images!\r\n"); + EMSG("SBMETA doesn't specify any images!\r\n"); return CMD_RET_FAILURE; } @@ -280,10 +420,10 @@ static int light_sbmetaboot(int argc, char *const argv[]) 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; + EMSG("sbmetaboot failed\r\n"); + while (1); + return CMD_RET_FAILURE; } - return 0; } diff --git a/board/thead/light-c910/sbmeta/sbmeta.h b/board/thead/light-c910/sbmeta/sbmeta.h index 4955d758..5a721b80 100644 --- a/board/thead/light-c910/sbmeta/sbmeta.h +++ b/board/thead/light-c910/sbmeta/sbmeta.h @@ -17,8 +17,7 @@ #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 SBMETA_PART 5 #define ENTRY_SIZE 128 #define PLAIN_SBMETA_TEXT 4096 #define SBMETA_SIZE 4736 /* 4K SMBETA image + 640 footer */ @@ -26,23 +25,10 @@ #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; +#define SBMETA_SECURITY_LEVEL_H 3 /* verify signature and hash */ +#define SBMETA_SECURITY_LEVEL_M 2 /* verify checksum */ +#define SBMETA_SECURITY_LEVEL_L 1 /* no verification */ #endif diff --git a/board/thead/light-c910/sec_check.c b/board/thead/light-c910/sec_check.c index af44ec9b..847e9ef5 100644 --- a/board/thead/light-c910/sec_check.c +++ b/board/thead/light-c910/sec_check.c @@ -130,16 +130,18 @@ void dump_image_header_info(long addr) int verify_customer_image(img_type_t type, long addr) { int ret; - + /* Double check image number */ - if (image_have_head(addr) == 0) + if (image_have_head(addr) == 0) { + printf("error: image has no secure header\r\n"); return -1; + } /* Dump image header information here */ dump_image_header_info(addr); /* Call customer image verification function */ - if ((type == T_TF) || (type == T_TEE) || (type == T_KRLIMG)) { + if ((type == T_TF) || (type == T_TEE) || (type == T_KRLIMG) || (type == T_DTB) || (type == T_SBMETA)) { ret = csi_sec_custom_image_verify(addr, UBOOT_STAGE_ADDR); if (ret) { printf("Image(%d) is verified fail, Please go to check!\n\n", type); diff --git a/board/thead/light-c910/secimg_load.c b/board/thead/light-c910/secimg_load.c index 49b8262d..9120eff4 100644 --- a/board/thead/light-c910/secimg_load.c +++ b/board/thead/light-c910/secimg_load.c @@ -10,7 +10,7 @@ #include "sec_library.h" #define ENV_SECIMG_LOAD "sec_m_load" -#define VAL_SECIMG_LOAD "ext4load mmc 0:7 $tf_addr trust_firmware.bin; ext4load mmc 0:7 $tee_addr tee.bin" +#define VAL_SECIMG_LOAD "ext4load mmc ${mmcdev}:${mmcteepart} $tf_addr trust_firmware.bin; ext4load mmc ${mmcdev}:${mmcteepart} $tee_addr tee.bin\0" #define RPMB_BLOCK_SIZE 256 #define RPMB_ROLLBACK_BLOCK_START 1 @@ -23,14 +23,15 @@ static const unsigned char emmc_rpmb_key_sample[32] = {0x33, 0x22, 0x11, 0x00, 0 #endif extern int sprintf(char *buf, const char *fmt, ...); +extern char * get_slot_name_suffix(void); static int get_rpmb_key(uint8_t key[32]) { -#ifndef LIGHT_KDF_RPMB_KEY +#ifndef LIGHT_KDF_RPMB_KEY memcpy(key, emmc_rpmb_key_sample, sizeof(emmc_rpmb_key_sample)); return 0; -#else +#else uint32_t kdf_rpmb_key_length = 0; int ret = 0; ret = csi_kdf_gen_hmac_key(key, &kdf_rpmb_key_length); @@ -46,7 +47,7 @@ static int get_image_file_size(unsigned long img_src_addr) { img_header_t *img = (img_header_t *)img_src_addr; uint8_t magiccode[4] = {0}; - + magiccode[3] = img->magic_num & 0xff; magiccode[2] = (img->magic_num & 0xff00) >> 8; magiccode[1] = (img->magic_num & 0xff0000) >> 16; @@ -54,7 +55,7 @@ static int get_image_file_size(unsigned long img_src_addr) if (memcmp(header_magic, magiccode, 4) == 0) { return -1; } - + return img->image_size; } @@ -68,13 +69,13 @@ static int verify_and_load_image(unsigned long image_addr_src, unsigned long ima if (ret != 0) { return -1; } - + ret = csi_sec_custom_image_verify(image_addr_src, UBOOT_STAGE_ADDR); if (ret != 0) { printf("image verify error\r\n"); return -2; } - + image_size = get_image_file_size(image_addr_src); if (image_size < 0) { printf("image get size error\r\n"); @@ -112,15 +113,23 @@ int verify_and_load_tee_tf_image(void) } /* In order to use common bootloader for both secure boot and non-secure boot, - we only know the boot type through reading the sec_boot field in efuse. Due to - the efuse is only accessed in lifecycle(DEV/OEM/PRO/RMP), we ensure it must be + we only know the boot type through reading the sec_boot field in efuse. Due to + the efuse is only accessed in lifecycle(DEV/OEM/PRO/RMP), we ensure it must be non-secure boot in lifecycle(INIT) */ bool get_system_boot_type(void) { - bool btype = false; /* false: non-secure boot | true: secure boot */ + bool btype = true; /* false: non-secure boot | true: secure boot */ +#if 0 int lc = 0; sboot_st_t sb_flag = SECURE_BOOT_DIS; int ret = 0; +#endif + int sb_emulater = 0; + + sb_emulater = env_get_ulong("sb_emulater", 10, 0); + if (sb_emulater == 0) { + btype = false; + } # if 0 ret = csi_efuse_get_lc(&lc); /* 0: LC_INIT, 1: LC_DEV, 2: LC_OEM, 3: LC_PRO */ @@ -170,7 +179,7 @@ int sec_write_rollback_index(size_t rollback_index_slot, uint64_t rollback_index } *(uint64_t*)(blkdata + rpmb_offset) = rollback_index; - + if (get_rpmb_key(rpmb_key) != 0) { return -2; } @@ -189,19 +198,37 @@ static int do_secimg_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg bool sb_enable = false; const char *secimgs_load_str = VAL_SECIMG_LOAD; int ret = -1; - sb_enable = get_system_boot_type(); - if (sb_enable) { - /* By default, the value for ENV-SEC-M-LOAD is always to load opensbi image. - * if secure boot is enable, we force to change the value to load tee image. - * but Never to save it in volatile-RAM - */ - ret = env_set(ENV_SECIMG_LOAD, secimgs_load_str); - if (ret != 0) { - printf("Rewrite ENV (%s) fails\n", ENV_SECIMG_LOAD); - return CMD_RET_FAILURE; - } - } - + int teepart = 0; + +#ifdef CONFIG_ANDROID_AB + char *slot_suffix = get_slot_name_suffix(); + teepart = env_get_ulong("mmcteepart", 10, 8); + if ((strcmp(slot_suffix, "_a") == 0) && (teepart != 8)) { + /* Switch mmcbootpart to "_b" */ + env_set_ulong("mmcbootpart", 2); + /* Switch mmcteepart to "_b" */ + env_set_ulong("mmcteepart", 8); + } else if ((strcmp(slot_suffix, "_b") == 0) && (teepart != 9)){ + /* Switch mmcbootpart to "_b" */ + env_set_ulong("mmcbootpart", 3); + /* Switch mmcteepart to "_b" */ + env_set_ulong("mmcteepart", 9); + } +#endif + + sb_enable = get_system_boot_type(); + if (sb_enable) { + /* By default, the value for ENV-SEC-M-LOAD is always to load opensbi image. + * if secure boot is enable, we force to change the value to load tee image. + * but Never to save it in volatile-RAM + */ + ret = env_set(ENV_SECIMG_LOAD, secimgs_load_str); + if (ret != 0) { + printf("Rewrite ENV (%s) fails\n", ENV_SECIMG_LOAD); + return CMD_RET_FAILURE; + } + } + return CMD_RET_SUCCESS; } diff --git a/board/thead/light-c910/spl.c b/board/thead/light-c910/spl.c index 530c8cbf..6b560cc5 100644 --- a/board/thead/light-c910/spl.c +++ b/board/thead/light-c910/spl.c @@ -302,10 +302,12 @@ void cpu_performance_enable(void) #define CSR_MHINT2_E 0x7cc #define CSR_MHINT4 0x7ce csr_write(CSR_SMPEN, 0x1); - csr_write(CSR_MHINT2_E, csr_read(CSR_MHINT2_E) | 0x20000); + // FIXME set mhint2[22] to enable core icg en + csr_write(CSR_MHINT2_E, csr_read(CSR_MHINT2_E) | 0x420000); csr_write(CSR_MHINT4, csr_read(CSR_MHINT4) | 0x410); csr_write(CSR_MCCR2, 0xe2490009); - csr_write(CSR_MHCR, 0x117f); // clear bit7 to disable indirect branch prediction + // FIXME: Clear bit[12] to disable L0BTB. + csr_write(CSR_MHCR, 0x17f); // clear bit7 to disable indirect brantch prediction csr_write(CSR_MXSTATUS, 0x638000); csr_write(CSR_MHINT, 0x6e30c | (1<<21) | (1<<22)); // set bit21 & bit 22 to close tlb & fence broadcast } diff --git a/cmd/bootandroid.c b/cmd/bootandroid.c index fbd43546..923d1669 100644 --- a/cmd/bootandroid.c +++ b/cmd/bootandroid.c @@ -1,4 +1,3 @@ - /* * (C) Copyright 2018, Linaro Limited * @@ -33,14 +32,14 @@ /* - * Knowing secure boot is enable or disable dependents on + * Knowing secure boot is enable or disable dependents on * special data field in efuse and efuse control register. */ extern bool get_system_boot_type(void); /* * The suffix for partition name is from the value of ENV_BOOTAB */ -static const char *slot_name_suffix = NULL;; +static const char *slot_name_suffix = NULL; /* * BOOT IMAGE HEADER V3/V4 PAGESIZE @@ -99,7 +98,7 @@ static int get_number_of_pages(int image_size, int page_size) * and append bootconfig to the end of ramdisk(initrd) * doc:https://www.kernel.org/doc/html/next/translations/zh_CN/admin-guide/bootconfig.html#initrd */ -static int prepare_data_from_vendor_boot(struct andr_img_hdr *hdr, int dtb_start, uint8_t** buf_bootconfig, int* vendor_bootconfig_size) +static int prepare_data_from_vendor_boot(struct andr_img_hdr *hdr, int dtb_start, uint8_t** buf_bootconfig, int* vendor_bootconfig_size, bool isRecovery) { int ret; disk_partition_t part_info; @@ -133,7 +132,15 @@ static int prepare_data_from_vendor_boot(struct andr_img_hdr *hdr, int dtb_start if (part_info.size * part_info.blksz > CONFIG_FASTBOOT_BUF_SIZE) { return -1; } - vendor_boot_data = (uint8_t*)CONFIG_FASTBOOT_BUF_ADDR; + //vendor_boot_data = (uint8_t*)CONFIG_FASTBOOT_BUF_ADDR; + + printf("vendor_boot_data part_info.size = %ld, part_info.blksz = %lu", part_info.size, part_info.blksz); + // reuse kernel start address to load vendor boot data + // because av_malloc(32M) failed in 2G devices + // TODO: why av_malloc failed + // ATTATION: If the vendor_boot partition size > boot partition size, it is error. + // avb_malloc(part_info.size * part_info.blksz); + vendor_boot_data = (uint8_t*)env_get_hex(ENV_KERNEL_ADDR, DEFAULT_KERNEL_ADDR); ret = blk_dread(dev_desc, part_info.start, part_info.size, vendor_boot_data); // vendor_boot.img @@ -216,10 +223,44 @@ static int prepare_data_from_vendor_boot(struct andr_img_hdr *hdr, int dtb_start } #endif + if (isRecovery) { + int i = 0; + struct vendor_ramdisk_table_entry *ramdisk_entry = NULL; + int vendor_ramdisk_table_offset = vendor_boot_pagesize * (o + p + q); + int vendor_ramdisk_table_entry_num = byteToInt(vendor_boot_data,2116);//offset 2116 + printf("vendor_boot vendor_ramdisk_table_entry_num:%d\n",vendor_ramdisk_table_entry_num); + int vendor_ramdisk_table_entry_size = byteToInt(vendor_boot_data,2120);//offset 2116 + printf("vendor_boot vendor_ramdisk_table_entry_size:%d\n",vendor_ramdisk_table_entry_size); + for (i = 0; i < vendor_ramdisk_table_entry_num; i++) { + ramdisk_entry = (struct vendor_ramdisk_table_entry*)(vendor_boot_data + vendor_ramdisk_table_offset + + ( i * vendor_ramdisk_table_entry_size )); + if (ramdisk_entry->ramdisk_type != VENDOR_RAMDISK_TYPE_RECOVERY) { + continue; + } + printf("find recovery from ramdisk table."); + int ramdisk_start = env_get_hex(ENV_RAMDISK_ADDR, DEFAULT_RAMDISK_ADDR); + int recovery_ramdisk_offset = vendor_boot_pagesize * o + ramdisk_entry->ramdisk_offset; + memcpy((void *)(uint64_t)ramdisk_start, vendor_boot_data + recovery_ramdisk_offset, + ramdisk_entry->ramdisk_size);//ramdisk + //get bootconfig form vendor_boot.img and append bootconfig to ramdisk + char* bootconfig_params = (char*)*buf_bootconfig; + int ret = addBootConfigParameters(bootconfig_params, *vendor_bootconfig_size, + ramdisk_start + ramdisk_entry->ramdisk_size , 0); + if (ret == -1) { + printf("\nadd BootConfig Parameters error!!!\n"); + } else { + printf("\nramdisk size is changed,new value is:%d\n",ramdisk_entry->ramdisk_size + ret); + //set ramdisk size for bootm + env_set_hex(ENV_RAMDISK_SIZE, ramdisk_entry->ramdisk_size + ret); + } + break; + } + } + return 0; } -static void prepare_loaded_parttion_data(const uint8_t* data) +static void prepare_loaded_parttion_data(const uint8_t* data, bool isRecovery) { struct andr_img_hdr *hdr = (struct andr_img_hdr *)map_sysmem((phys_addr_t)data, 0); @@ -234,7 +275,7 @@ static void prepare_loaded_parttion_data(const uint8_t* data) hdr->kernel_size = byteToInt((uint8_t *)data, 8); hdr->ramdisk_size = byteToInt((uint8_t *)data, 12); hdr->page_size = BOOT_IMAGE_HEADER_V3_PAGESIZE; - prepare_data_from_vendor_boot(hdr,dtb_start,&buf_bootconfig,&size_bootconfig); + prepare_data_from_vendor_boot(hdr,dtb_start,&buf_bootconfig,&size_bootconfig,isRecovery); } int kernel_start = env_get_hex(ENV_KERNEL_ADDR, DEFAULT_KERNEL_ADDR); @@ -257,12 +298,15 @@ static void prepare_loaded_parttion_data(const uint8_t* data) printf("boot.img kernel space and ramdis space are overlaped !!!\n"); } else { memcpy((void *)(uint64_t)kernel_start, data + kernel_offset, hdr->kernel_size); - memcpy((void *)(uint64_t)ramdisk_start, data + ramdisk_offset, hdr->ramdisk_size); + if (!isRecovery) { + memcpy((void *)(uint64_t)ramdisk_start, data + ramdisk_offset, hdr->ramdisk_size); + } + if( hdr->header_version < 3) { //set ramdisk size for bootm env_set_hex(ENV_RAMDISK_SIZE, hdr->ramdisk_size); memcpy((void *)(uint64_t)dtb_start, data + dtb_offset, hdr->dtb_size); - } else { + } else if (!isRecovery) { //get bootconfig form vendor_boot.img and append bootconfig to ramdisk char* bootconfig_params=(char*)buf_bootconfig; int ret = addBootConfigParameters(bootconfig_params, size_bootconfig, @@ -283,7 +327,7 @@ static void prepare_loaded_parttion_data(const uint8_t* data) unmap_sysmem(hdr); } -static int prepare_boot_data(const AvbSlotVerifyData *out_data) +static int prepare_boot_data(const AvbSlotVerifyData *out_data, bool isRecovery) { int res = CMD_RET_FAILURE; int i = 0; @@ -296,13 +340,13 @@ static int prepare_boot_data(const AvbSlotVerifyData *out_data) if (loaded_partition->partition_name != NULL) { printf("partition_name=%s, data_size=%ld\n", \ loaded_partition->partition_name, loaded_partition->data_size); - prepare_loaded_parttion_data(loaded_partition->data); + prepare_loaded_parttion_data(loaded_partition->data, isRecovery); } } return res; } -static void prepare_partition_data(const char *name) +static void prepare_partition_data(const char *name, bool isRecovery) { int ret = 0; disk_partition_t part_info; @@ -328,7 +372,7 @@ static void prepare_partition_data(const char *name) } ret = blk_dread(dev_desc, part_info.start, part_info.size, data); - prepare_loaded_parttion_data(data); + prepare_loaded_parttion_data(data, isRecovery); printf("prepare_partition_data %s, read=%d, start:%lx, size:%ld, blksize:%lx\n", \ name, ret, part_info.start, part_info.size, part_info.blksz); @@ -360,12 +404,18 @@ static void clear_bcb(void) printf("BootAndriod bcb info :clear_bcb write=%d, %ld,%ld,%ld\n", ret, part_info.start, part_info.size, part_info.blksz); } -static int do_andriod_bcb_business(void) +static int do_andriod_bcb_business(int *boot_recovery) { AvbIOResult ret = AVB_IO_RESULT_OK; size_t bytes_read = 0; int res = CMD_RET_FAILURE; +#ifdef CONFIG_ANDROID_AB + char *slot_suffix = "_a"; +#else + char *slot_suffix = ""; +#endif + if (avb_ops != NULL) { avb_ops_free(avb_ops); avb_ops = NULL; @@ -410,13 +460,18 @@ static int do_andriod_bcb_business(void) } /* Enter into fastboot mode if bcb string is bootonce or bootrecovery */ - if (0 == strncmp(s_bcb->message.command, BCB_BOOTONCE, strlen(BCB_BOOTONCE))|| \ - 0 == strncmp(s_bcb->message.command, BCB_BOOTRECOVERY, strlen(BCB_BOOTRECOVERY))) { + if (0 == strncmp(s_bcb->message.command, "bootonce-bootloader", strlen("bootonce-bootloader"))) + { printf("BootAndriod Info: Bcb read %ld bytes, %s\n", bytes_read, s_bcb->message.command); printf("BootAndriod Info: Enter fastboot mode\n"); clear_bcb(); run_command("fastboot usb 0", 0); } + else if (0 == strncmp(s_bcb->message.command, "boot-recovery", strlen("boot-recovery"))) + { + printf("recovery slot_suffix = %s\n", slot_suffix); + *boot_recovery = 1; + } memset(boot_ctl, 0, sizeof(struct bootloader_control)); memcpy(boot_ctl, (struct bootloader_control*)s_bcb->slot_suffix, sizeof(struct bootloader_control)); @@ -455,8 +510,9 @@ static int do_bootandroid(struct cmd_tbl_s *cmdtp, int flag, int argc, AvbHashtreeErrorMode htflags = AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE; int res = CMD_RET_FAILURE; char bp_name[32] = {0}; + int boot_recovery = 0; - res = do_andriod_bcb_business(); + res = do_andriod_bcb_business(&boot_recovery); if (res != CMD_RET_SUCCESS) { goto exit; } @@ -477,7 +533,7 @@ static int do_bootandroid(struct cmd_tbl_s *cmdtp, int flag, int argc, if (slot_result == AVB_SLOT_VERIFY_RESULT_OK) { printf("BootAndriod Info: Request Partition are verified successfully\n"); printf("BootAndriod cmdline: slot_data.cmdline:%s\n", slot_data->cmdline); - prepare_boot_data(slot_data); + prepare_boot_data(slot_data, boot_recovery ? true:false); if (ret == 0) { if (slot_data != NULL) avb_slot_verify_data_free(slot_data); @@ -487,15 +543,20 @@ static int do_bootandroid(struct cmd_tbl_s *cmdtp, int flag, int argc, run_command("reset", 0); } } else { - /* Go to load BOOT partition directly in non-secure boot */ + /* Go to load BOOT partition directly in non-secure boot */ get_partition_name(BOOT_PARTITION, bp_name); - prepare_partition_data(bp_name); + prepare_partition_data(bp_name, boot_recovery ? true:false); } - + exit: return res; } +const char * get_slot_name_suffix(void) +{ + return slot_name_suffix; +} + U_BOOT_CMD( bootandroid, 2, 1, do_bootandroid, "bootandroid - boot android bootimg from device\n", diff --git a/cmd/booti.c b/cmd/booti.c index 35febee1..594e535a 100644 --- a/cmd/booti.c +++ b/cmd/booti.c @@ -67,7 +67,6 @@ static int booti_start(cmd_tbl_t *cmdtp, int flag, int argc, int do_booti(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int ret; - /* Consume 'booti' */ argc--; argv++; @@ -127,15 +126,14 @@ int do_secboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #if CONFIG_IS_ENABLED(LIGHT_SEC_UPGRADE) if (light_secboot(argc, argv) != 0) { - run_command("reset", 0); return -1; } #endif return 0; } U_BOOT_CMD( - secboot, CONFIG_SYS_MAXARGS, 1, do_secboot, - "verify image file with known pubkey which reside in father image or itself!", + secboot, CONFIG_SYS_MAXARGS, 1, do_secboot, + "verify image file with known pubkey which reside in father image or itself!", "vimage addr imgname[[tee/tf] - verify specifed image resides in addr\n" ); diff --git a/common/Kconfig b/common/Kconfig index a7c5ba27..4e40692c 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -962,6 +962,20 @@ config TPL_HASH and the algorithms it supports are defined in common/hash.c. See also CMD_HASH for command-line access. +config BOARD_RNG_SEED + bool "Provide /chosen/rng-seed property to the linux kernel" + help + Selecting this option requires the board to define a + board_rng_seed() function, which should return a buffer + which will be used to populate the /chosen/rng-seed property + in the device tree for the OS being booted. + + It is up to the board code (and more generally the whole + BSP) where and how to store (or generate) such a seed, how + to ensure a given seed is only used once, how to create a + new seed for use on subsequent boots, and whether or not the + kernel should account any entropy from the given seed. + endmenu menu "Update support" diff --git a/common/fdt_support.c b/common/fdt_support.c index a334e008..f1f2d1ea 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -7,6 +7,7 @@ */ #include <common.h> +#include <abuf.h> #include <env.h> #include <mapmem.h> #include <stdio_dev.h> @@ -274,6 +275,7 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end) int fdt_chosen(void *fdt) { + struct abuf buf = {}; int nodeoffset; int err; char *str; /* used to set string properties */ @@ -289,6 +291,17 @@ int fdt_chosen(void *fdt) if (nodeoffset < 0) return nodeoffset; + if (IS_ENABLED(CONFIG_BOARD_RNG_SEED) && !board_rng_seed(&buf)) { + err = fdt_setprop(fdt, nodeoffset, "rng-seed", + abuf_data(&buf), abuf_size(&buf)); + abuf_uninit(&buf); + if (err < 0) { + printf("WARNING: could not set rng-seed %s.\n", + fdt_strerror(err)); + return err; + } + } + str = env_get("bootargs"); if (str) { err = fdt_setprop(fdt, nodeoffset, "bootargs", str, diff --git a/configs/light_a_val_android_defconfig b/configs/light_a_val_android_defconfig index 4ac4bedb..7e3098ef 100644 --- a/configs/light_a_val_android_defconfig +++ b/configs/light_a_val_android_defconfig @@ -103,9 +103,9 @@ CONFIG_DDR_REGU_0V8=800000 CONFIG_DDR_REGU_1V1=1100000 CONFIG_SPL_TEXT_BASE=0xffe0000800 CONFIG_LIGHT_ANDROID_BOOT_IMAGE_VAL_A=y -# CONFIG_AVB_USE_OEM_KEY is not set +CONFIG_AVB_USE_OEM_KEY=y # CONFIG_AVB_ROLLBACK_ENABLE is not set -# CONFIG_AVB_HW_ENGINE_ENABLE is not set +CONFIG_AVB_HW_ENGINE_ENABLE=y CONFIG_ANDROID_BOOT_IMAGE=y CONFIG_LIBAVB=y CONFIG_AVB_VERIFY=y @@ -114,3 +114,4 @@ CONFIG_CMD_BOOTANDROID=y CONFIG_ANDROID_AB=y CONFIG_CMD_AB_SELECT=y CONFIG_XBC=y +CONFIG_BOARD_RNG_SEED=y diff --git a/configs/light_a_val_sec_defconfig b/configs/light_a_val_sec_defconfig index d3af2ada..08372c5a 100644 --- a/configs/light_a_val_sec_defconfig +++ b/configs/light_a_val_sec_defconfig @@ -18,6 +18,12 @@ CONFIG_SYS_PROMPT="C910 Light# " CONFIG_DDR_LP4X_3733_SINGLERANK=y # CONFIG_DDR_LP4_3733_DUALRANK is not set CONFIG_DDR_BOARD_CONFIG=y +# CONFIG_TPM is not set +# CONFIG_TPM_Z32H330TC_SPI is not set +# CONFIG_TPM_V2 is not set +# CONFIG_CMD_TPM_V2 is not set +# CONFIG_CMD_TPM is not set +# CONFIG_CMD_TPM_TEST is not set CONFIG_CMD_BOOT_SLAVE=y CONFIG_CMD_ERASEENV=y CONFIG_CMD_GPT=y diff --git a/configs/light_ant_ref_android_defconfig b/configs/light_ant_ref_android_defconfig new file mode 100644 index 00000000..3af11f1d --- /dev/null +++ b/configs/light_ant_ref_android_defconfig @@ -0,0 +1,119 @@ +CONFIG_RISCV=y +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_ENV_SIZE=0x20000 +CONFIG_ENV_OFFSET=0xe0000 +CONFIG_NR_DRAM_BANKS=8 +CONFIG_SPL=y +CONFIG_SMP=y +CONFIG_TARGET_LIGHT_C910=y +CONFIG_TARGET_LIGHT_FM_C910_VAL_ANT_REF=y +CONFIG_ARCH_RV64I=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_BUILD_TARGET="u-boot-with-spl.bin" +CONFIG_DISPLAY_CPUINFO=y +CONFIG_DISPLAY_BOARDINFO=y +# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set +CONFIG_SPL_RAM_SUPPORT=y +CONFIG_SPL_RAM_DEVICE=y +CONFIG_SYS_PROMPT="C910 Light# " +CONFIG_DDR_LP4X_3200_SINGLERANK=y +CONFIG_DDR_H32_MODE=y +# CONFIG_DDR_LP4_3733_DUALRANK is not set +CONFIG_DDR_BOARD_CONFIG=y +CONFIG_CMD_BOOT_SLAVE=y +CONFIG_CMD_ERASEENV=y +CONFIG_CMD_GPT=y +CONFIG_CMD_MTD=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_SPI=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MEMTEST=y +CONFIG_DDR_SCAN=y +CONFIG_DDR_PRBS_TEST=n +# CONFIG_DOS_PARTITION is not set +# CONFIG_ISO_PARTITION is not set +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_OF_EMBED=y +CONFIG_DEFAULT_DEVICE_TREE="light-ant-ref" +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_SPL_CLK=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_UDP_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x10000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_FASTBOOT_CMD_OEM_FORMAT=y +CONFIG_DM_GPIO=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_DW=y +CONFIG_DWAPB_GPIO=y +# CONFIG_MMC_SPI is not set +CONFIG_MMC_VERBOSE=y +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_MMC_IO_VOLTAGE=y +CONFIG_MMC_UHS_SUPPORT=y +CONFIG_MMC_HS400_SUPPORT=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_SNPS=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_SNPS=y +CONFIG_MMC_SDHCI_SDMA=y +CONFIG_CMD_MMC=y +CONFIG_CMD_MMC_RPMB=y +CONFIG_SUPPORT_EMMC_RPMB=y +CONFIG_DM_MTD=y +CONFIG_MTD_SPI_NAND=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_PHY_REALTEK=y +CONFIG_RTL8211E_PINE64_GIGABIT_FIX=y +CONFIG_RTL8211X_PHY_FORCE_MASTER=y +CONFIG_RTL8211F_PHY_FORCE_EEE_RXC_ON=y +CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_DESIGNWARE_SPI=y +CONFIG_DESIGNWARE_QSPI=y +CONFIG_USB=y +CONFIG_USB_DWC3=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="U-Boot-THEAD" +CONFIG_USB_GADGET_VENDOR_NUM=0x1234 +CONFIG_USB_GADGET_PRODUCT_NUM=0x8888 +# CONFIG_SPL_USE_TINY_PRINTF is not set +# CONFIG_EFI_LOADER is not set +# CONFIG_LIGHT_SEC_UPGRADE is not set +CONFIG_BOARD_LATE_INIT=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_DM_VIDEO=y +CONFIG_PHY=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_CMD_BMP=y +CONFIG_VIDEO_BRIDGE=y +CONFIG_DM_PCA953X=y +CONFIG_VIDEO_VS_DPU=y +CONFIG_VIDEO_LCD_ILITEK_ILI9881C=y +CONFIG_VIDEO_DW_DSI_LIGHT=y +CONFIG_VIDEO_DW_DPHY=y +CONFIG_VIDEO_DW_DSI_HOST=y +CONFIG_SYS_WHITE_ON_BLACK=y +CONFIG_SYS_TEXT_BASE=0x7b000000 +CONFIG_PMIC_VOL_INIT=y +CONFIG_DDR_REGU_0V6=600000 +CONFIG_DDR_REGU_0V8=800000 +CONFIG_DDR_REGU_1V1=1100000 +CONFIG_SPL_TEXT_BASE=0xffe0000800 +CONFIG_LIGHT_ANDROID_BOOT_IMAGE_ANT_REF=y +CONFIG_AVB_USE_OEM_KEY=y +# CONFIG_AVB_ROLLBACK_ENABLE is not set +CONFIG_AVB_HW_ENGINE_ENABLE=y +CONFIG_ANDROID_BOOT_IMAGE=y +CONFIG_LIBAVB=y +CONFIG_AVB_VERIFY=y +CONFIG_CMD_AVB=y +CONFIG_CMD_BOOTANDROID=y +CONFIG_ANDROID_AB=y +CONFIG_CMD_AB_SELECT=y +CONFIG_XBC=y +CONFIG_BOARD_RNG_SEED=y diff --git a/configs/light_b_product_android_defconfig b/configs/light_b_product_android_defconfig index 777e3d55..c46a8ec4 100644 --- a/configs/light_b_product_android_defconfig +++ b/configs/light_b_product_android_defconfig @@ -107,9 +107,9 @@ CONFIG_DDR_REGU_0V8=800000 CONFIG_DDR_REGU_1V1=1100000 CONFIG_SPL_TEXT_BASE=0xffe0000800 CONFIG_LIGHT_ANDROID_BOOT_IMAGE_VAL_B=y -# CONFIG_AVB_USE_OEM_KEY is not set +CONFIG_AVB_USE_OEM_KEY=y # CONFIG_AVB_ROLLBACK_ENABLE is not set -# CONFIG_AVB_HW_ENGINE_ENABLE is not set +CONFIG_AVB_HW_ENGINE_ENABLE=y CONFIG_ANDROID_BOOT_IMAGE=y CONFIG_LIBAVB=y CONFIG_AVB_VERIFY=y @@ -118,3 +118,4 @@ CONFIG_CMD_BOOTANDROID=y CONFIG_ANDROID_AB=y CONFIG_CMD_AB_SELECT=y CONFIG_XBC=y +CONFIG_BOARD_RNG_SEED=y diff --git a/configs/light_beagle_android_defconfig b/configs/light_beagle_android_defconfig index 69bdae33..48942561 100644 --- a/configs/light_beagle_android_defconfig +++ b/configs/light_beagle_android_defconfig @@ -101,6 +101,10 @@ CONFIG_PMIC_VOL_INIT=y CONFIG_DDR_REGU_0V6=600000 CONFIG_DDR_REGU_0V8=800000 CONFIG_DDR_REGU_1V1=1100000 +CONFIG_LIGHT_ANDROID_BOOT_IMAGE_VAL_BEAGLE=y +CONFIG_AVB_USE_OEM_KEY=y +# CONFIG_AVB_ROLLBACK_ENABLE is not set +CONFIG_AVB_HW_ENGINE_ENABLE=y CONFIG_ANDROID_BOOT_IMAGE=y CONFIG_LIBAVB=y CONFIG_AVB_VERIFY=y @@ -109,3 +113,5 @@ CONFIG_CMD_BOOTANDROID=y CONFIG_ANDROID_AB=y CONFIG_CMD_AB_SELECT=y CONFIG_XBC=y +CONFIG_BOARD_RNG_SEED=y +CONFIG_SPL_TEXT_BASE=0xffe0000800
\ No newline at end of file diff --git a/configs/light_lpi4a_android_defconfig b/configs/light_lpi4a_android_defconfig index 3f161fbf..bbf91a86 100644 --- a/configs/light_lpi4a_android_defconfig +++ b/configs/light_lpi4a_android_defconfig @@ -102,10 +102,10 @@ CONFIG_DDR_REGU_0V6=600000 CONFIG_DDR_REGU_0V8=800000 CONFIG_DDR_REGU_1V1=1100000 CONFIG_SPL_TEXT_BASE=0xffe0000800 -CONFIG_LIGHT_ANDROID_BOOT_IMAGE_VAL_B=y -# CONFIG_AVB_USE_OEM_KEY is not set +CONFIG_LIGHT_ANDROID_BOOT_IMAGE_VAL_LPI4A=y +CONFIG_AVB_USE_OEM_KEY=y # CONFIG_AVB_ROLLBACK_ENABLE is not set -# CONFIG_AVB_HW_ENGINE_ENABLE is not set +CONFIG_AVB_HW_ENGINE_ENABLE=y CONFIG_ANDROID_BOOT_IMAGE=y CONFIG_LIBAVB=y CONFIG_AVB_VERIFY=y @@ -114,3 +114,4 @@ CONFIG_CMD_BOOTANDROID=y CONFIG_ANDROID_AB=y CONFIG_CMD_AB_SELECT=y CONFIG_XBC=y +CONFIG_BOARD_RNG_SEED=y diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c index 9dc70beb..4b5a7a13 100644 --- a/drivers/fastboot/fb_command.c +++ b/drivers/fastboot/fb_command.c @@ -266,7 +266,7 @@ void fastboot_data_complete(char *response) } /** - * check_image_board_id() - check if board id in image matched with board id in env + * check_image_board_id() - check if board id in image matched with board id in env * * @image_data: Image data * @@ -275,28 +275,22 @@ void fastboot_data_complete(char *response) int check_image_board_id(uint8_t *image_data) { char *env_board_id = NULL; - char board_id[3] = {0}; - + char board_id[3] = {0}; env_board_id = env_get("board#"); - /*if current board id is null or image has no header,skip check*/ if (env_board_id == NULL || env_board_id[0] == 0 || image_have_head((unsigned long)image_data) == 0) { return 0; } - memcpy(board_id, image_data + BOARD_ID_OFFSET,sizeof(uint16_t)); - - /*if image board id is null,skip check*/ - if (*(uint16_t*)board_id == 0) { - return 0; + /*if image board id is null,skip check*/ + if (*(uint16_t*)board_id == 0) { + return 0; } - - /*check if current board id match with board id in image*/ + /*check if current board id match with board id in image*/ if (strncmp(env_board_id, board_id, sizeof(board_id)) != 0) { - printf("U-BOOT image download via fastboot is interrupted due to the U-BOOT for board %s does not work in the board %s\r\n",board_id,env_board_id); + printf("U-BOOT image download via fastboot is interrupted due to the U-BOOT for board %s does not work in the board %s\r\n",board_id,env_board_id); return -1; } - return 0; } @@ -316,12 +310,12 @@ static void flash(char *cmd_parameter, char *response) char cmdbuf[32]; u32 block_cnt; struct blk_desc *dev_desc; - int ret = 0; + int ret = 0; if (strcmp(cmd_parameter, "uboot") == 0) { - ret = check_image_board_id(fastboot_buf_addr); + ret = check_image_board_id(fastboot_buf_addr); if (ret != 0) { - fastboot_fail("U-BOOT image does not match the type of BOARD", response); + fastboot_fail("U-BOOT image does not match the type of BOARD", response); return; } @@ -342,6 +336,7 @@ static void flash(char *cmd_parameter, char *response) run_command(cmdbuf, 0); run_command("mmc partconf 0 1 0 0", 0); + } else if ((strcmp(cmd_parameter, "fw") == 0)) { memcpy((void *)LIGHT_FW_ADDR, fastboot_buf_addr, image_size); } else if ((strcmp(cmd_parameter, "uImage") == 0)) { @@ -356,7 +351,7 @@ static void flash(char *cmd_parameter, char *response) memcpy((void *)LIGHT_TF_FW_ADDR, fastboot_buf_addr, image_size); } else if ((strcmp(cmd_parameter, TEE_PART_NAME) == 0)) { memcpy((void *)LIGHT_TEE_FW_ADDR, fastboot_buf_addr, image_size); - } + } if(strcmp(cmd_parameter, "uboot") == 0 || (strcmp(cmd_parameter, "fw") == 0) || (strcmp(cmd_parameter, "uImage") == 0) || (strcmp(cmd_parameter, "dtb") == 0) || @@ -375,7 +370,7 @@ static void flash(char *cmd_parameter, char *response) #endif /* Send ACK to host */ fastboot_okay(NULL, response); - + /* set secure upgrade flag to indicate it is TF image upgrade*/ sprintf(cmdbuf,"env set sec_upgrade_mode 0x%x", TF_SEC_UPGRADE_FLAG); run_command(cmdbuf, 0); @@ -391,13 +386,29 @@ static void flash(char *cmd_parameter, char *response) /* Send ACK to host */ fastboot_okay(NULL, response); - + /* set secure upgrade flag to indicate it is TEE image upgrade*/ sprintf(cmdbuf,"env set sec_upgrade_mode 0x%x", TEE_SEC_UPGRADE_FLAG); run_command(cmdbuf, 0); run_command("saveenv", 0); run_command("reset", 0); return; + } else if (strcmp(cmd_parameter, SBMETA_IMG_UPD_NAME) == 0) { + #if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC) + /* tee/tf/uboot image must be written into stash partition */ + sprintf(cmdbuf, "%s", STASH_PART_NAME); + fastboot_mmc_flash_write(cmdbuf, fastboot_buf_addr, image_size, response); + #endif + + /* Send ACK to host */ + fastboot_okay(NULL, response); + + /* set secure upgrade flag to indicate it is TEE image upgrade*/ + sprintf(cmdbuf,"env set sec_upgrade_mode 0x%x", SBMETA_SEC_UPGRADE_FLAG); + run_command(cmdbuf, 0); + run_command("saveenv", 0); + run_command("reset", 0); + return; } else if (strcmp(cmd_parameter, UBOOT_IMG_UPD_NAME) == 0) { #if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC) @@ -409,14 +420,14 @@ static void flash(char *cmd_parameter, char *response) /* Send ACK to host */ fastboot_okay(NULL, response); - + /* set secure upgrade flag to indicate it is UBOOT image upgrade*/ sprintf(cmdbuf,"env set sec_upgrade_mode 0x%x", UBOOT_SEC_UPGRADE_FLAG); run_command(cmdbuf, 0); run_command("saveenv", 0); run_command("reset", 0); return; - } + } #endif #if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC) diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile index 94c337b8..60dba79d 100644 --- a/drivers/tpm/Makefile +++ b/drivers/tpm/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_TPM_ST33ZP24_SPI) += tpm_tis_st33zp24_spi.o obj-$(CONFIG_TPM2_TIS_SANDBOX) += tpm2_tis_sandbox.o obj-$(CONFIG_TPM2_TIS_SPI) += tpm2_tis_spi.o +obj-$(CONFIG_TPM_Z32H330TC_SPI) += tpm2_tis_z32h330tc_spi.o diff --git a/drivers/tpm/tpm2_tis_z32h330tc_spi.c b/drivers/tpm/tpm2_tis_z32h330tc_spi.c new file mode 100644 index 00000000..5c009c97 --- /dev/null +++ b/drivers/tpm/tpm2_tis_z32h330tc_spi.c @@ -0,0 +1,676 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Author: + * Miquel Raynal <miquel.raynal@bootlin.com> + * + * Description: + * SPI-level driver for TCG/TIS TPM (trusted platform module). + * Specifications at www.trustedcomputinggroup.org + * + * This device driver implements the TPM interface as defined in + * the TCG SPI protocol stack version 2.0. + * + * It is based on the U-Boot driver tpm_tis_infineon_i2c.c. + */ + +#include <common.h> +#include <dm.h> +#include <fdtdec.h> +#include <log.h> +#include <spi.h> +#include <tpm-v2.h> +#include <linux/errno.h> +#include <linux/compiler.h> +#include <linux/types.h> +#include <linux/unaligned/be_byteshift.h> +#include <asm-generic/gpio.h> + +#include "tpm_tis.h" +#include "tpm_internal.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define TPM_ACCESS(l) (0x0000 | ((l) << 12)) +#define TPM_INT_ENABLE(l) (0x0008 | ((l) << 12)) +#define TPM_STS(l) (0x0018 | ((l) << 12)) +#define TPM_DATA_FIFO(l) (0x0024 | ((l) << 12)) +#define TPM_DID_VID(l) (0x0F00 | ((l) << 12)) +#define TPM_RID(l) (0x0F04 | ((l) << 12)) + +#define MAX_SPI_FRAMESIZE 64 + +/* Number of wait states to wait for */ +#define TPM_WAIT_STATES 100 + +/** + * struct tpm_tis_chip_data - Non-discoverable TPM information + * + * @pcr_count: Number of PCR per bank + * @pcr_select_min: Size in octets of the pcrSelect array + */ +struct tpm_tis_chip_data { + unsigned int pcr_count; + unsigned int pcr_select_min; + unsigned int time_before_first_cmd_ms; +}; + + +/** + * tpm_tis_spi_read() - Read from TPM register + * + * @addr: register address to read from + * @buffer: provided by caller + * @len: number of bytes to read + * + * Read len bytes from TPM register and put them into + * buffer (little-endian format, i.e. first byte is put into buffer[0]). + * + * NOTE: TPM is big-endian for multi-byte values. Multi-byte + * values have to be swapped. + * + * @return -EIO on error, 0 on success. + */ +static int tpm_tis_spi_xfer(struct udevice *dev, u32 addr, const u8 *out, + u8 *in, u16 len) +{ + struct spi_slave *slave = dev_get_parent_priv(dev); + int transfer_len, ret; + u8 tx_buf[MAX_SPI_FRAMESIZE]; + u8 rx_buf[MAX_SPI_FRAMESIZE]; + + if (in && out) { + log(LOGC_NONE, LOGL_ERR, "%s: can't do full duplex\n", + __func__); + return -EINVAL; + } + + ret = spi_claim_bus(slave); + if (ret < 0) { + log(LOGC_NONE, LOGL_ERR, "%s: could not claim bus\n", __func__); + return ret; + } + + while (len) { + /* Request */ + transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE); + tx_buf[0] = (in ? BIT(7) : 0) | (transfer_len - 1); + tx_buf[1] = 0xD4; + tx_buf[2] = addr >> 8; + tx_buf[3] = addr; + ret = spi_xfer(slave, 4 * 8, tx_buf, rx_buf, SPI_XFER_BEGIN); + if (ret < 0) { + log(LOGC_NONE, LOGL_ERR, + "%s: spi request transfer failed (err: %d)\n", + __func__, ret); + goto release_bus; + } + + /* Wait state */ + if (!(rx_buf[3] & 0x1)) { + int i; + + for (i = 0; i < TPM_WAIT_STATES; i++) { + ret = spi_xfer(slave, 1 * 8, NULL, rx_buf, 0); + if (ret) { + log(LOGC_NONE, LOGL_ERR, + "%s: wait state failed: %d\n", + __func__, ret); + goto release_bus; + } + + if (rx_buf[0] & 0x1) + break; + } + + if (i == TPM_WAIT_STATES) { + log(LOGC_NONE, LOGL_ERR, + "%s: timeout on wait state\n", __func__); + ret = -ETIMEDOUT; + goto release_bus; + } + } + + /* Read/Write */ + if (out) { + memcpy(tx_buf, out, transfer_len); + out += transfer_len; + } + + ret = spi_xfer(slave, transfer_len * 8, + out ? tx_buf : NULL, + in ? rx_buf : NULL, + SPI_XFER_END); + if (ret) { + log(LOGC_NONE, LOGL_ERR, + "%s: spi read transfer failed (err: %d)\n", + __func__, ret); + goto release_bus; + } + + if (in) { + memcpy(in, rx_buf, transfer_len); + in += transfer_len; + } + + len -= transfer_len; + } + +release_bus: + /* If an error occurred, release the chip by deasserting the CS */ + if (ret < 0) + spi_xfer(slave, 0, NULL, NULL, SPI_XFER_END); + + spi_release_bus(slave); + + return ret; +} + +static int tpm_tis_spi_read(struct udevice *dev, u16 addr, u8 *in, u16 len) +{ + return tpm_tis_spi_xfer(dev, addr, NULL, in, len); +} + +static int tpm_tis_spi_read32(struct udevice *dev, u32 addr, u32 *result) +{ + __le32 result_le; + int ret; + + ret = tpm_tis_spi_read(dev, addr, (u8 *)&result_le, sizeof(u32)); + if (!ret) + *result = le32_to_cpu(result_le); + + return ret; +} + +static int tpm_tis_spi_write(struct udevice *dev, u16 addr, const u8 *out, + u16 len) +{ + return tpm_tis_spi_xfer(dev, addr, out, NULL, len); +} + +static int tpm_tis_spi_check_locality(struct udevice *dev, int loc) +{ + const u8 mask = TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID; + struct tpm_chip *chip = dev_get_priv(dev); + u8 buf; + int ret; + + ret = tpm_tis_spi_read(dev, TPM_ACCESS(loc), &buf, 1); + if (ret) + return ret; + + if ((buf & mask) == mask) { + chip->locality = loc; + return 0; + } + + return -ENOENT; +} + +static void tpm_tis_spi_release_locality(struct udevice *dev, int loc, + bool force) +{ + const u8 mask = TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID; + u8 buf; + + if (tpm_tis_spi_read(dev, TPM_ACCESS(loc), &buf, 1) < 0) + return; + + if (force || (buf & mask) == mask) { + buf = TPM_ACCESS_ACTIVE_LOCALITY; + tpm_tis_spi_write(dev, TPM_ACCESS(loc), &buf, 1); + } +} + +static int tpm_tis_spi_request_locality(struct udevice *dev, int loc) +{ + struct tpm_chip *chip = dev_get_priv(dev); + unsigned long start, stop; + u8 buf = TPM_ACCESS_REQUEST_USE; + int ret; + + ret = tpm_tis_spi_check_locality(dev, loc); + if (!ret) + return 0; + + if (ret != -ENOENT) { + log(LOGC_NONE, LOGL_ERR, "%s: Failed to get locality: %d\n", + __func__, ret); + return ret; + } + + ret = tpm_tis_spi_write(dev, TPM_ACCESS(loc), &buf, 1); + if (ret) { + log(LOGC_NONE, LOGL_ERR, "%s: Failed to write to TPM: %d\n", + __func__, ret); + return ret; + } + + start = get_timer(0); + stop = chip->timeout_a; + do { + ret = tpm_tis_spi_check_locality(dev, loc); + if (!ret) + return 0; + + if (ret != -ENOENT) { + log(LOGC_NONE, LOGL_ERR, + "%s: Failed to get locality: %d\n", __func__, ret); + return ret; + } + + mdelay(TPM_TIMEOUT_MS); + } while (get_timer(start) < stop); + + log(LOGC_NONE, LOGL_ERR, "%s: Timeout getting locality: %d\n", __func__, + ret); + + return ret; +} + +static u8 tpm_tis_spi_status(struct udevice *dev, u8 *status) +{ + struct tpm_chip *chip = dev_get_priv(dev); + + return tpm_tis_spi_read(dev, TPM_STS(chip->locality), status, 1); +} + +static int tpm_tis_spi_wait_for_stat(struct udevice *dev, u8 mask, + unsigned long timeout, u8 *status) +{ + unsigned long start = get_timer(0); + unsigned long stop = timeout; + int ret; + + do { + mdelay(TPM_TIMEOUT_MS); + ret = tpm_tis_spi_status(dev, status); + if (ret) + return ret; + + if ((*status & mask) == mask) + return 0; + } while (get_timer(start) < stop); + + return -ETIMEDOUT; +} + +static u8 tpm_tis_spi_valid_status(struct udevice *dev, u8 *status) +{ + struct tpm_chip *chip = dev_get_priv(dev); + + return tpm_tis_spi_wait_for_stat(dev, TPM_STS_VALID, + chip->timeout_c, status); +} + +static int tpm_tis_spi_get_burstcount(struct udevice *dev) +{ + struct tpm_chip *chip = dev_get_priv(dev); + unsigned long start, stop; + u32 burstcount, ret; + + /* wait for burstcount */ + start = get_timer(0); + stop = chip->timeout_d; + do { + ret = tpm_tis_spi_read32(dev, TPM_STS(chip->locality), + &burstcount); + if (ret) + return -EBUSY; + + burstcount = (burstcount >> 8) & 0xFFFF; + if (burstcount) + return burstcount; + + mdelay(TPM_TIMEOUT_MS); + } while (get_timer(start) < stop); + + return -EBUSY; +} + +static int tpm_tis_spi_cancel(struct udevice *dev) +{ + struct tpm_chip *chip = dev_get_priv(dev); + u8 data = TPM_STS_COMMAND_READY; + + return tpm_tis_spi_write(dev, TPM_STS(chip->locality), &data, 1); +} + +static int tpm_tis_spi_recv_data(struct udevice *dev, u8 *buf, size_t count) +{ + struct tpm_chip *chip = dev_get_priv(dev); + int size = 0, burstcnt, len, ret; + u8 status; + + while (size < count && + tpm_tis_spi_wait_for_stat(dev, + TPM_STS_DATA_AVAIL | TPM_STS_VALID, + chip->timeout_c, &status) == 0) { + burstcnt = tpm_tis_spi_get_burstcount(dev); + if (burstcnt < 0) + return burstcnt; + + len = min_t(int, burstcnt, count - size); + ret = tpm_tis_spi_read(dev, TPM_DATA_FIFO(chip->locality), + buf + size, len); + if (ret < 0) + return ret; + + size += len; + } + + return size; +} + +static int z32h330tc_spi_recv(struct udevice *dev, u8 *buf, size_t count) +{ + struct tpm_chip *chip = dev_get_priv(dev); + int size, expected; + + if (!chip) + return -ENODEV; + + if (count < TPM_HEADER_SIZE) { + size = -EIO; + goto out; + } + + size = tpm_tis_spi_recv_data(dev, buf, TPM_HEADER_SIZE); + if (size < TPM_HEADER_SIZE) { + log(LOGC_NONE, LOGL_ERR, "TPM error, unable to read header\n"); + goto out; + } + + expected = get_unaligned_be32(buf + 2); + if (expected > count) { + size = -EIO; + goto out; + } + + size += tpm_tis_spi_recv_data(dev, &buf[TPM_HEADER_SIZE], + expected - TPM_HEADER_SIZE); + if (size < expected) { + log(LOGC_NONE, LOGL_ERR, + "TPM error, unable to read remaining bytes of result\n"); + size = -EIO; + goto out; + } + +out: + tpm_tis_spi_cancel(dev); + tpm_tis_spi_release_locality(dev, chip->locality, false); + + return size; +} + +static int z32h330tc_spi_send(struct udevice *dev, const u8 *buf, size_t len) +{ + struct tpm_chip *chip = dev_get_priv(dev); + u32 i, size; + u8 status; + int burstcnt, ret; + u8 data; + + if (!chip) + return -ENODEV; + + if (len > TPM_DEV_BUFSIZE) + return -E2BIG; /* Command is too long for our tpm, sorry */ + + ret = tpm_tis_spi_request_locality(dev, 0); + if (ret < 0) + return -EBUSY; + + /* + * Check if the TPM is ready. If not, if not, cancel the pending command + * and poll on the status to be finally ready. + */ + ret = tpm_tis_spi_status(dev, &status); + if (ret) + return ret; + + if (!(status & TPM_STS_COMMAND_READY)) { + /* Force the transition, usually this will be done at startup */ + ret = tpm_tis_spi_cancel(dev); + if (ret) { + log(LOGC_NONE, LOGL_ERR, + "%s: Could not cancel previous operation\n", + __func__); + goto out_err; + } + + ret = tpm_tis_spi_wait_for_stat(dev, TPM_STS_COMMAND_READY, + chip->timeout_b, &status); + if (ret < 0 || !(status & TPM_STS_COMMAND_READY)) { + log(LOGC_NONE, LOGL_ERR, + "status %d after wait for stat returned %d\n", + status, ret); + goto out_err; + } + } + + for (i = 0; i < len - 1;) { + burstcnt = tpm_tis_spi_get_burstcount(dev); + if (burstcnt < 0) + return burstcnt; + + size = min_t(int, len - i - 1, burstcnt); + ret = tpm_tis_spi_write(dev, TPM_DATA_FIFO(chip->locality), + buf + i, size); + if (ret < 0) + goto out_err; + + i += size; + } + + ret = tpm_tis_spi_valid_status(dev, &status); + if (ret) + goto out_err; + + if ((status & TPM_STS_DATA_EXPECT) == 0) { + ret = -EIO; + goto out_err; + } + + ret = tpm_tis_spi_write(dev, TPM_DATA_FIFO(chip->locality), + buf + len - 1, 1); + if (ret) + goto out_err; + + ret = tpm_tis_spi_valid_status(dev, &status); + if (ret) + goto out_err; + + if ((status & TPM_STS_DATA_EXPECT) != 0) { + ret = -EIO; + goto out_err; + } + + data = TPM_STS_GO; + ret = tpm_tis_spi_write(dev, TPM_STS(chip->locality), &data, 1); + if (ret) + goto out_err; + + return len; + +out_err: + tpm_tis_spi_cancel(dev); + tpm_tis_spi_release_locality(dev, chip->locality, false); + + return ret; +} + +static int z32h330tc_spi_cleanup(struct udevice *dev) +{ + struct tpm_chip *chip = dev_get_priv(dev); + + tpm_tis_spi_cancel(dev); + /* + * The TPM needs some time to clean up here, + * so we sleep rather than keeping the bus busy + */ + mdelay(2); + tpm_tis_spi_release_locality(dev, chip->locality, false); + + return 0; +} + +static int z32h330tc_spi_open(struct udevice *dev) +{ + struct tpm_chip *chip = dev_get_priv(dev); + struct tpm_chip_priv *priv = dev_get_uclass_priv(dev); + + if (chip->is_open) + return -EBUSY; + + chip->is_open = 1; + + return 0; +} + +static int z32h330tc_spi_close(struct udevice *dev) +{ + struct tpm_chip *chip = dev_get_priv(dev); + + if (chip->is_open) { + tpm_tis_spi_release_locality(dev, chip->locality, true); + chip->is_open = 0; + } + + return 0; +} + +static int z32h330tc_get_desc(struct udevice *dev, char *buf, int size) +{ + struct tpm_chip *chip = dev_get_priv(dev); + if (size < 80) + return -ENOSPC; + + return snprintf(buf, size, + "%s v2.0: VendorID 0x%04x, DeviceID 0x%04x, RevisionID 0x%02x [%s]", + dev->name, chip->vend_dev & 0xFFFF, + chip->vend_dev >> 16, chip->rid, + (chip->is_open ? "open" : "closed")); +} + +static int tpm_tis_wait_init(struct udevice *dev, int loc) +{ + struct tpm_chip *chip = dev_get_priv(dev); + unsigned long start, stop; + u8 status; + int ret; + + start = get_timer(0); + stop = chip->timeout_b; + do { + mdelay(TPM_TIMEOUT_MS); + + ret = tpm_tis_spi_read(dev, TPM_ACCESS(loc), &status, 1); + if (ret) + break; + + if (status & TPM_ACCESS_VALID) + return 0; + } while (get_timer(start) < stop); + + return -EIO; +} +static const struct tpm_tis_chip_data z32h330tc_std_chip_data; + +static int z32h330tc_spi_probe(struct udevice *dev) +{ + struct tpm_tis_chip_data * drv_data = &z32h330tc_std_chip_data;//(void *)dev_get_driver_data(dev); + struct tpm_chip_priv *priv = dev_get_uclass_priv(dev); + struct tpm_chip *chip = dev_get_priv(dev); + struct udevice * bus = NULL; + int ret; + + /* Use the TPM v2 stack */ + priv->version = TPM_V2; + + /* Ensure a minimum amount of time elapsed since reset of the TPM */ + mdelay(drv_data->time_before_first_cmd_ms); + chip->locality = 0; + chip->timeout_a = TIS_SHORT_TIMEOUT_MS; + chip->timeout_b = TIS_LONG_TIMEOUT_MS; + chip->timeout_c = TIS_SHORT_TIMEOUT_MS; + chip->timeout_d = TIS_SHORT_TIMEOUT_MS; + priv->pcr_count = drv_data->pcr_count; + priv->pcr_select_min = drv_data->pcr_select_min; + + ret = tpm_tis_wait_init(dev, chip->locality); + if (ret) { + log(LOGC_DM, LOGL_ERR, "%s: no device found\n", __func__); + return ret; + } + + ret = tpm_tis_spi_request_locality(dev, chip->locality); + if (ret) { + log(LOGC_NONE, LOGL_ERR, "%s: could not request locality %d\n", + __func__, chip->locality); + return ret; + } + + ret = tpm_tis_spi_read32(dev, TPM_DID_VID(chip->locality), + &chip->vend_dev); + if (ret) { + log(LOGC_NONE, LOGL_ERR, + "%s: could not retrieve VendorID/DeviceID\n", __func__); + return ret; + } + + ret = tpm_tis_spi_read(dev, TPM_RID(chip->locality), &chip->rid, 1); + if (ret) { + log(LOGC_NONE, LOGL_ERR, "%s: could not retrieve RevisionID\n", + __func__); + return ret; + } + + log(LOGC_NONE, LOGL_ERR, + "SPI TPMv2.0 found (vid:%04x, did:%04x, rid:%02x)\n", + chip->vend_dev & 0xFFFF, chip->vend_dev >> 16, chip->rid); + + return 0; +} + +static int z32h330tc_spi_remove(struct udevice *dev) +{ + struct tpm_chip *chip = dev_get_priv(dev); + + tpm_tis_spi_release_locality(dev, chip->locality, true); + + return 0; +} + +static const struct tpm_ops z32h330tc_spi_ops = { + .open = z32h330tc_spi_open, + .close = z32h330tc_spi_close, + .get_desc = z32h330tc_get_desc, + .send = z32h330tc_spi_send, + .recv = z32h330tc_spi_recv, + .cleanup = z32h330tc_spi_cleanup, +}; + +static const struct tpm_tis_chip_data z32h330tc_std_chip_data = { + .pcr_count = 24, + .pcr_select_min = 3, + .time_before_first_cmd_ms = 30, +}; + +static const struct udevice_id z32h330tc_spi_ids[] = { + { + .compatible = "z32h330tc,z32h330tc-spi", + .data = (ulong)&z32h330tc_std_chip_data, + }, + { } +}; + +U_BOOT_DRIVER(tpm_z32h330tc_spi) = { + .name = "tpm_z32h330tc_spi", + .id = UCLASS_TPM, + .of_match = z32h330tc_spi_ids, + .ops = &z32h330tc_spi_ops, + .probe = z32h330tc_spi_probe, + .remove = z32h330tc_spi_remove, + .priv_auto_alloc_size = sizeof(struct tpm_chip), +}; diff --git a/include/abuf.h b/include/abuf.h new file mode 100644 index 00000000..9badda64 --- /dev/null +++ b/include/abuf.h @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Handles a buffer that can be allocated and freed + * + * Copyright 2021 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef __ABUF_H +#define __ABUF_H + +#include <linux/types.h> + +/** + * struct abuf - buffer that can be allocated and freed + * + * This is useful for a block of data which may be allocated with malloc(), or + * not, so that it needs to be freed correctly when finished with. + * + * For now it has a very simple purpose. + * + * Using memset() to zero all fields is guaranteed to be equivalent to + * abuf_init(). + * + * @data: Pointer to data + * @size: Size of data in bytes + * @alloced: true if allocated with malloc(), so must be freed after use + */ +struct abuf { + void *data; + size_t size; + bool alloced; +}; + +static inline void *abuf_data(const struct abuf *abuf) +{ + return abuf->data; +} + +static inline size_t abuf_size(const struct abuf *abuf) +{ + return abuf->size; +} + +/** + * abuf_set() - set the (unallocated) data in a buffer + * + * This simply makes the abuf point to the supplied data, which must be live + * for the lifetime of the abuf. It is not alloced. + * + * Any existing data in the abuf is freed and the alloced member is set to + * false. + * + * @abuf: abuf to adjust + * @data: New contents of abuf + * @size: New size of abuf + */ +void abuf_set(struct abuf *abuf, void *data, size_t size); + +/** + * abuf_map_sysmem() - calls map_sysmem() to set up an abuf + * + * This is equivalent to abuf_set(abuf, map_sysmem(addr, size), size) + * + * Any existing data in the abuf is freed and the alloced member is set to + * false. + * + * @abuf: abuf to adjust + * @addr: Address to set the abuf to + * @size: New size of abuf + */ +void abuf_map_sysmem(struct abuf *abuf, ulong addr, size_t size); + +/** + * abuf_realloc() - Change the size of a buffer + * + * This uses realloc() to change the size of the buffer, with the same semantics + * as that function. If the abuf is not currently alloced, then it will alloc + * it if the size needs to increase (i.e. set the alloced member to true) + * + * @abuf: abuf to adjust + * @new_size: new size in bytes. + * if 0, the abuf is freed + * if greater than the current size, the abuf is extended and the new + * space is not inited. The alloced member is set to true + * if less than the current size, the abuf is contracted and the data at + * the end is lost. If @new_size is 0, this sets the alloced member to + * false + * Return: true if OK, false if out of memory + */ +bool abuf_realloc(struct abuf *abuf, size_t new_size); + +/** + * abuf_uninit_move() - Return the allocated contents and uninit the abuf + * + * This returns the abuf data to the caller, allocating it if necessary, so that + * the caller receives data that it can be sure will hang around. The caller is + * responsible for freeing the data. + * + * If the abuf has allocated data, it is returned. If the abuf has data but it + * is not allocated, then it is first allocated, then returned. + * + * If the abuf size is 0, this returns NULL + * + * The abuf is uninited as part of this, except if the allocation fails, in + * which NULL is returned and the abuf remains untouched. + * + * The abuf must be inited before this can be called. + * + * @abuf: abuf to uninit + * @sizep: if non-NULL, returns the size of the returned data + * Return: data contents, allocated with malloc(), or NULL if the data could not + * be allocated, or the data size is 0 + */ +void *abuf_uninit_move(struct abuf *abuf, size_t *sizep); + +/** + * abuf_init_move() - Make abuf take over the management of an allocated region + * + * After this, @data must not be used. All access must be via the abuf. + * + * @abuf: abuf to init + * @data: Existing allocated buffer to place in the abuf + * @size: Size of allocated buffer + */ +void abuf_init_move(struct abuf *abuf, void *data, size_t size); + +/** + * abuf_init_set() - Set up a new abuf + * + * Inits a new abuf and sets up its (unallocated) data + * + * @abuf: abuf to set up + * @data: New contents of abuf + * @size: New size of abuf + */ +void abuf_init_set(struct abuf *abuf, void *data, size_t size); + +/** + * abuf_uninit() - Free any memory used by an abuf + * + * The buffer must be inited before this can be called. + * + * @abuf: abuf to uninit + */ +void abuf_uninit(struct abuf *abuf); + +/** + * abuf_init() - Set up a new abuf + * + * This initially has no data and alloced is set to false. This is equivalent to + * setting all fields to 0, e.g. with memset(), so callers can do that instead + * if desired. + * + * @abuf: abuf to set up + */ +void abuf_init(struct abuf *abuf); + +#endif diff --git a/include/android_image.h b/include/android_image.h index 54d25af0..2a784607 100644 --- a/include/android_image.h +++ b/include/android_image.h @@ -136,4 +136,18 @@ struct andr_img_hdr { * else: jump to kernel_addr */ +#define VENDOR_RAMDISK_NAME_SIZE 32 +#define VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE 16 + +#define VENDOR_RAMDISK_TYPE_RECOVERY 2 +struct vendor_ramdisk_table_entry { + u32 ramdisk_size; /* size in bytes for the ramdisk image */ + u32 ramdisk_offset; /* offset to the ramdisk image in vendor ramdisk section */ + u32 ramdisk_type; /* type of the ramdisk */ + u8 ramdisk_name[VENDOR_RAMDISK_NAME_SIZE]; /* asciiz ramdisk name */ + + // Hardware identifiers describing the board, soc or platform which this + // ramdisk is intended to be loaded on. + u32 board_id[VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE]; +} __attribute__((packed)); #endif diff --git a/include/configs/light-c910.h b/include/configs/light-c910.h index eb4fff54..baaa2966 100644 --- a/include/configs/light-c910.h +++ b/include/configs/light-c910.h @@ -77,11 +77,13 @@ #define TF_IMG_UPD_NAME "stashtf" #define TEE_IMG_UPD_NAME "stashtee" #define UBOOT_IMG_UPD_NAME "stashuboot" +#define SBMETA_IMG_UPD_NAME "stashsbmeta" #define TF_PART_NAME "tf" #define TEE_PART_NAME "tee" #define UBOOT_PART_NAME "uboot" #define STASH_PART_NAME "stash" #define KERNEL_PART_NAME "kernel" +#define SBMETA_PART_NAME "sbmeta" #define UBOOT_STAGE_ADDR SRAM_BASE_ADDR @@ -96,6 +98,7 @@ #define TF_SEC_UPGRADE_FLAG 0x5555aaaa #define TEE_SEC_UPGRADE_FLAG 0x5a5aa5a5 #define UBOOT_SEC_UPGRADE_FLAG 0xa5a5aa55 +#define SBMETA_SEC_UPGRADE_FLAG 0xaaaa5555 /* Define secure debug log level */ #define LOG_LEVEL 1 @@ -116,9 +119,13 @@ #define ENV_KERNEL_LOGLEVEL "kernel_loglevel=7\0" #define ENV_STR_BOOT_DELAY #define CONFIG_ENV_OVERWRITE +#define ENV_STR_SERIAL "serial#=1234567890\0" +#define ENV_KERNEL_KDUMP "kdump_buf=180M\0" #else #define ENV_KERNEL_LOGLEVEL "kernel_loglevel=4\0" #define ENV_STR_BOOT_DELAY "bootdelay=0\0" +#define ENV_STR_SERIAL "serial#=\0" +#define ENV_KERNEL_KDUMP "kdump_buf=0M\0" #endif #define CONFIG_MISC_INIT_R @@ -129,19 +136,19 @@ "scriptaddr=0x00500000\0" \ "pxefile_addr_r=0x00600000\0" \ "dtb_addr=0x03800000\0" \ - "fdt_addr=0x03800000\0" \ + "fdt_addr_r=0x03800000\0" \ "kernel_addr_r=0x00200000\0" \ "ramdisk_addr_r=0x06000000\0" \ "boot_conf_addr_r=0xc0000000\0" \ "aon_ram_addr=0xffffef8000\0" \ "audio_ram_addr=0x32000000\0" \ - "str_ram_addr=0xffe0000000\0" \ + "str_ram_addr=0xffe0000000\0" \ "opensbi_addr=0x0\0" \ "fwaddr=0x10000000\0" \ "splashimage=0x30000000\0" \ "splashpos=m,m\0" \ "fdt_high=0xffffffffffffffff\0" \ - ENV_STR_BOARD \ + ENV_STR_BOARD \ "kernel_addr_r=0x00200000\0" \ "kdump_buf=180M\0" \ "mmcdev=0\0" \ @@ -158,4 +165,4 @@ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \ "\0" -#endif /* __CONFIG_H */
\ No newline at end of file +#endif /* __CONFIG_H */ diff --git a/include/env_flags.h b/include/env_flags.h index 7b8bf7b7..e343c5d7 100644 --- a/include/env_flags.h +++ b/include/env_flags.h @@ -81,7 +81,7 @@ enum env_flags_varaccess { NET_FLAGS \ SERIAL_FLAGS \ CONFIG_ENV_FLAGS_LIST_STATIC \ - BOARD_FLAGS + BOARD_FLAGS #ifdef CONFIG_CMD_ENV_FLAGS /* diff --git a/include/fdt_support.h b/include/fdt_support.h index a5bdf2f6..f0c09516 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -10,6 +10,7 @@ #ifdef CONFIG_OF_LIBFDT #include <linux/libfdt.h> +#include <abuf.h> u32 fdt_getprop_u32_default_node(const void *fdt, int off, int cell, const char *prop, const u32 dflt); @@ -170,6 +171,18 @@ int fdt_find_or_add_subnode(void *fdt, int parentoffset, const char *name); */ int ft_board_setup(void *blob, bd_t *bd); +/** + * board_rng_seed() - Provide a seed to be passed via /chosen/rng-seed + * + * This function is called if CONFIG_BOARD_RNG_SEED is set, and must + * be provided by the board. It should return, via @buf, some suitable + * seed value to pass to the kernel. + * + * @param buf A struct abuf for returning the seed and its size. + * @return 0 if ok, negative on error. + */ +int board_rng_seed(struct abuf *buf); + /* * The keystone2 SOC requires all 32 bit aliased addresses to be converted * to their 36 physical format. This has to happen after all fdt nodes diff --git a/lib/Makefile b/lib/Makefile index 1f953f31..88e7b236 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -121,6 +121,7 @@ else obj-y += vsprintf.o strto.o endif +obj-y += abuf.o obj-y += date.o # diff --git a/lib/abuf.c b/lib/abuf.c new file mode 100644 index 00000000..ef794e4f --- /dev/null +++ b/lib/abuf.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Handles a buffer that can be allocated and freed + * + * Copyright 2021 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef USE_HOSTCC +#include <common.h> +#include <malloc.h> +#include <mapmem.h> +#include <string.h> +#endif + +#include <abuf.h> + +void abuf_set(struct abuf *abuf, void *data, size_t size) +{ + abuf_uninit(abuf); + abuf->data = data; + abuf->size = size; +} + +#ifndef USE_HOSTCC +void abuf_map_sysmem(struct abuf *abuf, ulong addr, size_t size) +{ + abuf_set(abuf, map_sysmem(addr, size), size); +} + +char *memdup(const void *src, size_t len); +#else +/* copied from lib/string.c for convenience */ +static char *memdup(const void *src, size_t len) +{ + char *p; + + p = malloc(len); + if (!p) + return NULL; + + memcpy(p, src, len); + + return p; +} +#endif + +bool abuf_realloc(struct abuf *abuf, size_t new_size) +{ + void *ptr; + + if (!new_size) { + /* easy case, just need to uninit, freeing any allocation */ + abuf_uninit(abuf); + return true; + } else if (abuf->alloced) { + /* currently allocated, so need to reallocate */ + ptr = realloc(abuf->data, new_size); + if (!ptr) + return false; + abuf->data = ptr; + abuf->size = new_size; + return true; + } else if (new_size <= abuf->size) { + /* + * not currently alloced and new size is no larger. Just update + * it. Data is lost off the end if new_size < abuf->size + */ + abuf->size = new_size; + return true; + } else { + /* not currently allocated and new size is larger. Alloc and + * copy in data. The new space is not inited. + */ + ptr = malloc(new_size); + if (!ptr) + return false; + if (abuf->size) + memcpy(ptr, abuf->data, abuf->size); + abuf->data = ptr; + abuf->size = new_size; + abuf->alloced = true; + return true; + } +} + +void *abuf_uninit_move(struct abuf *abuf, size_t *sizep) +{ + void *ptr; + + if (sizep) + *sizep = abuf->size; + if (!abuf->size) + return NULL; + if (abuf->alloced) { + ptr = abuf->data; + } else { + ptr = memdup(abuf->data, abuf->size); + if (!ptr) + return NULL; + } + /* Clear everything out so there is no record of the data */ + abuf_init(abuf); + + return ptr; +} + +void abuf_init_set(struct abuf *abuf, void *data, size_t size) +{ + abuf_init(abuf); + abuf_set(abuf, data, size); +} + +void abuf_init_move(struct abuf *abuf, void *data, size_t size) +{ + abuf_init_set(abuf, data, size); + abuf->alloced = true; +} + +void abuf_uninit(struct abuf *abuf) +{ + if (abuf->alloced) + free(abuf->data); + abuf_init(abuf); +} + +void abuf_init(struct abuf *abuf) +{ + abuf->data = NULL; + abuf->size = 0; + abuf->alloced = false; +} diff --git a/lib/sec_library/include/core/csi_rv64_gcc.h b/lib/sec_library/include/core/csi_rv64_gcc.h index 0341b768..438aa1d8 100644 --- a/lib/sec_library/include/core/csi_rv64_gcc.h +++ b/lib/sec_library/include/core/csi_rv64_gcc.h @@ -14,6 +14,7 @@ #define _CSI_RV64_GCC_H_ #include <stdlib.h> +#include <linux/kernel.h> #ifndef __ASM #define __ASM __asm /*!< asm keyword for GNU Compiler */ |