diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2019-08-15 10:58:08 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-08-15 10:58:08 +0200 |
commit | bd1fbce74f79d647af4ee338f9193351811e80f4 (patch) | |
tree | dc119b20a406c2f7f9df0d1b7990deb876a402a4 /arch | |
parent | 53e145d550c1ee9db907fccd7ad4d98d6aee806b (diff) | |
parent | dd5dfb6ff467f6d640e48046acedfe435c649c94 (diff) | |
download | barebox-bd1fbce74f79d647af4ee338f9193351811e80f4.tar.gz barebox-bd1fbce74f79d647af4ee338f9193351811e80f4.tar.xz |
Merge branch 'for-next/imx8-hab'
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/boards/nxp-imx8mq-evk/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg | 1 | ||||
-rw-r--r-- | arch/arm/boards/nxp-imx8mq-evk/lowlevel.c | 106 | ||||
-rw-r--r-- | arch/arm/boards/nxp-imx8mq-evk/trampoline.S | 10 | ||||
-rw-r--r-- | arch/arm/cpu/uncompress.c | 17 | ||||
-rw-r--r-- | arch/arm/lib/pbl.lds.S | 17 | ||||
-rw-r--r-- | arch/arm/mach-imx/Kconfig | 5 | ||||
-rw-r--r-- | arch/arm/mach-imx/include/mach/habv4-imx8-gencsf.h | 59 | ||||
-rw-r--r-- | arch/arm/mach-imx/include/mach/imx-header.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-imx/include/mach/xload.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-imx/xload-common.c | 6 |
11 files changed, 179 insertions, 53 deletions
diff --git a/arch/arm/boards/nxp-imx8mq-evk/Makefile b/arch/arm/boards/nxp-imx8mq-evk/Makefile index 0546b0b078..7907de411f 100644 --- a/arch/arm/boards/nxp-imx8mq-evk/Makefile +++ b/arch/arm/boards/nxp-imx8mq-evk/Makefile @@ -1,4 +1,2 @@ obj-y += board.o -lwl-y += lowlevel.o ddr_init.o ddrphy_train.o - - +lwl-y += lowlevel.o ddr_init.o ddrphy_train.o trampoline.o diff --git a/arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg b/arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg index aff8321b9a..11463fe850 100644 --- a/arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg +++ b/arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg @@ -3,3 +3,4 @@ soc imx8mq loadaddr 0x007E1000 max_load_size 0x3F000 dcdofs 0x400 +#include <mach/habv4-imx8-gencsf.h> diff --git a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c index e3fdc64edf..a74171e5e5 100644 --- a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c +++ b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c @@ -53,76 +53,89 @@ static void setup_uart(void) static void nxp_imx8mq_evk_sram_setup(void) { - enum bootsource src = BOOTSOURCE_UNKNOWN; - int instance = BOOTSOURCE_INSTANCE_UNKNOWN; - int ret = -ENOTSUPP; - ddr_init(); +} - imx8_get_boot_source(&src, &instance); +extern unsigned char trampoline_start[]; +extern unsigned char trampoline_end[]; - if (src == BOOTSOURCE_MMC) - ret = imx8_esdhc_start_image(instance); +static void nxp_imx8mq_evk_install_tfa_trampoline(void) +{ + unsigned int tramp_len; + unsigned int offset; + /* + * Create a trampoline which is places in DRAM and calls back into the + * PBL entry function found in the TCRAM. Register x0 is set to 1 to + * indicate that DRAM setup was already run. + */ + tramp_len = (void *)trampoline_end - (void *)trampoline_start; + memcpy((void *)MX8MQ_ATF_BL33_BASE_ADDR, (void *)trampoline_start, + tramp_len); - BUG_ON(ret); + offset = get_runtime_offset(); + memcpy((void *)MX8MQ_ATF_BL33_BASE_ADDR + tramp_len, &offset, + sizeof(offset)); } +/* + * Power-on execution flow of start_nxp_imx8mq_evk() might not be + * obvious for a very first read, so here's, hopefully helpful, + * summary: + * + * 1. MaskROM uploads PBL into OCRAM and that's where this function is + * executed for the first time + * + * 2. DDR is initialized and the TF-A trampoline is installed in the + * DRAM. + * + * 3. TF-A is executed and exits into the trampoline in RAM, which enters the + * PBL for the second time. DRAM setup done is indicated by a one in register + * x0 by the trampoline + * + * 4. The piggydata is loaded from the SD card and copied to the expected + * location in the DRAM. + * + * 5. Standard barebox boot flow continues + */ static __noreturn noinline void nxp_imx8mq_evk_start(void) { + enum bootsource src = BOOTSOURCE_UNKNOWN; + int instance = BOOTSOURCE_INSTANCE_UNKNOWN; + int ret = -ENOTSUPP; + const u8 *bl31; + size_t bl31_size; + + imx8mq_cpu_lowlevel_init(); + if (IS_ENABLED(CONFIG_DEBUG_LL)) setup_uart(); - if (get_pc() < MX8MQ_DDR_CSD1_BASE_ADDR) { - /* - * We assume that we were just loaded by MaskROM into - * SRAM if we are not running from DDR. We also assume - * that means DDR needs to be initialized for the - * first time. - */ - nxp_imx8mq_evk_sram_setup(); - } /* - * Straight from the power-on we are at EL3, so the following - * code _will_ load and jump to ATF. - * - * However when we are re-executed upon exit from ATF's - * initialization routine, it is EL2 which means we'll skip - * loadting ATF blob again + * if register r0 does not contain 1, we are running for the first time + * and need to initialize the DRAM, install the trampoline and run TF-A + * (BL31). + * Otherwise the 1 indicates that the DRAM setup and trampoline are + * already installed and TF-A has been run. In this case we can skip */ if (current_el() == 3) { - const u8 *bl31; - size_t bl31_size; - + nxp_imx8mq_evk_sram_setup(); + nxp_imx8mq_evk_install_tfa_trampoline(); get_builtin_firmware(imx8mq_bl31_bin, &bl31, &bl31_size); imx8mq_atf_load_bl31(bl31, bl31_size); } + imx8_get_boot_source(&src, &instance); + + if (src == BOOTSOURCE_MMC) + ret = imx8_esdhc_load_piggy(instance); + else + BUG_ON(ret); /* * Standard entry we hit once we initialized both DDR and ATF */ imx8mq_barebox_entry(__dtb_imx8mq_evk_start); } -/* - * Power-on execution flow of start_nxp_imx8mq_evk() might not be - * obvious for a very first read, so here's, hopefully helpful, - * summary: - * - * 1. MaskROM uploads PBL into OCRAM and that's where this function is - * executed for the first time - * - * 2. DDR is initialized and full i.MX image is loaded to the - * beginning of RAM - * - * 3. start_nxp_imx8mq_evk, now in RAM, is executed again - * - * 4. BL31 blob is uploaded to OCRAM and the control is transfer to it - * - * 5. BL31 exits EL3 into EL2 at address MX8MQ_ATF_BL33_BASE_ADDR, - * executing start_nxp_imx8mq_evk() the third time - * - * 6. Standard barebox boot flow continues - */ ENTRY_FUNCTION(start_nxp_imx8mq_evk, r0, r1, r2) { imx8mq_cpu_lowlevel_init(); @@ -132,4 +145,3 @@ ENTRY_FUNCTION(start_nxp_imx8mq_evk, r0, r1, r2) nxp_imx8mq_evk_start(); } - diff --git a/arch/arm/boards/nxp-imx8mq-evk/trampoline.S b/arch/arm/boards/nxp-imx8mq-evk/trampoline.S new file mode 100644 index 0000000000..54a1b76518 --- /dev/null +++ b/arch/arm/boards/nxp-imx8mq-evk/trampoline.S @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: (GPL-2.0) */ +#include <linux/linkage.h> +#include <asm/sections.h> + .section .trampoline,"a" + .globl trampoline_start +trampoline_start: + ldr w19, trampoline_end + br x19 + .globl trampoline_end +trampoline_end: diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c index 4f16af22f8..9cc3b358b0 100644 --- a/arch/arm/cpu/uncompress.c +++ b/arch/arm/cpu/uncompress.c @@ -42,14 +42,18 @@ unsigned long free_mem_end_ptr; extern unsigned char input_data[]; extern unsigned char input_data_end[]; +extern unsigned char sha_sum[]; +extern unsigned char sha_sum_end[]; + void __noreturn barebox_multi_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata) { - uint32_t pg_len, uncompressed_len; + uint32_t pg_len, uncompressed_len, pbl_hash_len; void __noreturn (*barebox)(unsigned long, unsigned long, void *); unsigned long endmem = membase + memsize; unsigned long barebox_base; void *pg_start, *pg_end; + void *pbl_hash_start, *pbl_hash_end; unsigned long pc = get_pc(); pg_start = input_data + global_variable_offset(); @@ -92,6 +96,17 @@ void __noreturn barebox_multi_pbl_start(unsigned long membase, pr_debug("uncompressing barebox binary at 0x%p (size 0x%08x) to 0x%08lx (uncompressed size: 0x%08x)\n", pg_start, pg_len, barebox_base, uncompressed_len); + if (IS_ENABLED(CONFIG_PBL_VERIFY_PIGGY)) { + pbl_hash_start = sha_sum; + pbl_hash_end = sha_sum_end; + pbl_hash_len = pbl_hash_end - pbl_hash_start; + if (pbl_barebox_verify(pg_start, pg_len, pbl_hash_start, + pbl_hash_len) != 0) { + putc_ll('!'); + panic("hash mismatch, refusing to decompress"); + } + } + pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len); sync_caches_for_execution(); diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S index 300671bb51..01ed384495 100644 --- a/arch/arm/lib/pbl.lds.S +++ b/arch/arm/lib/pbl.lds.S @@ -68,6 +68,13 @@ SECTIONS . = ALIGN(4); .data : { *(.data*) } + . = ALIGN(4); + __shasum_start = .; + .shasum : { + KEEP(*(.shasum)) + } + __shasum_end = .; + .rel_dyn_start : { *(.__rel_dyn_start) } #ifdef CONFIG_CPU_32 .rel.dyn : { *(.rel*) } @@ -90,6 +97,16 @@ SECTIONS pbl_memory_size = . - BASE; +#if defined(CONFIG_CPU_64) && defined(CONFIG_HABV4) + . = ALIGN(0x1000); + __csf_start = .; + .hab_csf : { + BYTE(0x5a); + . += + 0x1fff; + } = 0x5a + __csf_end = .; +#endif /* CONFIG_CPU_64 && CONFIG_HABV4 */ + . = ALIGN(4); __piggydata_start = .; .piggydata : { diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 553d11a793..e7721621ab 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -183,6 +183,7 @@ config ARCH_IMX8MQ select COMMON_CLK_OF_PROVIDER select ARCH_HAS_FEC_IMX select HW_HAS_PCI + select PBL_VERIFY_PIGGY if HABV4 config ARCH_VF610 bool @@ -787,10 +788,10 @@ config HABV4 select HAB select NVMEM select IMX_OCOTP - depends on ARCH_IMX6 + depends on ARCH_IMX6 || ARCH_IMX8MQ depends on OFDEVICE help - High Assurance Boot, as found on i.MX28/i.MX6. + High Assurance Boot, as found on i.MX28/i.MX6/i.MX8MQ. config HAB_CERTS_ENV depends on HAB diff --git a/arch/arm/mach-imx/include/mach/habv4-imx8-gencsf.h b/arch/arm/mach-imx/include/mach/habv4-imx8-gencsf.h new file mode 100644 index 0000000000..34039ee590 --- /dev/null +++ b/arch/arm/mach-imx/include/mach/habv4-imx8-gencsf.h @@ -0,0 +1,59 @@ +/* + * This snippet can be included from a i.MX flash header configuration + * file for generating signed images. The necessary keys/certificates + * are expected in these config variables: + * + * CONFIG_HABV4_TABLE_BIN + * CONFIG_HABV4_CSF_CRT_PEM + * CONFIG_HABV4_IMG_CRT_PEM + */ +#if defined(CONFIG_HABV4) && defined(CONFIG_CPU_64) +hab [Header] +hab Version = 4.3 +hab Hash Algorithm = sha256 +hab Engine Configuration = 0 +hab Certificate Format = X509 +hab Signature Format = CMS +hab Engine = CAAM + +hab [Install SRK] +hab File = CONFIG_HABV4_TABLE_BIN +hab # SRK index within SRK-Table 0..3 +hab Source index = 0 + +hab [Install CSFK] +/* target key index in keystore 1 */ +hab File = CONFIG_HABV4_CSF_CRT_PEM + +hab [Authenticate CSF] + +hab [Unlock] +hab Engine = CAAM +hab Features = RNG + +hab [Install Key] +/* verification key index in key store (0, 2...4) */ +hab Verification index = 0 +/* target key index in key store (2...4) */ +hab Target index = 2 +hab File = CONFIG_HABV4_IMG_CRT_PEM + +hab [Authenticate Data] +/* verification key index in key store (2...4) */ +hab Verification index = 2 + +hab_blocks + +hab_encrypt [Install Secret Key] +hab_encrypt Verification index = 0 +hab_encrypt Target index = 0 +hab_encrypt_key +hab_encrypt_key_length 256 +hab_encrypt_blob_address + +hab_encrypt [Decrypt Data] +hab_encrypt Verification index = 0 +hab_encrypt Mac Bytes = 16 + +hab_encrypt_blocks +#endif diff --git a/arch/arm/mach-imx/include/mach/imx-header.h b/arch/arm/mach-imx/include/mach/imx-header.h index 50584bb24b..dc8e2eee2f 100644 --- a/arch/arm/mach-imx/include/mach/imx-header.h +++ b/arch/arm/mach-imx/include/mach/imx-header.h @@ -98,6 +98,7 @@ struct config_data { uint32_t image_size; uint32_t max_load_size; uint32_t load_size; + uint32_t pbl_code_size; char *outfile; char *srkfile; int header_version; @@ -111,6 +112,7 @@ struct config_data { int (*nop)(const struct config_data *data); int csf_space; char *csf; + int sign_image; char *signed_hdmi_firmware_file; int encrypt_image; size_t dek_size; diff --git a/arch/arm/mach-imx/include/mach/xload.h b/arch/arm/mach-imx/include/mach/xload.h index 8f141bc37e..a605e76339 100644 --- a/arch/arm/mach-imx/include/mach/xload.h +++ b/arch/arm/mach-imx/include/mach/xload.h @@ -6,7 +6,12 @@ int imx6_spi_load_image(int instance, unsigned int flash_offset, void *buf, int int imx6_spi_start_image(int instance); int imx6_esdhc_start_image(int instance); int imx8_esdhc_start_image(int instance); +int imx8_esdhc_load_piggy(int instance); int imx_image_size(void); +int piggydata_size(void); + +extern unsigned char input_data[]; +extern unsigned char input_data_end[]; #endif /* __MACH_XLOAD_H */ diff --git a/arch/arm/mach-imx/xload-common.c b/arch/arm/mach-imx/xload-common.c index c5727eba38..bd6405258e 100644 --- a/arch/arm/mach-imx/xload-common.c +++ b/arch/arm/mach-imx/xload-common.c @@ -8,3 +8,9 @@ int imx_image_size(void) /* i.MX header is 4k */ return barebox_image_size + SZ_4K; } + +int piggydata_size(void) +{ + return input_data_end - input_data; +} + |