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

Reply via email to