From: Alice Guo <alice....@nxp.com>

i.MX95 uses binman to invoke mkimage to create image container. 2 image
containers are needed currently. The first one is composed of
ahab-container.img, LPDDR firmware images, OEI images, System Manager
image and u-boot-spl.bin. The second one is consisted of ARM Trusted
firmware and u-boot.bin.

Because DDR OEI image and LPDDR firmware images have to be packaged
together and named as m33-oei-ddrfw.bin by binman, so imx9_image.sh does
not check if m33-oei-ddrfw.bin exists.

When using "make imx95_19x19_evk_defconfig; make", imx9_image.sh will
delete the line for u-boot.bin in container.cfg. In fact, binman is
always called after the u-boot.bin is built, so imx9_image.sh does not
check if u-boot.bin exists.

Signed-off-by: Alice Guo <alice....@nxp.com>
---
 include/imx8image.h |  19 +++++--
 tools/imx8image.c   | 143 +++++++++++++++++++++++++++++++++++++++++++++++-----
 tools/imx9_image.sh |   8 +++
 3 files changed, 153 insertions(+), 17 deletions(-)

diff --git a/include/imx8image.h b/include/imx8image.h
index 6b95e93fb5..b48e2b0396 100644
--- a/include/imx8image.h
+++ b/include/imx8image.h
@@ -157,7 +157,9 @@ enum imx8image_cmd {
        CMD_SOC_TYPE,
        CMD_CONTAINER,
        CMD_IMAGE,
-       CMD_DATA
+       CMD_DATA,
+       CMD_DUMMY_V2X,
+       CMD_HOLD
 };
 
 enum imx8image_core_type {
@@ -169,7 +171,9 @@ enum imx8image_core_type {
        CFG_A35,
        CFG_A55,
        CFG_A53,
-       CFG_A72
+       CFG_A72,
+       CFG_M33,
+       CFG_OEI
 };
 
 enum imx8image_fld_types {
@@ -208,7 +212,10 @@ typedef enum option_type {
        FILEOFF,
        MSG_BLOCK,
        SENTINEL,
-       UPOWER
+       UPOWER,
+       OEI,
+       DUMMY_V2X,
+       HOLD
 } option_type_t;
 
 typedef struct {
@@ -227,12 +234,16 @@ typedef struct {
 #define CORE_CA35       4
 #define CORE_CA72       5
 #define CORE_SECO       6
+#define CORE_M33        7
 
 #define CORE_ULP_CM33          0x1
 #define CORE_ULP_CA35          0x2
 #define CORE_ULP_UPOWER        0x4
 #define CORE_ULP_SENTINEL      0x6
 
+#define CORE_IMX95_M33P                0
+#define CORE_IMX95_A55C0       2
+
 #define SC_R_OTP       357U
 #define SC_R_DEBUG     354U
 #define SC_R_ROM_0     236U
@@ -246,10 +257,12 @@ typedef struct {
 #define IMG_TYPE_EXEC    0x03   /* Executable image type */
 #define IMG_TYPE_DATA    0x04   /* Data image type */
 #define IMG_TYPE_DCD_DDR 0x05   /* DCD/DDR image type */
+#define IMG_TYPE_OEI     0x05   /* Optional Executable image type */
 #define IMG_TYPE_SECO    0x06   /* SECO image type */
 #define IMG_TYPE_SENTINEL 0x06 /* SENTINEL image type */
 #define IMG_TYPE_PROV    0x07   /* Provisioning image type */
 #define IMG_TYPE_DEK     0x08   /* DEK validation type */
+#define IMG_TYPE_V2X_DUMMY 0x0E /* V2X Dummy image */
 
 #define IMG_TYPE_SHIFT   0
 #define IMG_TYPE_MASK    0x1f
diff --git a/tools/imx8image.c b/tools/imx8image.c
index 0135b19095..94b1efacd1 100644
--- a/tools/imx8image.c
+++ b/tools/imx8image.c
@@ -7,6 +7,7 @@
 
 #include "imx8image.h"
 #include <image.h>
+#include <linux/sizes.h>
 
 static int p_idx;
 static int sector_size;
@@ -54,6 +55,8 @@ static table_entry_t imx8image_cmds[] = {
        {CMD_CONTAINER,         "CONTAINER",            "new container",      },
        {CMD_IMAGE,             "IMAGE",                "new image",          },
        {CMD_DATA,              "DATA",                 "new data",           },
+       {CMD_DUMMY_V2X,         "DUMMY_V2X",            "v2x",                },
+       {CMD_HOLD,              "HOLD",                 "hold",               },
        {-1,                    "",                     "",                   },
 };
 
@@ -66,6 +69,8 @@ static table_entry_t imx8image_core_entries[] = {
        {CFG_A55,       "A55",                  "A55 core",     },
        {CFG_A53,       "A53",                  "A53 core",     },
        {CFG_A72,       "A72",                  "A72 core",     },
+       {CFG_OEI,       "OEI",                  "OEI", },
+       {CFG_M33,       "M33",                  "M33 core", },
        {-1,            "",                     "",             },
 };
 
@@ -144,6 +149,14 @@ static void parse_cfg_cmd(image_t *param_stack, int32_t 
cmd, char *token,
                        exit(EXIT_FAILURE);
                }
                break;
+       case CMD_DUMMY_V2X:
+               param_stack[p_idx].option = DUMMY_V2X;
+               param_stack[p_idx++].entry = (uint32_t)strtoll(token, NULL, 0);
+               break;
+       case CMD_HOLD:
+               param_stack[p_idx].option = HOLD;
+               param_stack[p_idx].entry = (uint32_t)strtoll(token, NULL, 0);
+               param_stack[p_idx++].filename = NULL;
        default:
                break;
        }
@@ -221,6 +234,16 @@ static void parse_cfg_fld(image_t *param_stack, int32_t 
*cmd, char *token,
                                (*cmd == CMD_DATA) ? DATA : AP;
                        param_stack[p_idx].filename = token;
                        break;
+               case CFG_OEI:
+                       param_stack[p_idx].option = OEI;
+                       param_stack[p_idx].filename = token;
+                       param_stack[p_idx].ext = CORE_CM4_0;
+                       break;
+               case CFG_M33:
+                       param_stack[p_idx].option = M40;
+                       param_stack[p_idx].ext = 0;
+                       param_stack[p_idx].filename = token;
+                       break;
                }
                break;
        case CFG_LOAD_ADDR:
@@ -238,9 +261,15 @@ static void parse_cfg_fld(image_t *param_stack, int32_t 
*cmd, char *token,
                case CFG_A53:
                case CFG_A55:
                case CFG_A72:
+               case CFG_M33:
                        param_stack[p_idx++].entry =
                                (uint32_t)strtoll(token, NULL, 0);
                        break;
+               case CFG_OEI:
+                       param_stack[p_idx].dst = (uint32_t)strtoll(token, NULL, 
0);
+                       param_stack[p_idx].entry = param_stack[p_idx].dst + 1;
+                       p_idx++;
+                       break;
                }
        default:
                break;
@@ -549,6 +578,7 @@ static void set_image_array_entry(flash_header_v3_t 
*container,
                                  char *tmp_filename, bool dcd_skip)
 {
        uint64_t entry = image_stack->entry;
+       uint64_t dst = image_stack->dst;
        uint64_t core = image_stack->ext;
        uint32_t meta;
        char *tmp_name = "";
@@ -558,7 +588,9 @@ static void set_image_array_entry(flash_header_v3_t 
*container,
        img->offset = offset;  /* Is re-adjusted later */
        img->size = size;
 
-       set_image_hash(img, tmp_filename, IMAGE_HASH_ALGO_DEFAULT);
+       if (type != DUMMY_V2X) {
+               set_image_hash(img, tmp_filename, IMAGE_HASH_ALGO_DEFAULT);
+       }
 
        switch (type) {
        case SECO:
@@ -580,6 +612,27 @@ static void set_image_array_entry(flash_header_v3_t 
*container,
                img->dst = 0xe4000000; /* S400 IRAM base */
                img->entry = 0xe4000000;
                break;
+       case OEI:
+               if (soc != IMX9) {
+                       fprintf(stderr, "Error: invalid core id: %" PRIi64 
"\n", core);
+                       exit(EXIT_FAILURE);
+               }
+
+               img->hab_flags |= IMG_TYPE_OEI;
+               if (core == CORE_CM4_0) {
+                       img->hab_flags |= CORE_ULP_CM33 << 
BOOT_IMG_FLAGS_CORE_SHIFT;
+                       meta = CORE_IMX95_M33P;
+
+               } else {
+                       img->hab_flags |= CORE_ULP_CA35 << 
BOOT_IMG_FLAGS_CORE_SHIFT;
+                       meta = CORE_IMX95_A55C0;
+               }
+               tmp_name = "OEI";
+               img->dst = (dst ? dst : entry);
+               img->entry = entry;
+               img->meta = meta;
+               custom_partition = 0;
+               break;
        case AP:
                if (soc == QX && core == CORE_CA35) {
                        meta = IMAGE_A35_DEFAULT_META(custom_partition);
@@ -587,8 +640,10 @@ static void set_image_array_entry(flash_header_v3_t 
*container,
                        meta = IMAGE_A53_DEFAULT_META(custom_partition);
                } else if (soc == QM && core == CORE_CA72) {
                        meta = IMAGE_A72_DEFAULT_META(custom_partition);
-               } else if (((soc == ULP) || (soc == IMX9)) && core == 
CORE_CA35) {
+               } else if ((soc == ULP) && core == CORE_CA35) {
                        meta = 0;
+               } else if ((soc == IMX9) && core == CORE_CA35) {
+                       meta = CORE_IMX95_A55C0;
                } else {
                        fprintf(stderr,
                                "Error: invalid AP core id: %" PRIu64 "\n",
@@ -687,6 +742,15 @@ static void set_image_array_entry(flash_header_v3_t 
*container,
                        img->entry = 0x28300200;
                }
                break;
+       case DUMMY_V2X:
+               img->hab_flags |= IMG_TYPE_V2X_DUMMY;
+               img->hab_flags |= CORE_SC << BOOT_IMG_FLAGS_CORE_SHIFT;
+               tmp_name = "V2X Dummy";
+               set_image_hash(img, "/dev/null", IMAGE_HASH_ALGO_DEFAULT);
+               img->dst = entry;
+               img->entry = entry;
+               img->size = 0; /* dummy image has no size */
+               break;
        default:
                fprintf(stderr, "unrecognized image type (%d)\n", type);
                exit(EXIT_FAILURE);
@@ -709,15 +773,26 @@ void set_container(flash_header_v3_t *container,  
uint16_t sw_version,
        fprintf(stdout, "container flags: 0x%x\n", container->flags);
 }
 
-static int get_container_image_start_pos(image_t *image_stack, uint32_t align)
+static int get_container_image_start_pos(image_t *image_stack, uint32_t align, 
uint32_t *v2x)
 {
        image_t *img_sp = image_stack;
        /*8K total container header*/
        int file_off = CONTAINER_IMAGE_ARRAY_START_OFFSET;
        FILE *fd = NULL;
-       flash_header_v3_t header;
+       flash_header_v3_t *header;
+       flash_header_v3_t *header2;
+       void *p;
        int ret;
 
+       p = calloc(1, SZ_4K);
+       if (!p) {
+               fprintf(stderr, "Fail to alloc 4K memory\n");
+               exit(EXIT_FAILURE);
+       }
+
+       header = p;
+       header2 = p + FIRST_CONTAINER_HEADER_LENGTH;
+
        while (img_sp->option != NO_IMG) {
                if (img_sp->option == APPEND) {
                        fd = fopen(img_sp->filename, "r");
@@ -726,7 +801,7 @@ static int get_container_image_start_pos(image_t 
*image_stack, uint32_t align)
                                exit(EXIT_FAILURE);
                        }
 
-                       ret = fread(&header, sizeof(header), 1, fd);
+                       ret = fread(header, SZ_4K, 1, fd);
                        if (ret != 1) {
                                printf("Failure Read header %d\n", ret);
                                exit(EXIT_FAILURE);
@@ -734,19 +809,27 @@ static int get_container_image_start_pos(image_t 
*image_stack, uint32_t align)
 
                        fclose(fd);
 
-                       if (header.tag != IVT_HEADER_TAG_B0) {
-                               fprintf(stderr, "header tag mismatched file 
%s\n", img_sp->filename);
+                       if (header->tag != IVT_HEADER_TAG_B0) {
+                               fprintf(stderr, "header tag mismatched \n");
                                exit(EXIT_FAILURE);
                        } else {
-                               file_off +=
-                                       header.img[header.num_images - 1].size;
-                               file_off = ALIGN(file_off, align);
+                               if (header2->tag != IVT_HEADER_TAG_B0) {
+                                       file_off += 
header->img[header->num_images - 1].size;
+                                       file_off = ALIGN(file_off, align);
+                               } else {
+                                       file_off = 
header2->img[header2->num_images - 1].offset + FIRST_CONTAINER_HEADER_LENGTH;
+                                       file_off += 
header2->img[header2->num_images - 1].size;
+                                       file_off = ALIGN(file_off, align);
+                                       fprintf(stderr, "Has 2nd container 
%x\n", file_off);
+                                       *v2x = true;
+                               }
                        }
                }
 
                img_sp++;
        }
 
+       free(p);
        return file_off;
 }
 
@@ -838,6 +921,7 @@ static int build_container(soc_type_t soc, uint32_t 
sector_size,
        char *tmp_filename = NULL;
        uint32_t size = 0;
        uint32_t file_padding = 0;
+       uint32_t v2x = false;
        int ret;
 
        int container = -1;
@@ -861,7 +945,7 @@ static int build_container(soc_type_t soc, uint32_t 
sector_size,
        set_imx_hdr_v3(&imx_header, 0);
        set_imx_hdr_v3(&imx_header, 1);
 
-       file_off = get_container_image_start_pos(image_stack, sector_size);
+       file_off = get_container_image_start_pos(image_stack, sector_size, 
&v2x);
        fprintf(stdout, "container image offset (aligned):%x\n", file_off);
 
        /* step through image stack and generate the header */
@@ -870,6 +954,7 @@ static int build_container(soc_type_t soc, uint32_t 
sector_size,
        /* stop once we reach null terminator */
        while (img_sp->option != NO_IMG) {
                switch (img_sp->option) {
+               case OEI:
                case AP:
                case M40:
                case M41:
@@ -892,6 +977,30 @@ static int build_container(soc_type_t soc, uint32_t 
sector_size,
                        file_off += ALIGN(sbuf.st_size, sector_size);
                        break;
 
+               case DUMMY_V2X:
+                       if (container < 0) {
+                               fprintf(stderr, "No container found\n");
+                               exit(EXIT_FAILURE);
+                       }
+                       tmp_filename = "dummy";
+                       set_image_array_entry(&imx_header.fhdr[container],
+                                               soc,
+                                               img_sp,
+                                               file_off,
+                                               0,
+                                               tmp_filename,
+                                               dcd_skip);
+                       img_sp->src = file_off;
+                       break;
+
+               case HOLD:
+                       if (container < 0) {
+                               fprintf(stderr, "No container found\n");
+                               exit(EXIT_FAILURE);
+                       }
+                       file_off += ALIGN(img_sp->entry, sector_size);
+                       break;
+
                case SECO:
                case SENTINEL:
                        if (container < 0) {
@@ -963,11 +1072,15 @@ static int build_container(soc_type_t soc, uint32_t 
sector_size,
        do {
                if (img_sp->option == APPEND) {
                        copy_file(ofd, img_sp->filename, 0, 0);
-                       file_padding += FIRST_CONTAINER_HEADER_LENGTH;
+                       if (v2x)
+                               file_padding += FIRST_CONTAINER_HEADER_LENGTH * 
2;
+                       else
+                               file_padding += FIRST_CONTAINER_HEADER_LENGTH;
                }
                img_sp++;
        } while (img_sp->option != NO_IMG);
 
+       fprintf(stderr, "%s: %x %d\n", __func__, file_padding, v2x);
        /* Add padding or skip appended container */
        ret = lseek(ofd, file_padding, SEEK_SET);
        if (ret < 0) {
@@ -980,6 +1093,7 @@ static int build_container(soc_type_t soc, uint32_t 
sector_size,
                /* Note: Image offset are not contained in the image */
                tmp = flatten_container_header(&imx_header, container + 1,
                                               &size, file_padding);
+               fprintf(stderr, "error writing image hdr %x\n", size);
                /* Write image header */
                if (write(ofd, tmp, size) != size) {
                        fprintf(stderr, "error writing image hdr\n");
@@ -1000,7 +1114,8 @@ static int build_container(soc_type_t soc, uint32_t 
sector_size,
                    img_sp->option == AP || img_sp->option == DATA ||
                    img_sp->option == SCD || img_sp->option == SCFW ||
                    img_sp->option == SECO || img_sp->option == MSG_BLOCK ||
-                   img_sp->option == UPOWER || img_sp->option == SENTINEL) {
+                   img_sp->option == UPOWER || img_sp->option == SENTINEL ||
+                   img_sp->option == OEI) {
                        copy_file_aligned(ofd, img_sp->filename, img_sp->src,
                                          sector_size);
                }
@@ -1031,7 +1146,7 @@ int imx8image_copy_image(int outfd, struct 
image_tool_params *mparams)
        fprintf(stdout, "CONTAINER SW VERSION:\t0x%04x\n", sw_version);
 
        build_container(soc, sector_size, emmc_fastboot,
-                       img_sp, dcd_skip, fuse_version, sw_version, outfd);
+                       img_sp, false, fuse_version, sw_version, outfd);
 
        return 0;
 }
diff --git a/tools/imx9_image.sh b/tools/imx9_image.sh
index ca78a57a19..6523d1a0ad 100755
--- a/tools/imx9_image.sh
+++ b/tools/imx9_image.sh
@@ -18,6 +18,14 @@ for f in $blobs; do
                continue
        fi
 
+       if [ $f = "m33-oei-ddrfw.bin" ]; then
+               continue
+       fi
+
+       if [ $f = "u-boot.bin" ]; then
+               continue
+       fi
+
        if [ ! -f $tmp ]; then
                echo "WARNING '$tmp' not found, resulting binary may be 
not-functional" >&2
 

-- 
2.43.0

Reply via email to