diff options
Diffstat (limited to 'arch/arm/mach-imx')
30 files changed, 876 insertions, 418 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 3266545c266..d94b5828d0d 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -31,7 +31,7 @@ config IMX_RDC config IMX_BOOTAUX bool "Support boot auxiliary core" - depends on ARCH_MX7 || ARCH_MX6 || ARCH_VF610 || ARCH_IMX8M + depends on ARCH_MX7 || ARCH_MX6 || ARCH_VF610 || ARCH_IMX8 || ARCH_IMX8M help bootaux [addr] to boot auxiliary core. @@ -86,6 +86,7 @@ config CMD_DEKBLOB select IMX_CAAM_DEK_ENCAP if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP select IMX_OPTEE_DEK_ENCAP if ARCH_IMX8M select IMX_SECO_DEK_ENCAP if ARCH_IMX8 + select IMX_ELE_DEK_ENCAP if ARCH_IMX8ULP || ARCH_IMX9 help This enables the 'dek_blob' command which is used with the Freescale secure boot mechanism. This command encapsulates and @@ -113,6 +114,12 @@ config IMX_SECO_DEK_ENCAP This enabled the DEK blob encapsulation with the SECO API. This option is only available on imx8. +config IMX_ELE_DEK_ENCAP + bool "Support the DEK blob encapsulation with ELE" + help + This enabled the DEK blob encapsulation with the ELE API. This option + is only available on imx8ulp and imx9. + config CMD_PRIBLOB bool "Support the set_priblob_bitfield command" depends on HAS_CAAM && IMX_HAB diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 906f538259a..aebfa6517bd 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -54,7 +54,7 @@ obj-$(CONFIG_IMX_RDC) += rdc-sema.o ifneq ($(CONFIG_SPL_BUILD),y) obj-$(CONFIG_IMX_BOOTAUX) += imx_bootaux.o endif -obj-$(CONFIG_SATA) += sata.o +obj-$(CONFIG_$(SPL_)SATA) += sata.o obj-$(CONFIG_IMX_HAB) += hab.o obj-$(CONFIG_SYSCOUNTER_TIMER) += syscounter.o endif @@ -66,6 +66,11 @@ ifeq ($(SOC),$(filter $(SOC),vf610)) obj-y += ddrmc-vf610.o obj-$(CONFIG_DDRMC_VF610_CALIBRATION) += ddrmc-vf610-calibration.o endif +ifeq ($(SOC),$(filter $(SOC),imx8)) +ifneq ($(CONFIG_SPL_BUILD),y) +obj-$(CONFIG_IMX_BOOTAUX) += imx_bootaux.o +endif +endif ifneq ($(CONFIG_SPL_BUILD),y) obj-$(CONFIG_CMD_BMODE) += cmd_bmode.o obj-$(CONFIG_CMD_HDMIDETECT) += cmd_hdmidet.o diff --git a/arch/arm/mach-imx/cmd_dek.c b/arch/arm/mach-imx/cmd_dek.c index 69ed57537b3..6fa5b41fcd3 100644 --- a/arch/arm/mach-imx/cmd_dek.c +++ b/arch/arm/mach-imx/cmd_dek.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2008-2015 Freescale Semiconductor, Inc. + * Copyright 2022 NXP * * Command for encapsulating DEK blob */ @@ -20,6 +21,11 @@ #include <firmware/imx/sci/sci.h> #include <asm/mach-imx/image.h> #endif +#ifdef CONFIG_IMX_ELE_DEK_ENCAP +#include <asm/mach-imx/ele_api.h> +#include <asm/mach-imx/image.h> +#endif + #include <cpu_func.h> /** @@ -101,6 +107,7 @@ static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len) 0x0, &shm_output); if (ret < 0) { printf("Cannot register output shared memory 0x%X\n", ret); + tee_shm_free(shm_input); goto error; } @@ -122,11 +129,11 @@ static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len) if (ret < 0) printf("Cannot generate Blob with PTA DEK Blob 0x%X\n", ret); -error: /* Free shared memory */ tee_shm_free(shm_input); tee_shm_free(shm_output); +error: /* Close session */ ret = tee_close_session(dev, arg.session); if (ret < 0) @@ -154,7 +161,7 @@ error: static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len) { - sc_err_t err; + int err; sc_rm_mr_t mr_input, mr_output; struct generate_key_blob_hdr hdr; u8 in_size, out_size; @@ -283,6 +290,84 @@ error: } #endif /* CONFIG_IMX_SECO_DEK_ENCAP */ +#ifdef CONFIG_IMX_ELE_DEK_ENCAP + +#define DEK_BLOB_HDR_SIZE 8 +#define AHAB_PRIVATE_KEY 0x81 +#define AHAB_DEK_BLOB 0x01 +#define AHAB_ALG_AES 0x03 +#define AHAB_128_AES_KEY 0x10 +#define AHAB_192_AES_KEY 0x18 +#define AHAB_256_AES_KEY 0x20 + +static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len) +{ + u8 in_size, out_size; + u8 *src_ptr, *dst_ptr; + struct generate_key_blob_hdr hdr; + + /* Set sizes */ + in_size = sizeof(struct generate_key_blob_hdr) + len / 8; + out_size = BLOB_SIZE(len / 8) + DEK_BLOB_HDR_SIZE; + + /* Get src and dst virtual addresses */ + src_ptr = map_sysmem(src_addr, in_size); + dst_ptr = map_sysmem(dst_addr, out_size); + + /* Check addr input */ + if (!(src_ptr && dst_ptr)) { + debug("src_addr or dst_addr invalid\n"); + return -1; + } + + /* Build key header */ + hdr.version = 0x0; + hdr.length_lsb = in_size; + hdr.length_msb = 0x00; + hdr.tag = AHAB_PRIVATE_KEY; + hdr.flags = AHAB_DEK_BLOB; + hdr.algorithm = AHAB_ALG_AES; + hdr.mode = 0x0; /* Not used by the ELE */ + + switch (len) { + case 128: + hdr.size = AHAB_128_AES_KEY; + break; + case 192: + hdr.size = AHAB_192_AES_KEY; + break; + case 256: + hdr.size = AHAB_256_AES_KEY; + break; + default: + /* Not supported */ + debug("Invalid DEK size. Valid sizes are 128, 192 and 256b\n"); + return -1; + } + + /* Move input key and append blob header */ + memmove((void *)(src_ptr + sizeof(struct generate_key_blob_hdr)), + (void *)src_ptr, len / 8); + memcpy((void *)src_ptr, (void *)&hdr, + sizeof(struct generate_key_blob_hdr)); + + /* Flush the cache */ + flush_dcache_range(src_addr, src_addr + in_size); + flush_dcache_range((ulong)dst_ptr, (ulong)(dst_ptr + + roundup(out_size, ARCH_DMA_MINALIGN))); + + /* Call ELE */ + if (ele_generate_dek_blob(0x00, src_addr, dst_addr, out_size)) + return -1; + + /* Invalidate output buffer */ + invalidate_dcache_range((ulong)dst_ptr, (ulong)(dst_ptr + + roundup(out_size, ARCH_DMA_MINALIGN))); + + return 0; +} +#endif /* CONFIG_IMX_ELE_DEK_ENCAP */ + /** * do_dek_blob() - Handle the "dek_blob" command-line command * @cmdtp: Command data struct pointer diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 702cfc33275..488638c9058 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -510,3 +510,7 @@ char nxp_board_rev_string(void) return (*rev + nxp_board_rev() - 1); } #endif + +__weak void reset_cpu(void) +{ +} diff --git a/arch/arm/mach-imx/ele_ahab.c b/arch/arm/mach-imx/ele_ahab.c index 99fc5402719..785b0d6ec3c 100644 --- a/arch/arm/mach-imx/ele_ahab.c +++ b/arch/arm/mach-imx/ele_ahab.c @@ -7,14 +7,13 @@ #include <command.h> #include <errno.h> #include <asm/io.h> -#include <asm/mach-imx/s400_api.h> +#include <asm/mach-imx/ele_api.h> #include <asm/mach-imx/sys_proto.h> #include <asm/arch-imx/cpu.h> #include <asm/arch/sys_proto.h> #include <asm/mach-imx/image.h> #include <console.h> #include <cpu_func.h> -#include <asm/mach-imx/ahab.h> #include <asm/global_data.h> DECLARE_GLOBAL_DATA_PTR; @@ -267,7 +266,7 @@ int ahab_auth_cntr_hdr(struct container_hdr *container, u16 length) flush_dcache_range(IMG_CONTAINER_BASE, IMG_CONTAINER_BASE + ALIGN(length, CONFIG_SYS_CACHELINE_SIZE) - 1); - err = ahab_auth_oem_ctnr(IMG_CONTAINER_BASE, &resp); + err = ele_auth_oem_ctnr(IMG_CONTAINER_BASE, &resp); if (err) { printf("Authenticate container hdr failed, return %d, resp 0x%x\n", err, resp); @@ -282,7 +281,7 @@ int ahab_auth_release(void) int err; u32 resp; - err = ahab_release_container(&resp); + err = ele_release_container(&resp); if (err) { printf("Error: release container failed, resp 0x%x!\n", resp); display_ahab_auth_ind(resp); @@ -296,7 +295,7 @@ int ahab_verify_cntr_image(struct boot_img_t *img, int image_index) int err; u32 resp; - err = ahab_verify_image(image_index, &resp); + err = ele_verify_image(image_index, &resp); if (err) { printf("Authenticate img %d failed, return %d, resp 0x%x\n", image_index, err, resp); @@ -403,7 +402,7 @@ static int do_authenticate(struct cmd_tbl *cmdtp, int flag, int argc, if (argc < 2) return CMD_RET_USAGE; - addr = simple_strtoul(argv[1], NULL, 16); + addr = hextoul(argv[1], NULL); printf("Authenticate OS container at 0x%lx\n", addr); @@ -485,7 +484,7 @@ static int do_ahab_close(struct cmd_tbl *cmdtp, int flag, int argc, return -EPERM; } - err = ahab_forward_lifecycle(8, &resp); + err = ele_forward_lifecycle(8, &resp); if (err != 0) { printf("Error in forward lifecycle to OEM closed\n"); return -EIO; @@ -502,7 +501,7 @@ int ahab_dump(void) int ret, i = 0; do { - ret = ahab_dump_buffer(buffer, 32); + ret = ele_dump_buffer(buffer, 32); if (ret < 0) { printf("Error in dump AHAB log\n"); return -EIO; @@ -547,7 +546,7 @@ static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc, char *const display_life_cycle(lc); - ret = ahab_get_events(events, &cnt, NULL); + ret = ele_get_events(events, &cnt, NULL); if (ret) { printf("Get ELE EVENTS error %d\n", ret); return CMD_RET_FAILURE; @@ -564,6 +563,68 @@ static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc, char *const return 0; } +static int do_sec_fuse_prog(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + ulong addr; + u32 header, response; + + if (argc < 2) + return CMD_RET_USAGE; + + addr = hextoul(argv[1], NULL); + header = *(u32 *)addr; + + if ((header & 0xff0000ff) != 0x89000000) { + printf("Wrong Signed message block format, header 0x%x\n", header); + return CMD_RET_FAILURE; + } + + header = (header & 0xffff00) >> 8; + + printf("Signed Message block at 0x%lx, size 0x%x\n", addr, header); + flush_dcache_range(addr, addr + header - 1); + + if (ele_write_secure_fuse(addr, &response)) { + printf("Program secure fuse failed, response 0x%x\n", response); + return CMD_RET_FAILURE; + } + + printf("Program secure fuse completed, response 0x%x\n", response); + + return CMD_RET_SUCCESS; +} + +static int do_ahab_return_lifecycle(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + ulong addr; + u32 header, response; + + if (argc < 2) + return CMD_RET_USAGE; + + addr = hextoul(argv[1], NULL); + header = *(u32 *)addr; + + if ((header & 0xff0000ff) != 0x89000000) { + printf("Wrong Signed message block format, header 0x%x\n", header); + return CMD_RET_FAILURE; + } + + header = (header & 0xffff00) >> 8; + + printf("Signed Message block at 0x%lx, size 0x%x\n", addr, header); + flush_dcache_range(addr, addr + header - 1); + + if (ele_return_lifecycle_update(addr, &response)) { + printf("Return lifecycle failed, response 0x%x\n", response); + return CMD_RET_FAILURE; + } + + printf("Return lifecycle completed, response 0x%x\n", response); + + return CMD_RET_SUCCESS; +} + U_BOOT_CMD(auth_cntr, CONFIG_SYS_MAXARGS, 1, do_authenticate, "autenticate OS container via AHAB", "addr\n" @@ -584,3 +645,15 @@ U_BOOT_CMD(ahab_status, CONFIG_SYS_MAXARGS, 1, do_ahab_status, "display AHAB lifecycle only", "" ); + +U_BOOT_CMD(ahab_sec_fuse_prog, CONFIG_SYS_MAXARGS, 1, do_sec_fuse_prog, + "Program secure fuse via signed message block", + "addr\n" + "addr - Signed message block for secure fuse\n" +); + +U_BOOT_CMD(ahab_return_lifecycle, CONFIG_SYS_MAXARGS, 1, do_ahab_return_lifecycle, + "Return lifecycle to OEM field return via signed message block", + "addr\n" + "addr - Return lifecycle message block signed by OEM SRK\n" +); diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index c6747b257c4..b3ef36c7973 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -289,9 +289,10 @@ static char *rsn_str[] = { }; static char *sts_str[] = { - "STS = HAB_SUCCESS (0xF0)\n", + "STS = HAB_STS_ANY (0x00)\n", "STS = HAB_FAILURE (0x33)\n", "STS = HAB_WARNING (0x69)\n", + "STS = HAB_SUCCESS (0xF0)\n", "STS = INVALID\n", NULL }; @@ -336,8 +337,7 @@ static uint8_t hab_statuses[5] = { HAB_STS_ANY, HAB_FAILURE, HAB_WARNING, - HAB_SUCCESS, - -1 + HAB_SUCCESS }; static uint8_t hab_reasons[26] = { @@ -365,8 +365,7 @@ static uint8_t hab_reasons[26] = { HAB_UNS_ITEM, HAB_UNS_KEY, HAB_UNS_PROTOCOL, - HAB_UNS_STATE, - -1 + HAB_UNS_STATE }; static uint8_t hab_contexts[12] = { @@ -380,8 +379,7 @@ static uint8_t hab_contexts[12] = { HAB_CTX_COMMAND, HAB_CTX_AUT_DAT, HAB_CTX_ASSERT, - HAB_CTX_EXIT, - -1 + HAB_CTX_EXIT }; static uint8_t hab_engines[16] = { @@ -399,30 +397,35 @@ static uint8_t hab_engines[16] = { HAB_ENG_ROM, HAB_ENG_HDCP, HAB_ENG_RTL, - HAB_ENG_SW, - -1 + HAB_ENG_SW }; -static inline uint8_t get_idx(uint8_t *list, uint8_t tgt) +static inline u32 get_idx(u8 *list, u8 tgt, u32 size) { - uint8_t idx = 0; - uint8_t element = list[idx]; - while (element != -1) { + u32 idx = 0; + u8 element; + + while (idx < size) { + element = list[idx]; if (element == tgt) return idx; - element = list[++idx]; + ++idx; } - return -1; + return idx; } static void process_event_record(uint8_t *event_data, size_t bytes) { struct record *rec = (struct record *)event_data; - printf("\n\n%s", sts_str[get_idx(hab_statuses, rec->contents[0])]); - printf("%s", rsn_str[get_idx(hab_reasons, rec->contents[1])]); - printf("%s", ctx_str[get_idx(hab_contexts, rec->contents[2])]); - printf("%s", eng_str[get_idx(hab_engines, rec->contents[3])]); + printf("\n\n%s", sts_str[get_idx(hab_statuses, rec->contents[0], + ARRAY_SIZE(hab_statuses))]); + printf("%s", rsn_str[get_idx(hab_reasons, rec->contents[1], + ARRAY_SIZE(hab_reasons))]); + printf("%s", ctx_str[get_idx(hab_contexts, rec->contents[2], + ARRAY_SIZE(hab_contexts))]); + printf("%s", eng_str[get_idx(hab_engines, rec->contents[3], + ARRAY_SIZE(hab_engines))]); } static void display_event(uint8_t *event_data, size_t bytes) @@ -932,10 +935,10 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size, printf("ivt entry = 0x%08x, dcd = 0x%08x, csf = 0x%08x\n", ivt->entry, ivt->dcd, ivt->csf); puts("Dumping IVT\n"); - print_buffer(ivt_addr, (void *)(ivt_addr), 4, 0x8, 0); + print_buffer(ivt_addr, (void *)(uintptr_t)(ivt_addr), 4, 0x8, 0); puts("Dumping CSF Header\n"); - print_buffer(ivt->csf, (void *)(ivt->csf), 4, 0x10, 0); + print_buffer(ivt->csf, (void *)(uintptr_t)(ivt->csf), 4, 0x10, 0); #if !defined(CONFIG_SPL_BUILD) get_hab_status(); @@ -944,7 +947,7 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size, puts("\nCalling authenticate_image in ROM\n"); printf("\tivt_offset = 0x%x\n", ivt_offset); printf("\tstart = 0x%08lx\n", start); - printf("\tbytes = 0x%x\n", bytes); + printf("\tbytes = 0x%lx\n", (ulong)bytes); #endif #ifndef CONFIG_ARM64 diff --git a/arch/arm/mach-imx/image-container.c b/arch/arm/mach-imx/image-container.c index 5b059a64292..5f188ab32d1 100644 --- a/arch/arm/mach-imx/image-container.c +++ b/arch/arm/mach-imx/image-container.c @@ -22,6 +22,25 @@ #define QSPI_NOR_DEV 3 #define ROM_API_DEV 4 +/* The unit of second image offset number which provision by the fuse bits */ +#define SND_IMG_OFF_UNIT (0x100000UL) + +/* + * If num = 0, off = (2 ^ 2) * 1MB + * else If num = 2, off = (2 ^ 0) * 1MB + * else off = (2 ^ num) * 1MB + */ +#define SND_IMG_NUM_TO_OFF(num) \ + ((1UL << ((0 == (num)) ? 2 : (2 == (num)) ? 0 : (num))) * SND_IMG_OFF_UNIT) + +#define GET_SND_IMG_NUM(fuse) (((fuse) >> 24) & 0x1F) + +#if defined(CONFIG_IMX8QM) +#define FUSE_IMG_SET_OFF_WORD 464 +#elif defined(CONFIG_IMX8QXP) +#define FUSE_IMG_SET_OFF_WORD 720 +#endif + int get_container_size(ulong addr, u16 *header_length) { struct container_hdr *phdr; @@ -31,7 +50,7 @@ int get_container_size(ulong addr, u16 *header_length) u32 max_offset = 0, img_end; phdr = (struct container_hdr *)addr; - if (phdr->tag != 0x87 && phdr->version != 0x0) { + if (phdr->tag != 0x87 || phdr->version != 0x0) { debug("Wrong container header\n"); return -EFAULT; } @@ -136,15 +155,53 @@ static int get_dev_container_size(void *dev, int dev_type, unsigned long offset, return ret; } +static bool check_secondary_cnt_set(unsigned long *set_off) +{ +#if IS_ENABLED(CONFIG_ARCH_IMX8) + int ret; + u8 set_id = 1; + u32 fuse_val = 0; + + if (!(is_imx8qxp() && is_soc_rev(CHIP_REV_B))) { + ret = sc_misc_get_boot_container(-1, &set_id); + if (ret) + return false; + /* Secondary boot */ + if (set_id == 2) { + ret = sc_misc_otp_fuse_read(-1, FUSE_IMG_SET_OFF_WORD, &fuse_val); + if (!ret) { + if (set_off) + *set_off = SND_IMG_NUM_TO_OFF(GET_SND_IMG_NUM(fuse_val)); + return true; + } + } + } +#endif + + return false; +} + static unsigned long get_boot_device_offset(void *dev, int dev_type) { - unsigned long offset = 0; + unsigned long offset = 0, sec_set_off = 0; + bool sec_boot = false; + + if (dev_type == ROM_API_DEV) { + offset = (unsigned long)dev; + return offset; + } + + sec_boot = check_secondary_cnt_set(&sec_set_off); + if (sec_boot) + printf("Secondary set selected\n"); + else + printf("Primary set selected\n"); if (dev_type == MMC_DEV) { struct mmc *mmc = (struct mmc *)dev; if (IS_SD(mmc) || mmc->part_config == MMCPART_NOAVAILABLE) { - offset = CONTAINER_HDR_MMCSD_OFFSET; + offset = sec_boot ? sec_set_off : CONTAINER_HDR_MMCSD_OFFSET; } else { u8 part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config); @@ -154,19 +211,23 @@ static unsigned long get_boot_device_offset(void *dev, int dev_type) else offset = CONTAINER_HDR_EMMC_OFFSET; } else { - offset = CONTAINER_HDR_MMCSD_OFFSET; + offset = sec_boot ? sec_set_off : CONTAINER_HDR_MMCSD_OFFSET; } } } else if (dev_type == QSPI_DEV) { - offset = CONTAINER_HDR_QSPI_OFFSET; + offset = sec_boot ? (sec_set_off + CONTAINER_HDR_QSPI_OFFSET) : + CONTAINER_HDR_QSPI_OFFSET; } else if (dev_type == NAND_DEV) { - offset = CONTAINER_HDR_NAND_OFFSET; + offset = sec_boot ? (sec_set_off + CONTAINER_HDR_NAND_OFFSET) : + CONTAINER_HDR_NAND_OFFSET; } else if (dev_type == QSPI_NOR_DEV) { offset = CONTAINER_HDR_QSPI_OFFSET + 0x08000000; - } else if (dev_type == ROM_API_DEV) { - offset = (unsigned long)dev; + } else { + printf("Not supported dev_type: %d\n", dev_type); } + debug("container set offset 0x%lx\n", offset); + return offset; } @@ -227,6 +288,25 @@ unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc, return end / mmc->read_bl_len; } + +int spl_mmc_emmc_boot_partition(struct mmc *mmc) +{ + int part; + + part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config); + if (part == 1 || part == 2) { + unsigned long sec_set_off = 0; + bool sec_boot = false; + + sec_boot = check_secondary_cnt_set(&sec_set_off); + if (sec_boot) + part = (part == 1) ? 2 : 1; + } else if (part == 7) { + part = 0; + } + + return part; +} #endif #ifdef CONFIG_SPL_NAND_SUPPORT diff --git a/arch/arm/mach-imx/imx8/ahab.c b/arch/arm/mach-imx/imx8/ahab.c index 9addb824b6d..b58b14ca9b4 100644 --- a/arch/arm/mach-imx/imx8/ahab.c +++ b/arch/arm/mach-imx/imx8/ahab.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2018-2019 NXP + * Copyright 2018-2019, 2022 NXP */ #include <common.h> @@ -16,6 +16,8 @@ #include <asm/mach-imx/image.h> #include <console.h> #include <cpu_func.h> +#include "u-boot/sha256.h" +#include <asm/mach-imx/ahab.h> DECLARE_GLOBAL_DATA_PTR; @@ -24,6 +26,86 @@ DECLARE_GLOBAL_DATA_PTR; #define SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE (0x60000000UL) #define SECO_PT 2U +#define AHAB_HASH_TYPE_MASK 0x00000700 +#define AHAB_HASH_TYPE_SHA256 0 + +int ahab_auth_cntr_hdr(struct container_hdr *container, u16 length) +{ + int err; + + memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)container, + ALIGN(length, CONFIG_SYS_CACHELINE_SIZE)); + + err = sc_seco_authenticate(-1, SC_SECO_AUTH_CONTAINER, + SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE); + if (err) + printf("Authenticate container hdr failed, return %d\n", err); + + return err; +} + +int ahab_auth_release(void) +{ + int err; + + err = sc_seco_authenticate(-1, SC_SECO_REL_CONTAINER, 0); + if (err) + printf("Error: release container failed!\n"); + + return err; +} + +int ahab_verify_cntr_image(struct boot_img_t *img, int image_index) +{ + sc_faddr_t start, end; + sc_rm_mr_t mr; + int err; + int ret = 0; + + debug("img %d, dst 0x%llx, src 0x%x, size 0x%x\n", + image_index, img->dst, img->offset, img->size); + + /* Find the memreg and set permission for seco pt */ + err = sc_rm_find_memreg(-1, &mr, + img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1), + ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE) - 1); + + if (err) { + printf("Error: can't find memreg for image load address 0x%llx, error %d\n", + img->dst, err); + return -ENOMEM; + } + + err = sc_rm_get_memreg_info(-1, mr, &start, &end); + if (!err) + debug("memreg %u 0x%llx -- 0x%llx\n", mr, start, end); + + err = sc_rm_set_memreg_permissions(-1, mr, + SECO_PT, SC_RM_PERM_FULL); + if (err) { + printf("Set permission failed for img %d, error %d\n", + image_index, err); + return -EPERM; + } + + err = sc_seco_authenticate(-1, SC_SECO_VERIFY_IMAGE, + 1 << image_index); + if (err) { + printf("Authenticate img %d failed, return %d\n", + image_index, err); + ret = -EIO; + } + + err = sc_rm_set_memreg_permissions(-1, mr, + SECO_PT, SC_RM_PERM_NONE); + if (err) { + printf("Remove permission failed for img %d, error %d\n", + image_index, err); + ret = -EPERM; + } + + return ret; +} static inline bool check_in_dram(ulong addr) { @@ -46,11 +128,12 @@ int authenticate_os_container(ulong addr) struct container_hdr *phdr; int i, ret = 0; int err; - sc_rm_mr_t mr; - sc_faddr_t start, end; u16 length; struct boot_img_t *img; unsigned long s, e; +#ifdef CONFIG_ARMV8_CE_SHA256 + u8 hash_value[SHA256_SUM_LEN]; +#endif if (addr % 4) { puts("Error: Image's address is not 4 byte aligned\n"); @@ -76,14 +159,9 @@ int authenticate_os_container(ulong addr) length = phdr->length_lsb + (phdr->length_msb << 8); debug("container length %u\n", length); - memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)addr, - ALIGN(length, CONFIG_SYS_CACHELINE_SIZE)); - err = sc_seco_authenticate(-1, SC_SECO_AUTH_CONTAINER, - SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE); + err = ahab_auth_cntr_hdr(phdr, length); if (err) { - printf("Authenticate container hdr failed, return %d\n", - err); ret = -EIO; goto exit; } @@ -105,50 +183,27 @@ int authenticate_os_container(ulong addr) flush_dcache_range(s, e); - /* Find the memreg and set permission for seco pt */ - err = sc_rm_find_memreg(-1, &mr, s, e); - if (err) { - printf("Error: can't find memreg for image load address 0x%llx, error %d\n", img->dst, err); - ret = -ENOMEM; - goto exit; - } - - err = sc_rm_get_memreg_info(-1, mr, &start, &end); - if (!err) - debug("memreg %u 0x%llx -- 0x%llx\n", mr, start, end); - - err = sc_rm_set_memreg_permissions(-1, mr, SECO_PT, - SC_RM_PERM_FULL); - if (err) { - printf("Set permission failed for img %d, error %d\n", - i, err); - ret = -EPERM; - goto exit; - } - - err = sc_seco_authenticate(-1, SC_SECO_VERIFY_IMAGE, - (1 << i)); - if (err) { - printf("Authenticate img %d failed, return %d\n", - i, err); - ret = -EIO; +#ifdef CONFIG_ARMV8_CE_SHA256 + if (((img->hab_flags & AHAB_HASH_TYPE_MASK) >> 8) == AHAB_HASH_TYPE_SHA256) { + sha256_csum_wd((void *)img->dst, img->size, hash_value, CHUNKSZ_SHA256); + err = memcmp(&img->hash, &hash_value, SHA256_SUM_LEN); + if (err) { + printf("img %d hash comparison failed, error %d\n", i, err); + ret = -EIO; + goto exit; + } + } else { +#endif + ret = ahab_verify_cntr_image(img, i); + if (ret) + goto exit; +#ifdef CONFIG_ARMV8_CE_SHA256 } - - err = sc_rm_set_memreg_permissions(-1, mr, SECO_PT, - SC_RM_PERM_NONE); - if (err) { - printf("Remove permission failed for img %d, err %d\n", - i, err); - ret = -EPERM; - } - - if (ret) - goto exit; +#endif } exit: - if (sc_seco_authenticate(-1, SC_SECO_REL_CONTAINER, 0) != SC_ERR_NONE) - printf("Error: release container failed!\n"); + ahab_auth_release(); return ret; } @@ -263,7 +318,7 @@ static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc, u16 lc; err = sc_seco_chip_info(-1, &lc, NULL, NULL, NULL); - if (err != SC_ERR_NONE) { + if (err) { printf("Error in get lifecycle\n"); return -EIO; } @@ -271,7 +326,7 @@ static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc, display_life_cycle(lc); err = sc_seco_get_event(-1, idx, &event); - while (err == SC_ERR_NONE) { + while (!err) { printf("SECO Event[%u] = 0x%08X\n", idx, event); display_ahab_auth_event(event); @@ -312,7 +367,7 @@ static int do_ahab_close(struct cmd_tbl *cmdtp, int flag, int argc, return -EACCES; err = sc_seco_chip_info(-1, &lc, NULL, NULL, NULL); - if (err != SC_ERR_NONE) { + if (err) { printf("Error in get lifecycle\n"); return -EIO; } @@ -324,7 +379,7 @@ static int do_ahab_close(struct cmd_tbl *cmdtp, int flag, int argc, } err = sc_seco_forward_lifecycle(-1, 16); - if (err != SC_ERR_NONE) { + if (err) { printf("Error in forward lifecycle to OEM closed\n"); return -EIO; } diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index 7b292c07ef9..c62357044e0 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -26,6 +26,8 @@ #include <asm/armv8/mmu.h> #include <asm/setup.h> #include <asm/mach-imx/boot_mode.h> +#include <power-domain.h> +#include <elf.h> #include <spl.h> DECLARE_GLOBAL_DATA_PTR; @@ -107,6 +109,178 @@ int arch_misc_init(void) } #endif +#ifdef CONFIG_IMX_BOOTAUX + +#ifdef CONFIG_IMX8QM +int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) +{ + sc_rsrc_t core_rsrc, mu_rsrc; + sc_faddr_t tcml_addr; + u32 tcml_size = SZ_128K; + ulong addr; + + switch (core_id) { + case 0: + core_rsrc = SC_R_M4_0_PID0; + tcml_addr = 0x34FE0000; + mu_rsrc = SC_R_M4_0_MU_1A; + break; + case 1: + core_rsrc = SC_R_M4_1_PID0; + tcml_addr = 0x38FE0000; + mu_rsrc = SC_R_M4_1_MU_1A; + break; + default: + printf("Not support this core boot up, ID:%u\n", core_id); + return -EINVAL; + } + + addr = (sc_faddr_t)boot_private_data; + + if (addr >= tcml_addr && addr <= tcml_addr + tcml_size) { + printf("Wrong image address 0x%lx, should not in TCML\n", + addr); + return -EINVAL; + } + + printf("Power on M4 and MU\n"); + + if (sc_pm_set_resource_power_mode(-1, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) + return -EIO; + + if (sc_pm_set_resource_power_mode(-1, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) + return -EIO; + + printf("Copy M4 image from 0x%lx to TCML 0x%lx\n", addr, (ulong)tcml_addr); + + if (addr != tcml_addr) + memcpy((void *)tcml_addr, (void *)addr, tcml_size); + + printf("Start M4 %u\n", core_id); + if (sc_pm_cpu_start(-1, core_rsrc, true, tcml_addr) != SC_ERR_NONE) + return -EIO; + + printf("bootaux complete\n"); + return 0; +} +#endif + +#ifdef CONFIG_IMX8QXP +int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) +{ + sc_rsrc_t core_rsrc, mu_rsrc = SC_R_NONE; + sc_faddr_t aux_core_ram; + u32 size; + ulong addr; + + switch (core_id) { + case 0: + core_rsrc = SC_R_M4_0_PID0; + aux_core_ram = 0x34FE0000; + mu_rsrc = SC_R_M4_0_MU_1A; + size = SZ_128K; + break; + case 1: + core_rsrc = SC_R_DSP; + aux_core_ram = 0x596f8000; + size = SZ_2K; + break; + default: + printf("Not support this core boot up, ID:%u\n", core_id); + return -EINVAL; + } + + addr = (sc_faddr_t)boot_private_data; + + if (addr >= aux_core_ram && addr <= aux_core_ram + size) { + printf("Wrong image address 0x%lx, should not in aux core ram\n", + addr); + return -EINVAL; + } + + printf("Power on aux core %d\n", core_id); + + if (sc_pm_set_resource_power_mode(-1, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) + return -EIO; + + if (mu_rsrc != SC_R_NONE) { + if (sc_pm_set_resource_power_mode(-1, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) + return -EIO; + } + + if (core_id == 1) { + struct power_domain pd; + + if (sc_pm_clock_enable(-1, core_rsrc, SC_PM_CLK_PER, true, false) != SC_ERR_NONE) { + printf("Error enable clock\n"); + return -EIO; + } + + if (!power_domain_lookup_name("audio_sai0", &pd)) { + if (power_domain_on(&pd)) { + printf("Error power on SAI0\n"); + return -EIO; + } + } + + if (!power_domain_lookup_name("audio_ocram", &pd)) { + if (power_domain_on(&pd)) { + printf("Error power on HIFI RAM\n"); + return -EIO; + } + } + } + + printf("Copy image from 0x%lx to 0x%lx\n", addr, (ulong)aux_core_ram); + if (core_id == 0) { + /* M4 use bin file */ + memcpy((void *)aux_core_ram, (void *)addr, size); + } else { + /* HIFI use elf file */ + if (!valid_elf_image(addr)) + return -1; + addr = load_elf_image_shdr(addr); + } + + printf("Start %s\n", core_id == 0 ? "M4" : "HIFI"); + + if (sc_pm_cpu_start(-1, core_rsrc, true, aux_core_ram) != SC_ERR_NONE) + return -EIO; + + printf("bootaux complete\n"); + return 0; +} +#endif + +int arch_auxiliary_core_check_up(u32 core_id) +{ + sc_rsrc_t core_rsrc; + sc_pm_power_mode_t power_mode; + + switch (core_id) { + case 0: + core_rsrc = SC_R_M4_0_PID0; + break; +#ifdef CONFIG_IMX8QM + case 1: + core_rsrc = SC_R_M4_1_PID0; + break; +#endif + default: + printf("Not support this core, ID:%u\n", core_id); + return 0; + } + + if (sc_pm_get_resource_power_mode(-1, core_rsrc, &power_mode) != SC_ERR_NONE) + return 0; + + if (power_mode != SC_PM_PW_MODE_OFF) + return 1; + + return 0; +} +#endif + int print_bootinfo(void) { enum boot_device bt_dev = get_boot_device(); @@ -195,7 +369,7 @@ enum boot_device get_boot_device(void) #define FUSE_UNIQUE_ID_WORD1 17 void get_board_serial(struct tag_serialnr *serialnr) { - sc_err_t err; + int err; u32 val1 = 0, val2 = 0; u32 word1, word2; @@ -206,13 +380,13 @@ void get_board_serial(struct tag_serialnr *serialnr) word2 = FUSE_UNIQUE_ID_WORD1; err = sc_misc_otp_fuse_read(-1, word1, &val1); - if (err != SC_ERR_NONE) { + if (err) { printf("%s fuse %d read error: %d\n", __func__, word1, err); return; } err = sc_misc_otp_fuse_read(-1, word2, &val2); - if (err != SC_ERR_NONE) { + if (err) { printf("%s fuse %d read error: %d\n", __func__, word2, err); return; } diff --git a/arch/arm/mach-imx/imx8/fdt.c b/arch/arm/mach-imx/imx8/fdt.c index 02b3ee5c111..491c8bb8c75 100644 --- a/arch/arm/mach-imx/imx8/fdt.c +++ b/arch/arm/mach-imx/imx8/fdt.c @@ -110,7 +110,7 @@ static int config_smmu_resource_sid(int rsrc, int sid) err = sc_rm_set_master_sid(-1, rsrc, sid); debug("set_master_sid rsrc=%d sid=0x%x err=%d\n", rsrc, sid, err); - if (err != SC_ERR_NONE) { + if (err) { if (!check_owned_resource(rsrc)) { printf("%s rsrc[%d] not owned\n", __func__, rsrc); return -1; diff --git a/arch/arm/mach-imx/imx8/snvs_security_sc.c b/arch/arm/mach-imx/imx8/snvs_security_sc.c index d7b20a1fcbf..1eaa68f8d5f 100644 --- a/arch/arm/mach-imx/imx8/snvs_security_sc.c +++ b/arch/arm/mach-imx/imx8/snvs_security_sc.c @@ -286,16 +286,15 @@ static int check_write_secvio_config(u32 id, u32 *_p1, u32 *_p2, u32 *_p3, u32 *_p4, u32 *_p5, u32 _cnt) { - int scierr = 0; + int err; u32 d1 = ptr_value(_p1); u32 d2 = ptr_value(_p2); u32 d3 = ptr_value(_p3); u32 d4 = ptr_value(_p4); u32 d5 = ptr_value(_p5); - scierr = sc_seco_secvio_config(-1, id, SC_WRITE_CONF, &d1, &d2, &d3, - &d4, &d4, _cnt); - if (scierr != SC_ERR_NONE) { + err = sc_seco_secvio_config(-1, id, SC_WRITE_CONF, &d1, &d2, &d3, &d4, &d4, _cnt); + if (err) { printf("Failed to set secvio configuration\n"); debug("Failed to set conf id 0x%x with values ", id); debug("0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x (cnt: %d)\n", @@ -315,7 +314,7 @@ static int check_write_secvio_config(u32 id, u32 *_p1, u32 *_p2, *(u32 *)_p5 = d5; exit: - return scierr; + return err; } #define SC_CHECK_WRITE1(id, _p1) \ @@ -323,7 +322,7 @@ exit: static int apply_snvs_config(struct snvs_security_sc_conf *cnf) { - int scierr = 0; + int err = 0; debug("%s\n", __func__); @@ -365,92 +364,88 @@ static int apply_snvs_config(struct snvs_security_sc_conf *cnf) cnf->lp.act_tamper_routing_ctl1, cnf->lp.act_tamper_routing_ctl2); - scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_filt_cfg), - &cnf->lp.tamper_filt_cfg, - &cnf->lp.tamper_filt1_cfg, - &cnf->lp.tamper_filt2_cfg, NULL, - NULL, 3); - if (scierr != SC_ERR_NONE) + err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_filt_cfg), + &cnf->lp.tamper_filt_cfg, + &cnf->lp.tamper_filt1_cfg, + &cnf->lp.tamper_filt2_cfg, + NULL, NULL, 3); + if (err) goto exit; /* Configure AT */ - scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper1_cfg), - &cnf->lp.act_tamper1_cfg, - &cnf->lp.act_tamper2_cfg, - &cnf->lp.act_tamper2_cfg, - &cnf->lp.act_tamper2_cfg, - &cnf->lp.act_tamper2_cfg, 5); - if (scierr != SC_ERR_NONE) + err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper1_cfg), + &cnf->lp.act_tamper1_cfg, + &cnf->lp.act_tamper2_cfg, + &cnf->lp.act_tamper2_cfg, + &cnf->lp.act_tamper2_cfg, + &cnf->lp.act_tamper2_cfg, 5); + if (err) goto exit; /* Configure AT routing */ - scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper_routing_ctl1), - &cnf->lp.act_tamper_routing_ctl1, - &cnf->lp.act_tamper_routing_ctl2, - NULL, NULL, NULL, 2); - if (scierr != SC_ERR_NONE) + err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper_routing_ctl1), + &cnf->lp.act_tamper_routing_ctl1, + &cnf->lp.act_tamper_routing_ctl2, + NULL, NULL, NULL, 2); + if (err) goto exit; /* Configure AT frequency */ - scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_clk_ctl), - &cnf->lp.act_tamper_clk_ctl); - if (scierr != SC_ERR_NONE) + err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_clk_ctl), + &cnf->lp.act_tamper_clk_ctl); + if (err) goto exit; /* Activate the ATs */ - scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_ctl), - &cnf->lp.act_tamper_ctl); - if (scierr != SC_ERR_NONE) + err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_ctl), &cnf->lp.act_tamper_ctl); + if (err) goto exit; /* Activate the detectors */ - scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_cfg), - &cnf->lp.tamper_det_cfg, - &cnf->lp.tamper_det_cfg2, NULL, NULL, - NULL, 2); - if (scierr != SC_ERR_NONE) + err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_cfg), + &cnf->lp.tamper_det_cfg, + &cnf->lp.tamper_det_cfg2, NULL, NULL, NULL, 2); + if (err) goto exit; /* Configure LP secvio */ - scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.secvio_ctl), - &cnf->lp.secvio_ctl); - if (scierr != SC_ERR_NONE) + err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.secvio_ctl), &cnf->lp.secvio_ctl); + if (err) goto exit; /* Configure HP secvio */ - scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.secvio_ctl), - &cnf->hp.secvio_ctl); - if (scierr != SC_ERR_NONE) + err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.secvio_ctl), &cnf->hp.secvio_ctl); + if (err) goto exit; /* Lock access */ - scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.lock), &cnf->hp.lock); - if (scierr != SC_ERR_NONE) + err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.lock), &cnf->hp.lock); + if (err) goto exit; - scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.lock), &cnf->lp.lock); - if (scierr != SC_ERR_NONE) + err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.lock), &cnf->lp.lock); + if (err) goto exit; exit: - return (scierr == SC_ERR_NONE) ? 0 : -EIO; + return err; } static int dgo_write(u32 _id, u8 _access, u32 *_pdata) { - int scierr = sc_seco_secvio_dgo_config(-1, _id, _access, _pdata); + int err = sc_seco_secvio_dgo_config(-1, _id, _access, _pdata); - if (scierr != SC_ERR_NONE) { + if (err) { printf("Failed to set dgo configuration\n"); debug("Failed to set conf id 0x%x : 0x%.8x", _id, *_pdata); } - return scierr; + return err; } static int apply_snvs_dgo_config(struct snvs_dgo_conf *cnf) { - int scierr = 0; + int err; debug("%s\n", __func__); @@ -468,50 +463,50 @@ static int apply_snvs_dgo_config(struct snvs_dgo_conf *cnf) cnf->tamper_misc_ctl, cnf->tamper_core_volt_mon_ctl); - dgo_write(0x04, 1, &cnf->tamper_offset_ctl); - if (scierr != SC_ERR_NONE) + err = dgo_write(0x04, 1, &cnf->tamper_offset_ctl); + if (err) goto exit; - dgo_write(0x14, 1, &cnf->tamper_pull_ctl); - if (scierr != SC_ERR_NONE) + err = dgo_write(0x14, 1, &cnf->tamper_pull_ctl); + if (err) goto exit; - dgo_write(0x24, 1, &cnf->tamper_ana_test_ctl); - if (scierr != SC_ERR_NONE) + err = dgo_write(0x24, 1, &cnf->tamper_ana_test_ctl); + if (err) goto exit; - dgo_write(0x34, 1, &cnf->tamper_sensor_trim_ctl); - if (scierr != SC_ERR_NONE) + err = dgo_write(0x34, 1, &cnf->tamper_sensor_trim_ctl); + if (err) goto exit; - dgo_write(0x54, 1, &cnf->tamper_core_volt_mon_ctl); - if (scierr != SC_ERR_NONE) + err = dgo_write(0x54, 1, &cnf->tamper_core_volt_mon_ctl); + if (err) goto exit; /* Last as it could lock the writes */ - dgo_write(0x44, 1, &cnf->tamper_misc_ctl); - if (scierr != SC_ERR_NONE) + err = dgo_write(0x44, 1, &cnf->tamper_misc_ctl); + if (err) goto exit; exit: - return (scierr == SC_ERR_NONE) ? 0 : -EIO; + return err; } static int pad_write(u32 _pad, u32 _value) { - int scierr = sc_pad_set(-1, _pad, _value); + int err = sc_pad_set(-1, _pad, _value); - if (scierr != SC_ERR_NONE) { + if (err) { printf("Failed to set pad configuration\n"); debug("Failed to set conf pad 0x%x : 0x%.8x", _pad, _value); } - return scierr; + return err; } static int apply_tamper_pin_list_config(struct tamper_pin_cfg *confs, u32 size) { - int scierr = 0; + int err = 0; u32 idx; debug("%s\n", __func__); @@ -519,13 +514,13 @@ static int apply_tamper_pin_list_config(struct tamper_pin_cfg *confs, u32 size) for (idx = 0; idx < size; idx++) { debug("\t idx %d: pad %d: 0x%.8x\n", idx, confs[idx].pad, confs[idx].mux_conf); - pad_write(confs[idx].pad, 3 << 30 | confs[idx].mux_conf); - if (scierr != SC_ERR_NONE) + err = pad_write(confs[idx].pad, 3 << 30 | confs[idx].mux_conf); + if (err) goto exit; } exit: - return (scierr == SC_ERR_NONE) ? 0 : -EIO; + return err; } int examples(void) @@ -753,7 +748,7 @@ static char snvs_clear_status_help_text[] = static int do_snvs_clear_status(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - int scierr = 0; + int err; u32 idx = 0; struct snvs_security_sc_conf conf = {0}; @@ -764,20 +759,18 @@ static int do_snvs_clear_status(struct cmd_tbl *cmdtp, int flag, int argc, conf.lp.status = hextoul(argv[++idx], NULL); conf.lp.tamper_det_status = hextoul(argv[++idx], NULL); - scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.status), - &conf.lp.status, NULL, NULL, NULL, - NULL, 1); - if (scierr != SC_ERR_NONE) + err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.status), + &conf.lp.status, NULL, NULL, NULL, NULL, 1); + if (err) goto exit; - scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_status), - &conf.lp.tamper_det_status, NULL, - NULL, NULL, NULL, 1); - if (scierr != SC_ERR_NONE) + err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_status), + &conf.lp.tamper_det_status, NULL, NULL, NULL, NULL, 1); + if (err) goto exit; exit: - return (scierr == SC_ERR_NONE) ? 0 : 1; + return err; } U_BOOT_CMD(snvs_clear_status, @@ -793,7 +786,7 @@ static char snvs_sec_status_help_text[] = static int do_snvs_sec_status(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - int scierr; + int err; u32 idx; u32 data[5]; @@ -864,8 +857,8 @@ static int do_snvs_sec_status(struct cmd_tbl *cmdtp, int flag, int argc, for (idx = 0; idx < ARRAY_SIZE(pads); idx++) { u8 pad_id = pads[idx]; - scierr = sc_pad_get(-1, pad_id, &data[0]); - if (scierr == 0) + err = sc_pad_get(-1, pad_id, &data[0]); + if (!err) printf("\t- Pin %d: %.8x\n", pad_id, data[0]); else printf("Failed to read Pin %d\n", pad_id); @@ -876,8 +869,8 @@ static int do_snvs_sec_status(struct cmd_tbl *cmdtp, int flag, int argc, for (idx = 0; idx < ARRAY_SIZE(fuses); idx++) { u32 fuse_id = fuses[idx]; - scierr = sc_misc_otp_fuse_read(-1, fuse_id, &data[0]); - if (scierr == 0) + err = sc_misc_otp_fuse_read(-1, fuse_id, &data[0]); + if (!err) printf("\t- Fuse %d: %.8x\n", fuse_id, data[0]); else printf("Failed to read Fuse %d\n", fuse_id); @@ -888,10 +881,10 @@ static int do_snvs_sec_status(struct cmd_tbl *cmdtp, int flag, int argc, for (idx = 0; idx < ARRAY_SIZE(snvs); idx++) { struct snvs_reg *reg = &snvs[idx]; - scierr = sc_seco_secvio_config(-1, reg->id, 0, &data[0], - &data[1], &data[2], &data[3], - &data[4], reg->nb); - if (scierr == 0) { + err = sc_seco_secvio_config(-1, reg->id, 0, &data[0], + &data[1], &data[2], &data[3], + &data[4], reg->nb); + if (!err) { int subidx; printf("\t- SNVS %.2x(%d):", reg->id, reg->nb); @@ -908,8 +901,8 @@ static int do_snvs_sec_status(struct cmd_tbl *cmdtp, int flag, int argc, for (idx = 0; idx < ARRAY_SIZE(dgo); idx++) { u8 dgo_id = dgo[idx]; - scierr = sc_seco_secvio_dgo_config(-1, dgo_id, 0, &data[0]); - if (scierr == 0) + err = sc_seco_secvio_dgo_config(-1, dgo_id, 0, &data[0]); + if (!err) printf("\t- DGO %.2x: %.8x\n", dgo_id, data[0]); else printf("Failed to read DGO %d\n", dgo_id); diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig index 7639439bdc9..3d62d7052e7 100644 --- a/arch/arm/mach-imx/imx8m/Kconfig +++ b/arch/arm/mach-imx/imx8m/Kconfig @@ -124,6 +124,9 @@ config TARGET_IMX8MM_VENICE select IMX8M_LPDDR4 select GATEWORKS_SC select MISC + select FSL_CAAM + select ARCH_MISC_INIT + select SPL_CRYPTO if SPL config TARGET_KONTRON_MX8MM bool "Kontron Electronics N80xx" @@ -175,6 +178,9 @@ config TARGET_IMX8MN_VENICE select IMX8M_LPDDR4 select GATEWORKS_SC select MISC + select FSL_CAAM + select ARCH_MISC_INIT + select SPL_CRYPTO if SPL config TARGET_IMX8MP_DATA_MODUL_EDM_SBC bool "Data Modul eDM SBC i.MX8M Plus" @@ -232,6 +238,9 @@ config TARGET_IMX8MP_VENICE select IMX8M_LPDDR4 select GATEWORKS_SC select MISC + select FSL_CAAM + select ARCH_MISC_INIT + select SPL_CRYPTO if SPL config TARGET_PICO_IMX8MQ bool "Support Technexion Pico iMX8MQ" @@ -245,6 +254,10 @@ config TARGET_IMX8MN_VAR_SOM select IMX8MN select SUPPORT_SPL select IMX8M_DDR4 + select MISC + select I2C_EEPROM + select DM_ETH_PHY + select NVMEM config TARGET_KONTRON_PITX_IMX8M bool "Support Kontron pITX-imx8m" diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c b/arch/arm/mach-imx/imx8m/clock_imx8mm.c index 31c34b6031f..986870799d3 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c @@ -90,7 +90,6 @@ static int fracpll_configure(enum pll_clocks pll, u32 freq) case ANATOP_DRAM_PLL: setbits_le32(GPC_BASE_ADDR + 0xEC, 1 << 7); setbits_le32(GPC_BASE_ADDR + 0xF8, 1 << 5); - writel(SRC_DDR1_ENABLE_MASK, SRC_BASE_ADDR + 0x1004); pll_base = &ana_pll->dram_pll_gnrl_ctl; break; diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 5ffdcabbb51..78b775f449d 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -333,7 +333,7 @@ phys_size_t get_effective_memsize(void) } } -phys_size_t board_get_usable_ram_top(phys_size_t total_size) +phys_addr_t board_get_usable_ram_top(phys_size_t total_size) { ulong top_addr; @@ -737,7 +737,7 @@ static int disable_fdt_nodes(void *blob, const char *const nodes_path[], int siz if (nodeoff < 0) continue; /* Not found, skip it */ - printf("Found %s node\n", nodes_path[i]); + debug("Found %s node\n", nodes_path[i]); add_status: rc = fdt_setprop(blob, nodeoff, "status", status, strlen(status) + 1); @@ -1266,7 +1266,7 @@ int ft_system_setup(void *blob, struct bd_info *bd) if (nodeoff >= 0) { const char *speed = "high-speed"; - printf("Found %s node\n", usb_dwc3_path[v]); + debug("Found %s node\n", usb_dwc3_path[v]); usb_modify_speed: diff --git a/arch/arm/mach-imx/imx8ulp/Makefile b/arch/arm/mach-imx/imx8ulp/Makefile index f7692cf3a78..2c9938fcdf0 100644 --- a/arch/arm/mach-imx/imx8ulp/Makefile +++ b/arch/arm/mach-imx/imx8ulp/Makefile @@ -5,7 +5,6 @@ obj-y += lowlevel_init.o obj-y += soc.o clock.o iomux.o pcc.o cgc.o rdc.o -obj-$(CONFIG_AHAB_BOOT) += ahab.o ifeq ($(CONFIG_SPL_BUILD),y) obj-y += upower/ diff --git a/arch/arm/mach-imx/imx8ulp/rdc.c b/arch/arm/mach-imx/imx8ulp/rdc.c index 50b097b035a..cfc09e79cbd 100644 --- a/arch/arm/mach-imx/imx8ulp/rdc.c +++ b/arch/arm/mach-imx/imx8ulp/rdc.c @@ -9,7 +9,7 @@ #include <asm/arch/imx-regs.h> #include <asm/arch/sys_proto.h> #include <asm/mach-imx/mu_hal.h> -#include <asm/mach-imx/s400_api.h> +#include <asm/mach-imx/ele_api.h> #include <asm/arch/rdc.h> #include <div64.h> @@ -203,12 +203,12 @@ int xrdc_config_msc(u32 msc, u32 index, u32 dom, u32 perm) int release_rdc(enum rdc_type type) { ulong s_mu_base = 0x27020000UL; - struct sentinel_msg msg; + struct ele_msg msg; int ret; u32 rdc_id = (type == RDC_XRDC) ? 0x78 : 0x74; - msg.version = AHAB_VERSION; - msg.tag = AHAB_CMD_TAG; + msg.version = ELE_VERSION; + msg.tag = ELE_CMD_TAG; msg.size = 2; msg.command = ELE_RELEASE_RDC_REQ; msg.data[0] = (rdc_id << 8) | 0x2; /* A35 XRDC */ @@ -266,7 +266,7 @@ void xrdc_mrc_region_set_access(int mrc_index, u32 addr, u32 access) mrgd[4] |= ((access & 0xFFF) << 16); } - /* not handle other cases, since S400 only set ACCESS1 and 2 */ + /* not handle other cases, since ELE only set ACCESS1 and 2 */ writel(mrgd[4], xrdc_base + off + 0x10); return; } @@ -295,7 +295,7 @@ void xrdc_init_mda(void) void xrdc_init_mrc(void) { - /* Re-config MRC3 for SRAM0 in case protected by S400 */ + /* Re-config MRC3 for SRAM0 in case protected by ELE */ xrdc_config_mrc_w0_w1(3, 0, 0x22010000, 0x10000); xrdc_config_mrc_dx_perm(3, 0, 0, 1); xrdc_config_mrc_dx_perm(3, 0, 1, 1); @@ -320,7 +320,7 @@ void xrdc_init_mrc(void) xrdc_config_mrc_dx_perm(5, 0, 1, 1); xrdc_config_mrc_w3_w4(5, 0, 0x0, 0x80000FFF); - /* Set MRC6 for DDR access from Sentinel */ + /* Set MRC6 for DDR access from ELE */ xrdc_config_mrc_w0_w1(6, 0, CFG_SYS_SDRAM_BASE, PHYS_SDRAM_SIZE); xrdc_config_mrc_dx_perm(6, 0, 4, 1); xrdc_config_mrc_w3_w4(6, 0, 0x0, 0x80000FFF); @@ -404,7 +404,7 @@ int trdc_mbc_set_access(u32 mbc_x, u32 dom_x, u32 mem_x, u32 blk_x, bool sec_acc val &= ~(0xFU << offset); /* MBC0-3 - * Global 0, 0x7777 secure pri/user read/write/execute, S400 has already set it. + * Global 0, 0x7777 secure pri/user read/write/execute, ELE has already set it. * So select MBC0_MEMN_GLBAC0 */ if (sec_access) { @@ -445,7 +445,7 @@ int trdc_mrc_region_set_access(u32 mrc_x, u32 dom_x, u32 addr_start, u32 addr_en continue; /* MRC0,1 - * Global 0, 0x7777 secure pri/user read/write/execute, S400 has already set it. + * Global 0, 0x7777 secure pri/user read/write/execute, ELE has already set it. * So select MRCx_MEMN_GLBAC0 */ if (sec_access) { diff --git a/arch/arm/mach-imx/imx8ulp/soc.c b/arch/arm/mach-imx/imx8ulp/soc.c index 81eae02b6a8..e23cf60d126 100644 --- a/arch/arm/mach-imx/imx8ulp/soc.c +++ b/arch/arm/mach-imx/imx8ulp/soc.c @@ -14,7 +14,7 @@ #include <event.h> #include <spl.h> #include <asm/arch/rdc.h> -#include <asm/mach-imx/s400_api.h> +#include <asm/mach-imx/ele_api.h> #include <asm/mach-imx/mu_hal.h> #include <cpu_func.h> #include <asm/setup.h> @@ -70,7 +70,7 @@ int mmc_get_env_dev(void) } #endif -static void set_cpu_info(struct sentinel_get_info_data *info) +static void set_cpu_info(struct ele_get_info_data *info) { gd->arch.soc_rev = info->soc; gd->arch.lifecycle = info->lc; @@ -582,9 +582,9 @@ void get_board_serial(struct tag_serialnr *serialnr) u32 res; int ret; - ret = ahab_read_common_fuse(1, uid, 4, &res); + ret = ele_read_common_fuse(1, uid, 4, &res); if (ret) - printf("ahab read fuse failed %d, 0x%x\n", ret, res); + printf("ele read fuse failed %d, 0x%x\n", ret, res); else printf("UID 0x%x,0x%x,0x%x,0x%x\n", uid[0], uid[1], uid[2], uid[3]); @@ -783,7 +783,7 @@ int imx8ulp_dm_post_init(void) struct udevice *devp; int ret; u32 res; - struct sentinel_get_info_data *info = (struct sentinel_get_info_data *)SRAM0_BASE; + struct ele_get_info_data *info = (struct ele_get_info_data *)SRAM0_BASE; ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(imx8ulp_mu), &devp); if (ret) { @@ -791,11 +791,11 @@ int imx8ulp_dm_post_init(void) return ret; } - ret = ahab_get_info(info, &res); + ret = ele_get_info(info, &res); if (ret) { - printf("ahab_get_info failed %d\n", ret); + printf("ele_get_info failed %d\n", ret); /* fallback to A0.1 revision */ - memset((void *)info, 0, sizeof(struct sentinel_get_info_data)); + memset((void *)info, 0, sizeof(struct ele_get_info_data)); info->soc = 0xa000084d; } diff --git a/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c b/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c index fcb02ed3af6..b471a75caa1 100644 --- a/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c +++ b/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c @@ -217,8 +217,8 @@ int upower_init(void) * CM33 Cache * PowerQuad RAM * ETF RAM - * Sentinel PKC, Data RAM1, Inst RAM0/1 - * Sentinel ROM + * ELE PKC, Data RAM1, Inst RAM0/1 + * ELE ROM * uPower IRAM/DRAM * uPower ROM * CM33 ROM @@ -230,7 +230,7 @@ int upower_init(void) * SSRAM Partition 7_a(128KB) * SSRAM Partition 7_b(64KB) * SSRAM Partition 7_c(64KB) - * Sentinel Data RAM0, Inst RAM2 + * ELE Data RAM0, Inst RAM2 */ /* MIPI-CSI FIFO BIT28 not set */ memon = 0x3FFFFFEFFFFFFCUL; diff --git a/arch/arm/mach-imx/imx9/clock.c b/arch/arm/mach-imx/imx9/clock.c index a7ecccaf879..766a8811c1f 100644 --- a/arch/arm/mach-imx/imx9/clock.c +++ b/arch/arm/mach-imx/imx9/clock.c @@ -709,8 +709,8 @@ struct imx_clk_setting imx_clk_settings[] = { /* Set A55 mtr bus to 133M */ {ARM_A55_MTR_BUS_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3}, - /* Sentinel to 133M */ - {SENTINEL_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3}, + /* ELE to 133M */ + {ELE_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3}, /* Bus_wakeup to 133M */ {BUS_WAKEUP_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3}, /* Bus_AON to 133M */ @@ -740,8 +740,8 @@ struct imx_clk_setting imx_clk_settings[] = { {ARM_A55_PERIPH_CLK_ROOT, SYS_PLL_PFD0, 3}, /* Set A55 mtr bus to 133M */ {ARM_A55_MTR_BUS_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3}, - /* Sentinel to 200M */ - {SENTINEL_CLK_ROOT, SYS_PLL_PFD1_DIV2, 2}, + /* ELE to 200M */ + {ELE_CLK_ROOT, SYS_PLL_PFD1_DIV2, 2}, /* Bus_wakeup to 133M */ {BUS_WAKEUP_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3}, /* Bus_AON to 133M */ diff --git a/arch/arm/mach-imx/imx9/clock_root.c b/arch/arm/mach-imx/imx9/clock_root.c index 06b93f60996..7d7ae865946 100644 --- a/arch/arm/mach-imx/imx9/clock_root.c +++ b/arch/arm/mach-imx/imx9/clock_root.c @@ -34,7 +34,7 @@ static struct clk_root_map clk_root_array[] = { { ARM_A55_MTR_BUS_CLK_ROOT, 2 }, { ARM_A55_CLK_ROOT, 0 }, { M33_CLK_ROOT, 2 }, - { SENTINEL_CLK_ROOT, 2 }, + { ELE_CLK_ROOT, 2 }, { BUS_WAKEUP_CLK_ROOT, 2 }, { BUS_AON_CLK_ROOT, 2 }, { WAKEUP_AXI_CLK_ROOT, 0 }, diff --git a/arch/arm/mach-imx/imx9/imx_bootaux.c b/arch/arm/mach-imx/imx9/imx_bootaux.c index 256e6fa1c54..6afb59e0515 100644 --- a/arch/arm/mach-imx/imx9/imx_bootaux.c +++ b/arch/arm/mach-imx/imx9/imx_bootaux.c @@ -13,7 +13,7 @@ int arch_auxiliary_core_check_up(u32 core_id) { struct arm_smccc_res res; - arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0, + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STARTED, 0, 0, 0, 0, 0, 0, &res); return res.a0; @@ -25,7 +25,7 @@ int arch_auxiliary_core_down(u32 core_id) printf("## Stopping auxiliary core\n"); - arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_STOP, 0, 0, + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STOP, 0, 0, 0, 0, 0, 0, &res); return 0; @@ -40,7 +40,7 @@ int arch_auxiliary_core_up(u32 core_id, ulong addr) printf("## Starting auxiliary core addr = 0x%08lX...\n", addr); - arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, addr, 0, + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_START, addr, 0, 0, 0, 0, 0, &res); return 0; diff --git a/arch/arm/mach-imx/imx9/soc.c b/arch/arm/mach-imx/imx9/soc.c index 64e8ac610e5..f43b73a6c21 100644 --- a/arch/arm/mach-imx/imx9/soc.c +++ b/arch/arm/mach-imx/imx9/soc.c @@ -34,7 +34,7 @@ #include <asm/setup.h> #include <asm/bootm.h> #include <asm/arch-imx/cpu.h> -#include <asm/mach-imx/s400_api.h> +#include <asm/mach-imx/ele_api.h> #include <fuse.h> #include <asm/arch/ddr.h> @@ -151,7 +151,7 @@ u32 get_cpu_temp_grade(int *minc, int *maxc) return val; } -static void set_cpu_info(struct sentinel_get_info_data *info) +static void set_cpu_info(struct ele_get_info_data *info) { gd->arch.soc_rev = info->soc; gd->arch.lifecycle = info->lc; @@ -557,7 +557,7 @@ int imx9_probe_mu(void *ctx, struct event *event) struct udevice *devp; int node, ret; u32 res; - struct sentinel_get_info_data info; + struct ele_get_info_data info; node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "fsl,imx93-mu-s4"); @@ -568,7 +568,7 @@ int imx9_probe_mu(void *ctx, struct event *event) if (gd->flags & GD_FLG_RELOC) return 0; - ret = ahab_get_info(&info, &res); + ret = ele_get_info(&info, &res); if (ret) return ret; @@ -600,35 +600,31 @@ int timer_init(void) enum env_location env_get_location(enum env_operation op, int prio) { enum boot_device dev = get_boot_device(); - enum env_location env_loc = ENVL_UNKNOWN; if (prio) - return env_loc; + return ENVL_UNKNOWN; switch (dev) { -#if defined(CONFIG_ENV_IS_IN_SPI_FLASH) case QSPI_BOOT: - env_loc = ENVL_SPI_FLASH; - break; -#endif -#if defined(CONFIG_ENV_IS_IN_MMC) + if (CONFIG_IS_ENABLED(ENV_IS_IN_SPI_FLASH)) + return ENVL_SPI_FLASH; + return ENVL_NOWHERE; case SD1_BOOT: case SD2_BOOT: case SD3_BOOT: case MMC1_BOOT: case MMC2_BOOT: case MMC3_BOOT: - env_loc = ENVL_MMC; - break; -#endif + if (CONFIG_IS_ENABLED(ENV_IS_IN_MMC)) + return ENVL_MMC; + else if (CONFIG_IS_ENABLED(ENV_IS_IN_EXT4)) + return ENVL_EXT4; + else if (CONFIG_IS_ENABLED(ENV_IS_IN_FAT)) + return ENVL_FAT; + return ENVL_NOWHERE; default: -#if defined(CONFIG_ENV_IS_NOWHERE) - env_loc = ENVL_NOWHERE; -#endif - break; + return ENVL_NOWHERE; } - - return env_loc; } static int mix_power_init(enum mix_power_domain pd) @@ -646,7 +642,7 @@ static int mix_power_init(enum mix_power_domain pd) mem_id = SRC_MEM_MEDIA; scr = BIT(5); - /* Enable S400 handshake */ + /* Enable ELE handshake */ struct blk_ctrl_s_aonmix_regs *s_regs = (struct blk_ctrl_s_aonmix_regs *)BLK_CTRL_S_ANOMIX_BASE_ADDR; @@ -763,8 +759,8 @@ int m33_prepare(void) while (!(val & SRC_MIX_SLICE_FUNC_STAT_RST_STAT)) val = readl(&mix_regs->func_stat); - /* Release Sentinel TROUT */ - ahab_release_m33_trout(); + /* Release ELE TROUT */ + ele_release_m33_trout(); /* Mask WDOG1 IRQ from A55, we use it for M33 reset */ setbits_le32(&s_regs->ca55_irq_mask[1], BIT(6)); @@ -772,7 +768,7 @@ int m33_prepare(void) /* Turn on WDOG1 clock */ ccm_lpcg_on(CCGR_WDG1, 1); - /* Set sentinel LP handshake for M33 reset */ + /* Set ELE LP handshake for M33 reset */ setbits_le32(&s_regs->lp_handshake[0], BIT(6)); /* Clear M33 TCM for ECC */ diff --git a/arch/arm/mach-imx/imx9/trdc.c b/arch/arm/mach-imx/imx9/trdc.c index e05c7048106..d0f855bb1bc 100644 --- a/arch/arm/mach-imx/imx9/trdc.c +++ b/arch/arm/mach-imx/imx9/trdc.c @@ -10,7 +10,7 @@ #include <asm/arch/imx-regs.h> #include <asm/arch/sys_proto.h> #include <div64.h> -#include <asm/mach-imx/s400_api.h> +#include <asm/mach-imx/ele_api.h> #include <asm/mach-imx/mu_hal.h> #define DID_NUM 16 @@ -196,7 +196,7 @@ int trdc_mbc_blk_config(ulong trdc_reg, u32 mbc_x, u32 dom_x, u32 mem_x, val &= ~(0xFU << offset); /* MBC0-3 - * Global 0, 0x7777 secure pri/user read/write/execute, S400 has already set it. + * Global 0, 0x7777 secure pri/user read/write/execute, ELE has already set it. * So select MBC0_MEMN_GLBAC0 */ if (sec_access) { @@ -266,7 +266,7 @@ int trdc_mrc_region_config(ulong trdc_reg, u32 mrc_x, u32 dom_x, u32 addr_start, continue; /* MRC0,1 - * Global 0, 0x7777 secure pri/user read/write/execute, S400 has already set it. + * Global 0, 0x7777 secure pri/user read/write/execute, ELE has already set it. * So select MRCx_MEMN_GLBAC0 */ if (sec_access) { @@ -315,7 +315,7 @@ bool trdc_mbc_enabled(ulong trdc_base) int release_rdc(u8 xrdc) { ulong s_mu_base = 0x47520000UL; - struct sentinel_msg msg; + struct ele_msg msg; int ret; u32 rdc_id; @@ -336,8 +336,8 @@ int release_rdc(u8 xrdc) return -EINVAL; } - msg.version = AHAB_VERSION; - msg.tag = AHAB_CMD_TAG; + msg.version = ELE_VERSION; + msg.tag = ELE_CMD_TAG; msg.size = 2; msg.command = ELE_RELEASE_RDC_REQ; msg.data[0] = (rdc_id << 8) | 0x2; /* A55 */ @@ -394,7 +394,7 @@ void trdc_init(void) /* DDR */ trdc_mrc_set_control(0x49010000, 0, 0, 0x7777); - /* S400*/ + /* ELE */ trdc_mrc_region_config(0x49010000, 0, 0, 0x80000000, 0xFFFFFFFF, false, 0); /* MTR */ diff --git a/arch/arm/mach-imx/imx_bootaux.c b/arch/arm/mach-imx/imx_bootaux.c index 888c53d6901..f7b14ca38d9 100644 --- a/arch/arm/mach-imx/imx_bootaux.c +++ b/arch/arm/mach-imx/imx_bootaux.c @@ -14,6 +14,7 @@ #include <linux/compiler.h> #include <cpu_func.h> +#ifndef CONFIG_IMX8 /* Just to avoid build error */ #if IS_ENABLED(CONFIG_IMX8M) #define SRC_M4C_NON_SCLR_RST_MASK BIT(0) @@ -45,7 +46,7 @@ static const struct rproc_att *get_host_mapping(unsigned long auxcore) * is valid, returns the entry point address. * Translates load addresses in the elf file to the U-Boot address space. */ -static unsigned long load_elf_image_m_core_phdr(unsigned long addr, ulong *stack) +static u32 load_elf_image_m_core_phdr(unsigned long addr, u32 *stack) { Elf32_Ehdr *ehdr; /* ELF header structure pointer */ Elf32_Phdr *phdr; /* Program header structure pointer */ @@ -95,7 +96,7 @@ static unsigned long load_elf_image_m_core_phdr(unsigned long addr, ulong *stack int arch_auxiliary_core_up(u32 core_id, ulong addr) { - ulong stack, pc; + u32 stack, pc; if (!addr) return -EINVAL; @@ -121,18 +122,18 @@ int arch_auxiliary_core_up(u32 core_id, ulong addr) pc = *(u32 *)(addr + 4); } - printf("## Starting auxiliary core stack = 0x%08lX, pc = 0x%08lX...\n", + printf("## Starting auxiliary core stack = 0x%08X, pc = 0x%08X...\n", stack, pc); - /* Set the stack and pc to M4 bootROM */ - writel(stack, M4_BOOTROM_BASE_ADDR); - writel(pc, M4_BOOTROM_BASE_ADDR + 4); + /* Set the stack and pc to MCU bootROM */ + writel(stack, MCU_BOOTROM_BASE_ADDR); + writel(pc, MCU_BOOTROM_BASE_ADDR + 4); flush_dcache_all(); - /* Enable M4 */ + /* Enable MCU */ if (IS_ENABLED(CONFIG_IMX8M)) { - arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0, 0, 0, 0, 0, NULL); + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_START, 0, 0, 0, 0, 0, 0, NULL); } else { clrsetbits_le32(SRC_BASE_ADDR + SRC_M4_REG_OFFSET, SRC_M4C_NON_SCLR_RST_MASK, SRC_M4_ENABLE_MASK); @@ -147,7 +148,7 @@ int arch_auxiliary_core_check_up(u32 core_id) unsigned int val; if (IS_ENABLED(CONFIG_IMX8M)) { - arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0, 0, 0, 0, 0, &res); + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STARTED, 0, 0, 0, 0, 0, 0, &res); return res.a0; } @@ -158,30 +159,34 @@ int arch_auxiliary_core_check_up(u32 core_id) return 1; } - +#endif /* * To i.MX6SX and i.MX7D, the image supported by bootaux needs * the reset vector at the head for the image, with SP and PC * as the first two words. * - * Per the cortex-M reference manual, the reset vector of M4 needs - * to exist at 0x0 (TCMUL). The PC and SP are the first two addresses - * of that vector. So to boot M4, the A core must build the M4's reset + * Per the cortex-M reference manual, the reset vector of M4/M7 needs + * to exist at 0x0 (TCMUL/IDTCM). The PC and SP are the first two addresses + * of that vector. So to boot M4/M7, the A core must build the M4/M7's reset * vector with getting the PC and SP from image and filling them to - * TCMUL. When M4 is kicked, it will load the PC and SP by itself. - * The TCMUL is mapped to (M4_BOOTROM_BASE_ADDR) at A core side for - * accessing the M4 TCMUL. + * TCMUL/IDTCM. When M4/M7 is kicked, it will load the PC and SP by itself. + * The TCMUL/IDTCM is mapped to (MCU_BOOTROM_BASE_ADDR) at A core side for + * accessing the M4/M7 TCMUL/IDTCM. */ static int do_bootaux(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { ulong addr; int ret, up; + u32 core = 0; if (argc < 2) return CMD_RET_USAGE; - up = arch_auxiliary_core_check_up(0); + if (argc > 2) + core = simple_strtoul(argv[2], NULL, 10); + + up = arch_auxiliary_core_check_up(core); if (up) { printf("## Auxiliary core is already up\n"); return CMD_RET_SUCCESS; @@ -192,7 +197,7 @@ static int do_bootaux(struct cmd_tbl *cmdtp, int flag, int argc, if (!addr) return CMD_RET_FAILURE; - ret = arch_auxiliary_core_up(0, addr); + ret = arch_auxiliary_core_up(core, addr); if (ret) return CMD_RET_FAILURE; @@ -202,5 +207,7 @@ static int do_bootaux(struct cmd_tbl *cmdtp, int flag, int argc, U_BOOT_CMD( bootaux, CONFIG_SYS_MAXARGS, 1, do_bootaux, "Start auxiliary core", - "" + "<address> [<core>]\n" + " - start auxiliary core [<core>] (default 0),\n" + " at address <address>\n" ); diff --git a/arch/arm/mach-imx/mx6/module_fuse.c b/arch/arm/mach-imx/mx6/module_fuse.c index 0f4565e3117..b58f11c1e56 100644 --- a/arch/arm/mach-imx/mx6/module_fuse.c +++ b/arch/arm/mach-imx/mx6/module_fuse.c @@ -206,7 +206,7 @@ int ft_system_setup(void *blob, struct bd_info *bd) if (off < 0) continue; /* Not found, skip it */ add_status: - rc = fdt_setprop(blob, nodeoff, "status", status, + rc = fdt_setprop(blob, off, "status", status, strlen(status) + 1); if (rc) { if (rc == -FDT_ERR_NOSPACE) { diff --git a/arch/arm/mach-imx/mxs/Kconfig b/arch/arm/mach-imx/mxs/Kconfig index b2026a3758a..d3233d8d14f 100644 --- a/arch/arm/mach-imx/mxs/Kconfig +++ b/arch/arm/mach-imx/mxs/Kconfig @@ -10,10 +10,12 @@ choice config TARGET_MX23_OLINUXINO bool "Support mx23_olinuxino" + select PL01X_SERIAL select BOARD_EARLY_INIT_F config TARGET_MX23EVK bool "Support mx23evk" + select PL01X_SERIAL select BOARD_EARLY_INIT_F config TARGET_XFI3 @@ -41,16 +43,37 @@ choice config TARGET_MX28EVK bool "Support mx28evk" + select PL01X_SERIAL select BOARD_EARLY_INIT_F config TARGET_XEA bool "Support XEA" + select PL01X_SERIAL endchoice config SYS_SOC default "mxs" +config SPL_MXS_PMU_MINIMAL_VDD5V_CURRENT + bool "Force minimal current draw from VDD5V by MX28 PMU" + default n + help + After setting this option, the current drawn from VDD5V + by the PMU is reduced to zero - the DCDC_BATT is used as + the main power source for PMU. + +config SPL_MXS_PMU_DISABLE_BATT_CHARGE + bool "Disable Battery Charging in MX28 PMU" + default n + +config SPL_MXS_PMU_ENABLE_4P2_LINEAR_REGULATOR + bool "Enable the 4P2 linear regulator in MX28 PMU" + default y + help + This option enables the 4P2 linear regulator (derived + from VDD5V) - so the VDD4P2 power source is operational. + source "board/freescale/mx28evk/Kconfig" source "board/liebherr/xea/Kconfig" diff --git a/arch/arm/mach-imx/parse-container.c b/arch/arm/mach-imx/parse-container.c index f7582825d6d..e2a9e2b2732 100644 --- a/arch/arm/mach-imx/parse-container.c +++ b/arch/arm/mach-imx/parse-container.c @@ -1,75 +1,16 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2018-2019 NXP + * Copyright 2018-2021 NXP */ #include <common.h> +#include <stdlib.h> #include <errno.h> #include <log.h> #include <spl.h> #include <asm/mach-imx/image.h> #ifdef CONFIG_AHAB_BOOT -#include <firmware/imx/sci/sci.h> -#endif - -#define SEC_SECURE_RAM_BASE 0x31800000UL -#define SEC_SECURE_RAM_END_BASE (SEC_SECURE_RAM_BASE + 0xFFFFUL) -#define SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE 0x60000000UL - -#define SECO_PT 2U - -#ifdef CONFIG_AHAB_BOOT -static int authenticate_image(struct boot_img_t *img, int image_index) -{ - sc_faddr_t start, end; - sc_rm_mr_t mr; - int err; - int ret = 0; - - debug("img %d, dst 0x%x, src 0x%x, size 0x%x\n", - image_index, (uint32_t)img->dst, img->offset, img->size); - - /* Find the memreg and set permission for seco pt */ - err = sc_rm_find_memreg(-1, &mr, - img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1), - ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE) - 1); - - if (err) { - printf("can't find memreg for image %d load address 0x%x, error %d\n", - image_index, img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1), err); - return -ENOMEM; - } - - err = sc_rm_get_memreg_info(-1, mr, &start, &end); - if (!err) - debug("memreg %u 0x%x -- 0x%x\n", mr, start, end); - - err = sc_rm_set_memreg_permissions(-1, mr, - SECO_PT, SC_RM_PERM_FULL); - if (err) { - printf("set permission failed for img %d, error %d\n", - image_index, err); - return -EPERM; - } - - err = sc_seco_authenticate(-1, SC_SECO_VERIFY_IMAGE, - 1 << image_index); - if (err) { - printf("authenticate img %d failed, return %d\n", - image_index, err); - ret = -EIO; - } - - err = sc_rm_set_memreg_permissions(-1, mr, - SECO_PT, SC_RM_PERM_NONE); - if (err) { - printf("remove permission failed for img %d, error %d\n", - image_index, err); - ret = -EPERM; - } - - return ret; -} +#include <asm/mach-imx/ahab.h> #endif static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image, @@ -110,10 +51,8 @@ static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image, } #ifdef CONFIG_AHAB_BOOT - if (authenticate_image(&images[image_index], image_index)) { - printf("Failed to authenticate image %d\n", image_index); + if (ahab_verify_cntr_image(&images[image_index], image_index)) return NULL; - } #endif return &images[image_index]; @@ -134,21 +73,27 @@ static int read_auth_container(struct spl_image_info *spl_image, * It will not override the ATF code, so safe to use it here, * no need malloc */ - container = (struct container_hdr *)spl_get_load_buffer(-size, size); + container = malloc(size); + if (!container) + return -ENOMEM; debug("%s: container: %p sector: %lu sectors: %u\n", __func__, container, sector, sectors); - if (info->read(info, sector, sectors, container) != sectors) - return -EIO; + if (info->read(info, sector, sectors, container) != sectors) { + ret = -EIO; + goto end; + } if (container->tag != 0x87 && container->version != 0x0) { - printf("Wrong container header\n"); - return -ENOENT; + printf("Wrong container header"); + ret = -ENOENT; + goto end; } if (!container->num_images) { - printf("Wrong container, no image found\n"); - return -ENOENT; + printf("Wrong container, no image found"); + ret = -ENOENT; + goto end; } length = container->length_lsb + (container->length_msb << 8); @@ -158,25 +103,24 @@ static int read_auth_container(struct spl_image_info *spl_image, size = roundup(length, info->bl_len); sectors = size / info->bl_len; - container = (struct container_hdr *)spl_get_load_buffer(-size, size); + free(container); + container = malloc(size); + if (!container) + return -ENOMEM; debug("%s: container: %p sector: %lu sectors: %u\n", __func__, container, sector, sectors); if (info->read(info, sector, sectors, container) != - sectors) - return -EIO; + sectors) { + ret = -EIO; + goto end; + } } #ifdef CONFIG_AHAB_BOOT - memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)container, - ALIGN(length, CONFIG_SYS_CACHELINE_SIZE)); - - ret = sc_seco_authenticate(-1, SC_SECO_AUTH_CONTAINER, - SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE); - if (ret) { - printf("authenticate container hdr failed, return %d\n", ret); - return ret; - } + ret = ahab_auth_cntr_hdr(container, length); + if (ret) + goto end_auth; #endif for (i = 0; i < container->num_images; i++) { @@ -197,9 +141,12 @@ static int read_auth_container(struct spl_image_info *spl_image, end_auth: #ifdef CONFIG_AHAB_BOOT - if (sc_seco_authenticate(-1, SC_SECO_REL_CONTAINER, 0)) - printf("Error: release container failed!\n"); + ahab_auth_release(); #endif + +end: + free(container); + return ret; } diff --git a/arch/arm/mach-imx/priblob.c b/arch/arm/mach-imx/priblob.c index 9b92eae7818..5b022d5c820 100644 --- a/arch/arm/mach-imx/priblob.c +++ b/arch/arm/mach-imx/priblob.c @@ -13,12 +13,16 @@ #include <asm/io.h> #include <common.h> #include <command.h> -#include "../drivers/crypto/fsl_caam_internal.h" +#include <fsl_sec.h> int do_priblob_write(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) { - writel((readl(CAAM_SCFGR) & 0xFFFFFFFC) | 3, CAAM_SCFGR); - printf("New priblob setting = 0x%x\n", readl(CAAM_SCFGR) & 0x3); + ccsr_sec_t *sec_regs = (ccsr_sec_t *)CAAM_BASE_ADDR; + u32 scfgr = sec_in32(&sec_regs->scfgr); + + scfgr |= 0x3; + sec_out32(&sec_regs->scfgr, scfgr); + printf("New priblob setting = 0x%x\n", sec_in32(&sec_regs->scfgr) & 0x3); return 0; } diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c index cb9801b7a13..6c13b00ef10 100644 --- a/arch/arm/mach-imx/spl.c +++ b/arch/arm/mach-imx/spl.c @@ -20,6 +20,7 @@ #include <asm/mach-imx/boot_mode.h> #include <g_dnl.h> #include <linux/libfdt.h> +#include <memalign.h> DECLARE_GLOBAL_DATA_PTR; @@ -315,47 +316,21 @@ ulong board_spl_fit_size_align(ulong size) size = ALIGN(size, 0x1000); size += CONFIG_CSF_SIZE; - return size; -} + if (size > CONFIG_SYS_BOOTM_LEN) + panic("spl: ERROR: image too big\n"); -void board_spl_fit_post_load(const void *fit) -{ - u32 offset = ALIGN(fdt_totalsize(fit), 0x1000); - - if (imx_hab_authenticate_image((uintptr_t)fit, - offset + IVT_SIZE + CSF_PAD_SIZE, - offset)) { - panic("spl: ERROR: image authentication unsuccessful\n"); - } + return size; } #endif void *board_spl_fit_buffer_addr(ulong fit_size, int sectors, int bl_len) { - int align_len = ARCH_DMA_MINALIGN - 1; - - /* Some devices like SDP, NOR, NAND, SPI are using bl_len =1, so their fit address - * is different with SD/MMC, this cause mismatch with signed address. Thus, adjust - * the bl_len to align with SD/MMC. - */ - if (bl_len < 512) - bl_len = 512; - - return (void *)((CONFIG_TEXT_BASE - fit_size - bl_len - - align_len) & ~align_len); -} +#if defined(CONFIG_SPL_LOAD_FIT_ADDRESS) + return (void *)CONFIG_SPL_LOAD_FIT_ADDRESS; +#else + return (void *)(CONFIG_TEXT_BASE + CONFIG_SYS_BOOTM_LEN); #endif - -#if defined(CONFIG_MX6) && defined(CONFIG_SPL_OS_BOOT) -int dram_init_banksize(void) -{ - gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE; - gd->bd->bi_dram[0].size = imx_ddr_size(); - - return 0; } -#endif - /* * read the address where the IVT header must sit * from IVT image header, loaded from SPL into @@ -365,7 +340,6 @@ int dram_init_banksize(void) void *spl_load_simple_fit_fix_load(const void *fit) { struct ivt *ivt; - unsigned long new; unsigned long offset; unsigned long size; u8 *tmp = (u8 *)fit; @@ -375,16 +349,23 @@ void *spl_load_simple_fit_fix_load(const void *fit) size = board_spl_fit_size_align(size); tmp += offset; ivt = (struct ivt *)tmp; - if (ivt->hdr.magic != IVT_HEADER_MAGIC) { - debug("no IVT header found\n"); - return (void *)fit; - } + debug("%s: ivt: %p offset: %lx size: %lx\n", __func__, ivt, offset, size); debug("%s: ivt self: %x\n", __func__, ivt->self); - new = ivt->self; - new -= offset; - debug("%s: new %lx\n", __func__, new); - memcpy((void *)new, fit, size); - return (void *)new; + if (imx_hab_authenticate_image((uintptr_t)fit, (uintptr_t)ivt, offset)) + panic("spl: ERROR: image authentication unsuccessful\n"); + + return (void *)fit; } +#endif /* CONFIG_IMX_HAB */ + +#if defined(CONFIG_MX6) && defined(CONFIG_SPL_OS_BOOT) +int dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = imx_ddr_size(); + + return 0; +} +#endif diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c index 9164045115f..4af41699678 100644 --- a/arch/arm/mach-imx/spl_imx_romapi.c +++ b/arch/arm/mach-imx/spl_imx_romapi.c @@ -76,13 +76,16 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image, u32 image_offset; ret = rom_api_query_boot_infor(QUERY_IVT_OFF, &offset); - ret |= rom_api_query_boot_infor(QUERY_PAGE_SZ, &pagesize); - ret |= rom_api_query_boot_infor(QUERY_IMG_OFF, &image_offset); + if (ret != ROM_API_OKAY) + goto err; - if (ret != ROM_API_OKAY) { - puts("ROMAPI: Failure query boot infor pagesize/offset\n"); - return -1; - } + ret = rom_api_query_boot_infor(QUERY_PAGE_SZ, &pagesize); + if (ret != ROM_API_OKAY) + goto err; + + ret = rom_api_query_boot_infor(QUERY_IMG_OFF, &image_offset); + if (ret != ROM_API_OKAY) + goto err; header = (struct legacy_img_hdr *)(CONFIG_SPL_IMX_ROMAPI_LOADADDR); @@ -124,6 +127,10 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image, } return 0; + +err: + puts("ROMAPI: Failure query boot infor pagesize/offset\n"); + return -1; } static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector, @@ -344,12 +351,12 @@ int board_return_to_bootrom(struct spl_image_info *spl_image, u32 boot, bstage; ret = rom_api_query_boot_infor(QUERY_BT_DEV, &boot); - ret |= rom_api_query_boot_infor(QUERY_BT_STAGE, &bstage); + if (ret != ROM_API_OKAY) + goto err; - if (ret != ROM_API_OKAY) { - puts("ROMAPI: failure at query_boot_info\n"); - return -1; - } + ret = rom_api_query_boot_infor(QUERY_BT_STAGE, &bstage); + if (ret != ROM_API_OKAY) + goto err; printf("Boot Stage: "); @@ -374,4 +381,7 @@ int board_return_to_bootrom(struct spl_image_info *spl_image, return spl_romapi_load_image_stream(spl_image, bootdev); return spl_romapi_load_image_seekable(spl_image, bootdev, boot); +err: + puts("ROMAPI: failure at query_boot_info\n"); + return -1; } |
