From: Ye Li <ye...@nxp.com> This patch adds V2X container support for i.MX95. Since V2X container may not be included in ahab-container.img of i.MX95, check if V2X container exists in order to get the correct image end.
Signed-off-by: Ye Li <ye...@nxp.com> Signed-off-by: Alice Guo <alice....@nxp.com> Reviewed-by: Peng Fan <peng....@nxp.com> --- arch/arm/mach-imx/image-container.c | 119 ++++++++++++++++++++++++++++-------- 1 file changed, 95 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-imx/image-container.c b/arch/arm/mach-imx/image-container.c index 2afe9d38a06..f84e23f4b2a 100644 --- a/arch/arm/mach-imx/image-container.c +++ b/arch/arm/mach-imx/image-container.c @@ -41,6 +41,52 @@ #define FUSE_IMG_SET_OFF_WORD 720 #endif +#define MAX_V2X_CTNR_IMG_NUM (4) +#define MIN_V2X_CTNR_IMG_NUM (2) + +#define IMG_FLAGS_IMG_TYPE_SHIFT (0u) +#define IMG_FLAGS_IMG_TYPE_MASK (0xfU) +#define IMG_FLAGS_IMG_TYPE(x) (((x) & IMG_FLAGS_IMG_TYPE_MASK) >> \ + IMG_FLAGS_IMG_TYPE_SHIFT) + +#define IMG_FLAGS_CORE_ID_SHIFT (4u) +#define IMG_FLAGS_CORE_ID_MASK (0xf0U) +#define IMG_FLAGS_CORE_ID(x) (((x) & IMG_FLAGS_CORE_ID_MASK) >> \ + IMG_FLAGS_CORE_ID_SHIFT) + +#define IMG_TYPE_V2X_PRI_FW (0x0Bu) /* Primary V2X FW */ +#define IMG_TYPE_V2X_SND_FW (0x0Cu) /* Secondary V2X FW */ + +#define CORE_V2X_PRI 9 +#define CORE_V2X_SND 10 + +static bool is_v2x_fw_container(ulong addr) +{ + struct container_hdr *phdr; + struct boot_img_t *img_entry; + + phdr = (struct container_hdr *)addr; + if (phdr->tag != 0x87 || phdr->version != 0x0) { + debug("Wrong container header\n"); + return false; + } + + if (phdr->num_images >= MIN_V2X_CTNR_IMG_NUM && phdr->num_images <= MAX_V2X_CTNR_IMG_NUM) { + img_entry = (struct boot_img_t *)(addr + sizeof(struct container_hdr)); + + if (IMG_FLAGS_IMG_TYPE(img_entry->hab_flags) == IMG_TYPE_V2X_PRI_FW && + IMG_FLAGS_CORE_ID(img_entry->hab_flags) == CORE_V2X_PRI) { + img_entry++; + + if (IMG_FLAGS_IMG_TYPE(img_entry->hab_flags) == IMG_TYPE_V2X_SND_FW && + IMG_FLAGS_CORE_ID(img_entry->hab_flags) == CORE_V2X_SND) + return true; + } + } + + return false; +} + int get_container_size(ulong addr, u16 *header_length) { struct container_hdr *phdr; @@ -83,7 +129,7 @@ int get_container_size(ulong addr, u16 *header_length) return max_offset; } -static int get_dev_container_size(void *dev, int dev_type, unsigned long offset, u16 *header_length) +static int get_dev_container_size(void *dev, int dev_type, unsigned long offset, u16 *header_length, bool *v2x_cntr) { u8 *buf = malloc(CONTAINER_HDR_ALIGNMENT); int ret = 0; @@ -150,6 +196,9 @@ static int get_dev_container_size(void *dev, int dev_type, unsigned long offset, ret = get_container_size((ulong)buf, header_length); + if (v2x_cntr) + *v2x_cntr = is_v2x_fw_container((ulong)buf); + free(buf); return ret; @@ -231,45 +280,67 @@ static unsigned long get_boot_device_offset(void *dev, int dev_type) return offset; } -static int get_imageset_end(void *dev, int dev_type) +static ulong get_imageset_end(void *dev, int dev_type) { - unsigned long offset1 = 0, offset2 = 0; - int value_container[2]; + unsigned long offset[3] = {}; + int value_container[3] = {}; u16 hdr_length; + bool v2x_fw = false; - offset1 = get_boot_device_offset(dev, dev_type); - offset2 = CONTAINER_HDR_ALIGNMENT + offset1; + offset[0] = get_boot_device_offset(dev, dev_type); - value_container[0] = get_dev_container_size(dev, dev_type, offset1, &hdr_length); + value_container[0] = get_dev_container_size(dev, dev_type, offset[0], &hdr_length, NULL); if (value_container[0] < 0) { printf("Parse seco container failed %d\n", value_container[0]); - return value_container[0]; + return 0; } debug("seco container size 0x%x\n", value_container[0]); - value_container[1] = get_dev_container_size(dev, dev_type, offset2, &hdr_length); - if (value_container[1] < 0) { - debug("Parse scu container failed %d, only seco container\n", - value_container[1]); - /* return seco container total size */ - return value_container[0] + offset1; + if (is_imx95()) { + offset[1] = ALIGN(hdr_length, CONTAINER_HDR_ALIGNMENT) + offset[0]; + + value_container[1] = get_dev_container_size(dev, dev_type, offset[1], &hdr_length, &v2x_fw); + if (value_container[1] < 0) { + printf("Parse v2x container failed %d\n", value_container[1]); + return value_container[0] + offset[0]; /* return seco container total size */ + } + + if (v2x_fw) { + debug("v2x container size 0x%x\n", value_container[1]); + offset[2] = ALIGN(hdr_length, CONTAINER_HDR_ALIGNMENT) + offset[1]; + } else { + printf("no v2x container included\n"); + offset[2] = offset[1]; + } + } else { + /* Skip offset[1] */ + offset[2] = ALIGN(hdr_length, CONTAINER_HDR_ALIGNMENT) + offset[0]; + } + + value_container[2] = get_dev_container_size(dev, dev_type, offset[2], &hdr_length, NULL); + if (value_container[2] < 0) { + debug("Parse scu container image failed %d, only seco container\n", value_container[2]); + if (is_imx95()) + return value_container[1] + offset[1]; /* return seco + v2x container total size */ + else + return value_container[0] + offset[0]; /* return seco container total size */ } - debug("scu container size 0x%x\n", value_container[1]); + debug("scu container size 0x%x\n", value_container[2]); - return value_container[1] + offset2; + return value_container[2] + offset[2]; } #ifdef CONFIG_SPL_SPI_LOAD unsigned int spl_spi_get_uboot_offs(struct spi_flash *flash) { - int end; + ulong end; end = get_imageset_end(flash, QSPI_DEV); end = ROUND(end, SZ_1K); - printf("Load image from QSPI 0x%x\n", end); + printf("Load image from QSPI 0x%lx\n", end); return end; } @@ -279,12 +350,12 @@ unsigned int spl_spi_get_uboot_offs(struct spi_flash *flash) unsigned long arch_spl_mmc_get_uboot_raw_sector(struct mmc *mmc, unsigned long raw_sect) { - int end; + ulong end; end = get_imageset_end(mmc, MMC_DEV); end = ROUND(end, SZ_1K); - printf("Load image from MMC/SD 0x%x\n", end); + printf("Load image from MMC/SD 0x%lx\n", end); return end / mmc->read_bl_len; } @@ -312,12 +383,12 @@ int spl_mmc_emmc_boot_partition(struct mmc *mmc) #ifdef CONFIG_SPL_NAND_SUPPORT uint32_t spl_nand_get_uboot_raw_page(void) { - int end; + ulong end; end = get_imageset_end((void *)NULL, NAND_DEV); end = ROUND(end, SZ_16K); - printf("Load image from NAND 0x%x\n", end); + printf("Load image from NAND 0x%lx\n", end); return end; } @@ -326,7 +397,7 @@ uint32_t spl_nand_get_uboot_raw_page(void) #ifdef CONFIG_SPL_NOR_SUPPORT unsigned long spl_nor_get_uboot_base(void) { - int end; + ulong end; /* Calculate the image set end, * if it is less than CFG_SYS_UBOOT_BASE(0x8281000), @@ -339,7 +410,7 @@ unsigned long spl_nor_get_uboot_base(void) else end = ROUND(end, SZ_1K); - printf("Load image from NOR 0x%x\n", end); + printf("Load image from NOR 0x%lx\n", end); return end; } -- 2.43.0