imx: container: add V2X container support for i.MX95

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.li@nxp.com>
Signed-off-by: Alice Guo <alice.guo@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
This commit is contained in:
Ye Li
2025-04-28 18:37:41 +08:00
committed by Fabio Estevam
parent 5f28a6599f
commit 86932bf014

View File

@@ -41,6 +41,52 @@
#define FUSE_IMG_SET_OFF_WORD 720 #define FUSE_IMG_SET_OFF_WORD 720
#endif #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) int get_container_size(ulong addr, u16 *header_length)
{ {
struct container_hdr *phdr; struct container_hdr *phdr;
@@ -83,7 +129,7 @@ int get_container_size(ulong addr, u16 *header_length)
return max_offset; 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); u8 *buf = malloc(CONTAINER_HDR_ALIGNMENT);
int ret = 0; 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); ret = get_container_size((ulong)buf, header_length);
if (v2x_cntr)
*v2x_cntr = is_v2x_fw_container((ulong)buf);
free(buf); free(buf);
return ret; return ret;
@@ -231,45 +280,67 @@ static unsigned long get_boot_device_offset(void *dev, int dev_type)
return offset; 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; unsigned long offset[3] = {};
int value_container[2]; int value_container[3] = {};
u16 hdr_length; u16 hdr_length;
bool v2x_fw = false;
offset1 = get_boot_device_offset(dev, dev_type); offset[0] = get_boot_device_offset(dev, dev_type);
offset2 = CONTAINER_HDR_ALIGNMENT + offset1;
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) { if (value_container[0] < 0) {
printf("Parse seco container failed %d\n", value_container[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]); debug("seco container size 0x%x\n", value_container[0]);
value_container[1] = get_dev_container_size(dev, dev_type, offset2, &hdr_length); if (is_imx95()) {
if (value_container[1] < 0) { offset[1] = ALIGN(hdr_length, CONTAINER_HDR_ALIGNMENT) + offset[0];
debug("Parse scu container failed %d, only seco container\n",
value_container[1]); value_container[1] = get_dev_container_size(dev, dev_type, offset[1], &hdr_length, &v2x_fw);
/* return seco container total size */ if (value_container[1] < 0) {
return value_container[0] + offset1; 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];
} }
debug("scu container size 0x%x\n", value_container[1]); 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 */
}
return value_container[1] + offset2; debug("scu container size 0x%x\n", value_container[2]);
return value_container[2] + offset[2];
} }
#ifdef CONFIG_SPL_SPI_LOAD #ifdef CONFIG_SPL_SPI_LOAD
unsigned int spl_spi_get_uboot_offs(struct spi_flash *flash) unsigned int spl_spi_get_uboot_offs(struct spi_flash *flash)
{ {
int end; ulong end;
end = get_imageset_end(flash, QSPI_DEV); end = get_imageset_end(flash, QSPI_DEV);
end = ROUND(end, SZ_1K); 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; 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 arch_spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
unsigned long raw_sect) unsigned long raw_sect)
{ {
int end; ulong end;
end = get_imageset_end(mmc, MMC_DEV); end = get_imageset_end(mmc, MMC_DEV);
end = ROUND(end, SZ_1K); 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; return end / mmc->read_bl_len;
} }
@@ -312,12 +383,12 @@ int spl_mmc_emmc_boot_partition(struct mmc *mmc)
#ifdef CONFIG_SPL_NAND_SUPPORT #ifdef CONFIG_SPL_NAND_SUPPORT
uint32_t spl_nand_get_uboot_raw_page(void) uint32_t spl_nand_get_uboot_raw_page(void)
{ {
int end; ulong end;
end = get_imageset_end((void *)NULL, NAND_DEV); end = get_imageset_end((void *)NULL, NAND_DEV);
end = ROUND(end, SZ_16K); 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; return end;
} }
@@ -326,7 +397,7 @@ uint32_t spl_nand_get_uboot_raw_page(void)
#ifdef CONFIG_SPL_NOR_SUPPORT #ifdef CONFIG_SPL_NOR_SUPPORT
unsigned long spl_nor_get_uboot_base(void) unsigned long spl_nor_get_uboot_base(void)
{ {
int end; ulong end;
/* Calculate the image set end, /* Calculate the image set end,
* if it is less than CFG_SYS_UBOOT_BASE(0x8281000), * if it is less than CFG_SYS_UBOOT_BASE(0x8281000),
@@ -339,7 +410,7 @@ unsigned long spl_nor_get_uboot_base(void)
else else
end = ROUND(end, SZ_1K); 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; return end;
} }