From: Fabien Parent <[email protected]> Add support for generating images that can boot on UFS storage for MediaTek SoCs.
The UFS device header is 4 KiB instead of 1.5 KiB, and the size field of its generic boot header covers the whole device header. Signed-off-by: Fabien Parent <[email protected]> [dlechner: rebase, fix header size check when verifying, document the ufs media type, use mtk_image_verify_gfh()] Signed-off-by: David Lechner <[email protected]> --- doc/README.mediatek | 1 + tools/mtk_image.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/mtk_image.h | 16 +++++++-- 3 files changed, 112 insertions(+), 2 deletions(-) diff --git a/doc/README.mediatek b/doc/README.mediatek index 246579d4be2..d38709408b7 100644 --- a/doc/README.mediatek +++ b/doc/README.mediatek @@ -107,6 +107,7 @@ To generate these two headers with mkimage: nor : Serial NOR emmc : eMMC sdmmc: SD + ufs : UFS nandinfo: Desired NAND device type, a combination of page size, oob size and optional device capacity. Valid types are: diff --git a/tools/mtk_image.c b/tools/mtk_image.c index 1b1aed59924..ac9c86df6bd 100644 --- a/tools/mtk_image.c +++ b/tools/mtk_image.c @@ -36,6 +36,9 @@ static const struct brom_img_type { }, { .name = "spim-nand", .type = BRLYT_TYPE_SNAND + }, { + .name = "ufs", + .type = BRLYT_TYPE_UFS } }; @@ -262,6 +265,8 @@ static int mtk_image_vrec_header(struct image_tool_params *params, if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) tparams->header_size = hdr_nand_size; + else if (hdr_media == BRLYT_TYPE_UFS) + tparams->header_size = sizeof(struct ufs_device_header); else tparams->header_size = sizeof(struct gen_device_header); @@ -357,6 +362,65 @@ static int mtk_image_verify_gen_header(const uint8_t *ptr, int print) return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_GEN, print); } +static int mtk_image_verify_ufs_header(const uint8_t *ptr, int print) +{ + union gen_boot_header *gbh = (union gen_boot_header *)ptr; + uint32_t gfh_offset, total_size, devh_size; + struct brom_layout_header *bh; + struct gfh_header *gfh; + const char *bootmedia; + + if (!strcmp(gbh->name, UFS_BOOT_NAME)) + bootmedia = "UFS"; + else + return -1; + + if (print) + printf("Boot Media: %s\n", bootmedia); + + devh_size = sizeof(struct ufs_device_header); + + if (le32_to_cpu(gbh->version) != 1 || + le32_to_cpu(gbh->size) != devh_size) + return -1; + + bh = (struct brom_layout_header *)(ptr + sizeof(union gen_boot_header)); + + if (strcmp(bh->name, BRLYT_NAME)) + return -1; + + if (le32_to_cpu(bh->magic) != BRLYT_MAGIC || + le32_to_cpu(bh->type) != BRLYT_TYPE_UFS) + return -1; + + if (img_gen) { + gfh_offset = devh_size; + } else { + gfh_offset = le32_to_cpu(bh->header_size); + + if (gfh_offset + sizeof(struct gfh_header) > img_size) { + /* + * This may happen if the hdr_offset used to generate + * this image is not zero. + * Since device header size is not fixed, we can't + * cover all possible cases. + * Assuming the image is valid only if the real + * device header size equals to devh_size. + */ + total_size = le32_to_cpu(bh->total_size); + + if (total_size - gfh_offset > img_size - devh_size) + return -1; + + gfh_offset = devh_size; + } + } + + gfh = (struct gfh_header *)(ptr + gfh_offset); + + return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_GEN, print); +} + static int mtk_image_verify_nand_header(const uint8_t *ptr, int print) { struct brom_layout_header *bh; @@ -504,6 +568,8 @@ static int mtk_image_verify_header(unsigned char *ptr, int image_size, if (is_mtk_nand_header(ptr)) return mtk_image_verify_nand_header(ptr, 0); + else if (!strcmp((char *)ptr, UFS_BOOT_NAME)) + return mtk_image_verify_ufs_header(ptr, 0); else return mtk_image_verify_gen_header(ptr, 0); @@ -530,6 +596,8 @@ static void mtk_image_print_header(const void *ptr, struct image_tool_params *pa if (is_mtk_nand_header(ptr)) mtk_image_verify_nand_header(ptr, 1); + else if (!strcmp((char *)ptr, UFS_BOOT_NAME)) + mtk_image_verify_ufs_header(ptr, 1); else mtk_image_verify_gen_header(ptr, 1); } @@ -658,6 +726,33 @@ static void mtk_image_set_gen_header(void *ptr, off_t filesize, filesize - sizeof(struct gen_device_header) - SHA256_SUM_LEN); } +static void mtk_image_set_ufs_header(void *ptr, off_t filesize, + uint32_t loadaddr) +{ + struct ufs_device_header *hdr = (struct ufs_device_header *)ptr; + struct gfh_header *gfh; + + /* Generic device header */ + snprintf(hdr->boot.name, sizeof(hdr->boot.name), "%s", UFS_BOOT_NAME); + hdr->boot.version = cpu_to_le32(1); + hdr->boot.size = cpu_to_le32(sizeof(*hdr)); + + /* BRLYT header */ + put_brom_layout_header(&hdr->brlyt, hdr_media); + hdr->brlyt.header_size = cpu_to_le32(hdr_offset + sizeof(*hdr)); + hdr->brlyt.total_size = cpu_to_le32(hdr_offset + filesize); + hdr->brlyt.header_size_2 = hdr->brlyt.header_size; + hdr->brlyt.total_size_2 = hdr->brlyt.total_size; + + /* GFH header */ + gfh = (struct gfh_header *)(ptr + sizeof(*hdr)); + put_ghf_header(gfh, filesize, sizeof(*hdr), + loadaddr, GFH_FLASH_TYPE_GEN); + + /* Generate SHA256 hash */ + put_hash((uint8_t *)gfh, filesize - sizeof(*hdr) - SHA256_SUM_LEN); +} + static void mtk_image_set_nand_header(void *ptr, off_t filesize, uint32_t loadaddr) { @@ -754,6 +849,8 @@ static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd, if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) mtk_image_set_nand_header(ptr, sbuf->st_size, params->addr); + else if (hdr_media == BRLYT_TYPE_UFS) + mtk_image_set_ufs_header(ptr, sbuf->st_size, params->addr); else mtk_image_set_gen_header(ptr, sbuf->st_size, params->addr); } diff --git a/tools/mtk_image.h b/tools/mtk_image.h index 54a838de863..8b4a601aec6 100644 --- a/tools/mtk_image.h +++ b/tools/mtk_image.h @@ -11,7 +11,7 @@ /* Device header definitions, all fields are little-endian */ -/* Header for NOR/SD/eMMC */ +/* Header for NOR/SD/eMMC/UFS */ union gen_boot_header { struct { char name[12]; @@ -25,6 +25,7 @@ union gen_boot_header { #define EMMC_BOOT_NAME "EMMC_BOOT" #define SF_BOOT_NAME "SF_BOOT" #define SDMMC_BOOT_NAME "SDMMC_BOOT" +#define UFS_BOOT_NAME "UFS_BOOT" /* BootROM layout header */ struct brom_layout_header { @@ -48,7 +49,8 @@ enum brlyt_img_type { BRLYT_TYPE_EMMC = 0x10005, BRLYT_TYPE_NOR = 0x10007, BRLYT_TYPE_SDMMC = 0x10008, - BRLYT_TYPE_SNAND = 0x10009 + BRLYT_TYPE_SNAND = 0x10009, + BRLYT_TYPE_UFS = 0x1000c }; /* Combined device header for NOR/SD/eMMC */ @@ -61,6 +63,16 @@ struct gen_device_header { }; }; +/* Device header for UFS */ +struct ufs_device_header { + union gen_boot_header boot; + + union { + struct brom_layout_header brlyt; + uint8_t brlyt_pad[0xE00]; + }; +}; + /* BootROM header definitions */ struct gfh_common_header { uint32_t magic_version; -- 2.53.0
