Commit b7a7aca466bf18625ab0d84999453e4a5685b751

Authored by Dan Nica
Committed by Larisa Grigore
1 parent 144ff8b965

mkimage: Add a dedicated 's32v234image'

Create a dedicated s32v234image.

Signed-off-by: Dan Nica <dan.nica@nxp.com>

Showing 10 changed files with 350 additions and 2 deletions Side-by-side Diff

arch/arm/include/asm/arch-s32v234/mc_cgm_regs.h
1 1 /* SPDX-License-Identifier: GPL-2.0+ */
2 2 /*
3 3 * (C) Copyright 2015, Freescale Semiconductor, Inc.
  4 + * (C) Copyright 2020 NXP
4 5 */
5 6  
6 7 #ifndef __ARCH_ARM_MACH_S32V234_MCCGM_REGS_H__
... ... @@ -165,6 +166,9 @@
165 166 #define DFS_MAXNUMBER (4)
166 167  
167 168 #define DFS_PARAMS_Nr (3)
  169 +
  170 +#define FXOSC_CTL (MC_CGM0_BASE_ADDR + 0x280)
  171 +#define FXOSC_CTL_FASTBOOT_VALUE (0x018020f0)
168 172  
169 173 /* Frequencies are in Hz */
170 174 #define FIRC_CLK_FREQ (48000000)
arch/arm/include/asm/arch-s32v234/mc_me_regs.h
1 1 /* SPDX-License-Identifier: GPL-2.0+ */
2 2 /*
3 3 * (C) Copyright 2015, Freescale Semiconductor, Inc.
  4 + * (C) Copyright 2020 NXP
  5 + *
4 6 */
5 7  
6 8 #ifndef __ARCH_ARM_MACH_S32V234_MCME_REGS_H__
... ... @@ -90,6 +92,10 @@
90 92 #define MC_ME_RUNMODE_MC_PWRLVL0 (1 << 28)
91 93 #define MC_ME_RUNMODE_MC_PWRLVL1 (1 << 29)
92 94 #define MC_ME_RUNMODE_MC_PWRLVL2 (1 << 30)
  95 +
  96 +#define DRUN_MC_RESETVAL (0x00100010)
  97 +#define SYSCLK_FXOSC (1 << 0)
  98 +#define SYSCLK_ARM_PLL_DFS_1 BIT(1)
93 99  
94 100 /* MC_ME_DRUN_SEC_CC_I */
95 101 #define MC_ME_DRUN_SEC_CC_I (MC_ME_BASE_ADDR + 0x260)
arch/arm/mach-s32/Kconfig
  1 +# SPDX-License-Identifier: GPL-2.0+
  2 +# Copyright 2020 NXP
  3 +
1 4 config IMX_CONFIG
2 5 string
  6 +
  7 +config MKIMAGE_T
  8 + string
  9 + default "s32v234image"
  10 + depends on ARCH_S32V234
arch/arm/mach-s32/Makefile
... ... @@ -16,7 +16,8 @@
16 16 $(Q)mkdir -p $(dir $@)
17 17 $(call if_changed_dep,cpp_cfg)
18 18  
19   -MKIMAGEFLAGS_u-boot.s32 = -n $(filter-out $< $(PHONY),$^) -T imximage \
  19 +MKIMAGEFLAGS_u-boot.s32 = -n $(filter-out $< $(PHONY),$^) \
  20 + -T $(CONFIG_MKIMAGE_T) \
20 21 -e $(CONFIG_SYS_TEXT_BASE)
21 22 u-boot.s32: MKIMAGEOUTPUT = u-boot.s32.log
22 23  
... ... @@ -153,6 +153,7 @@
153 153 { IH_TYPE_KERNEL_NOLOAD, "kernel_noload", "Kernel Image (no loading done)", },
154 154 { IH_TYPE_KWBIMAGE, "kwbimage", "Kirkwood Boot Image",},
155 155 { IH_TYPE_IMXIMAGE, "imximage", "Freescale i.MX Boot Image",},
  156 + { IH_TYPE_S32V234IMAGE, "s32v234image", "NXP S32V234 Boot Image",},
156 157 { IH_TYPE_IMX8IMAGE, "imx8image", "NXP i.MX8 Boot Image",},
157 158 { IH_TYPE_IMX8MIMAGE, "imx8mimage", "NXP i.MX8M Boot Image",},
158 159 { IH_TYPE_INVALID, "invalid", "Invalid Image", },
configs/s32v234evb_defconfig
... ... @@ -5,7 +5,6 @@
5 5 CONFIG_ENV_OFFSET=0xC0000
6 6 CONFIG_NR_DRAM_BANKS=1
7 7 CONFIG_DISTRO_DEFAULTS=y
8   -CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/s32v234evb/s32v234evb.cfg"
9 8 CONFIG_USE_BOOTARGS=y
10 9 CONFIG_BOOTARGS="console=ttyLF0 root=/dev/ram rw"
11 10 CONFIG_BOARD_EARLY_INIT_F=y
... ... @@ -260,6 +260,7 @@
260 260 IH_TYPE_FLATDT, /* Binary Flat Device Tree Blob */
261 261 IH_TYPE_KWBIMAGE, /* Kirkwood Boot Image */
262 262 IH_TYPE_IMXIMAGE, /* Freescale IMXBoot Image */
  263 + IH_TYPE_S32V234IMAGE, /* NXP S32V234 Boot Image */
263 264 IH_TYPE_UBLIMAGE, /* Davinci UBL Image */
264 265 IH_TYPE_OMAPIMAGE, /* TI OMAP Config Header Image */
265 266 IH_TYPE_AISIMAGE, /* TI Davinci AIS Image */
... ... @@ -61,6 +61,8 @@
61 61 FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o
62 62 FIT_CIPHER_OBJS-$(CONFIG_FIT_CIPHER) := common/image-cipher.o
63 63  
  64 +S32V234IMAGE-$(CONFIG_S32V234) := s32v234image.o
  65 +
64 66 # The following files are synced with upstream DTC.
65 67 # Use synced versions from scripts/dtc/libfdt/.
66 68 LIBFDT_SRCS_SYNCED := fdt.c fdt_wip.c fdt_sw.c fdt_rw.c \
... ... @@ -95,6 +97,7 @@
95 97 common/image.o \
96 98 imagetool.o \
97 99 imximage.o \
  100 + $(S32V234IMAGE-y) \
98 101 imx8image.o \
99 102 imx8mimage.o \
100 103 kwbimage.o \
tools/s32v234image.c
  1 +// SPDX-License-Identifier: GPL-2.0+
  2 +/* Copyright 2019-2020 NXP */
  3 +
  4 +#include <image.h>
  5 +#include <generated/autoconf.h>
  6 +#include <config.h>
  7 +#include "imagetool.h"
  8 +#include "s32v234image.h"
  9 +#include <asm/arch/mc_me_regs.h>
  10 +#include <asm/arch/mc_cgm_regs.h>
  11 +
  12 +#define S32V234_AUTO_OFFSET ((size_t)(-1))
  13 +
  14 +#define S32V234_IVT_OFFSET 0x1000U
  15 +#define S32V234_HEADER_SIZE 0x1000U
  16 +#define S32V234_INITLOAD_SIZE 0x2000U
  17 +
  18 +static struct program_image image_layout = {
  19 + .ivt = {
  20 + /* The offset is actually 0x1000, but we do not
  21 + * want to integrate it in the generated image.
  22 + * This allows writing the image at 0x1000 on
  23 + * sdcard/qspi, which avoids overwriting the
  24 + * partition table.
  25 + */
  26 + .offset = 0x0,
  27 + .size = sizeof(struct ivt),
  28 + },
  29 + .boot_data = {
  30 + .offset = S32V234_AUTO_OFFSET,
  31 + .alignment = 0x8U,
  32 + .size = sizeof(struct boot_data),
  33 + },
  34 + .dcd = {
  35 + .offset = S32V234_AUTO_OFFSET,
  36 + .alignment = 0x8U,
  37 + .size = DCD_MAXIMUM_SIZE,
  38 + },
  39 +};
  40 +
  41 +static uint32_t dcd_data[] = {
  42 + DCD_HEADER,
  43 + DCD_WRITE_HEADER(4, PARAMS_BYTES(4)),
  44 + DCD_ADDR(FXOSC_CTL), DCD_MASK(FXOSC_CTL_FASTBOOT_VALUE),
  45 +
  46 + DCD_ADDR(MC_ME_DRUN_MC),
  47 + DCD_MASK(DRUN_MC_RESETVAL | MC_ME_RUNMODE_MC_XOSCON |
  48 + MC_ME_RUNMODE_MC_SYSCLK(SYSCLK_FXOSC)),
  49 +
  50 + DCD_ADDR(MC_ME_MCTL),
  51 + DCD_MASK(MC_ME_MCTL_KEY | MC_ME_MCTL_DRUN),
  52 + DCD_ADDR(MC_ME_MCTL),
  53 + DCD_MASK(MC_ME_MCTL_INVERTEDKEY | MC_ME_MCTL_DRUN),
  54 +};
  55 +
  56 +static struct ivt *get_ivt(struct program_image *image)
  57 +{
  58 + return (struct ivt *)image->ivt.data;
  59 +}
  60 +
  61 +static uint8_t *get_dcd(struct program_image *image)
  62 +{
  63 + return image->dcd.data;
  64 +}
  65 +
  66 +static struct boot_data *get_boot_data(struct program_image *image)
  67 +{
  68 + return (struct boot_data *)image->boot_data.data;
  69 +}
  70 +
  71 +static void s32gen1_print_header(const void *header)
  72 +{
  73 +}
  74 +
  75 +static void set_data_pointers(struct program_image *layout, void *header)
  76 +{
  77 + uint8_t *data = (uint8_t *)header;
  78 +
  79 + layout->ivt.data = data + layout->ivt.offset;
  80 + layout->boot_data.data = data + layout->boot_data.offset;
  81 + layout->dcd.data = data + layout->dcd.offset;
  82 +}
  83 +
  84 +static void s32gen1_set_header(void *header, struct stat *sbuf, int unused,
  85 + struct image_tool_params *tool_params)
  86 +{
  87 + uint8_t *dcd;
  88 + struct ivt *ivt;
  89 + struct boot_data *boot_data;
  90 +
  91 + set_data_pointers(&image_layout, header);
  92 +
  93 + dcd = get_dcd(&image_layout);
  94 + if (sizeof(dcd_data) > DCD_MAXIMUM_SIZE) {
  95 + fprintf(stderr, "DCD exceeds the maximum size\n");
  96 + exit(EXIT_FAILURE);
  97 + }
  98 + memcpy(dcd, &dcd_data[0], sizeof(dcd_data));
  99 + *(uint16_t *)(dcd + DCD_HEADER_LENGTH_OFFSET) =
  100 + cpu_to_be16(sizeof(dcd_data));
  101 +
  102 + ivt = get_ivt(&image_layout);
  103 + ivt->tag = IVT_TAG;
  104 + ivt->length = cpu_to_be16(sizeof(struct ivt));
  105 + ivt->version = IVT_VERSION;
  106 + ivt->entry = CONFIG_SYS_TEXT_BASE;
  107 + ivt->self = ivt->entry - S32V234_INITLOAD_SIZE + S32V234_IVT_OFFSET;
  108 + ivt->dcd_pointer = ivt->self + image_layout.dcd.offset;
  109 + ivt->boot_data_pointer = ivt->self + image_layout.boot_data.offset;
  110 +
  111 + boot_data = get_boot_data(&image_layout);
  112 + boot_data->start = ivt->entry - S32V234_INITLOAD_SIZE;
  113 + boot_data->length = ROUND(sbuf->st_size + S32V234_INITLOAD_SIZE,
  114 + 0x1000);
  115 +}
  116 +
  117 +static int s32gen1_check_image_type(uint8_t type)
  118 +{
  119 + if (type == IH_TYPE_S32V234IMAGE)
  120 + return EXIT_SUCCESS;
  121 + else
  122 + return EXIT_FAILURE;
  123 +}
  124 +
  125 +static int image_parts_comp(const void *p1, const void *p2)
  126 +{
  127 + const struct image_comp **part1 = (typeof(part1))p1;
  128 + const struct image_comp **part2 = (typeof(part2))p2;
  129 +
  130 + if ((*part2)->offset > (*part1)->offset)
  131 + return -1;
  132 +
  133 + if ((*part2)->offset < (*part1)->offset)
  134 + return 1;
  135 +
  136 + return 0;
  137 +}
  138 +
  139 +static void check_overlap(struct image_comp *comp1,
  140 + struct image_comp *comp2)
  141 +{
  142 + size_t end1 = comp1->offset + comp1->size;
  143 + size_t end2 = comp2->offset + comp2->size;
  144 +
  145 + if (end1 > comp2->offset && end2 > comp1->offset) {
  146 + fprintf(stderr, "Detected overlap between 0x%zx@0x%zx and "
  147 + "0x%zx@0x%zx\n",
  148 + comp1->size, comp1->offset,
  149 + comp2->size, comp2->offset);
  150 + exit(EXIT_FAILURE);
  151 + }
  152 +}
  153 +
  154 +static void s32g2xx_compute_dyn_offsets(struct image_comp **parts,
  155 + size_t n_parts)
  156 +{
  157 + size_t i;
  158 + size_t align_mask;
  159 + size_t rem;
  160 +
  161 + for (i = 0U; i < n_parts; i++) {
  162 + if (parts[i]->offset == S32V234_AUTO_OFFSET) {
  163 + if (i == 0) {
  164 + parts[i]->offset = 0U;
  165 + continue;
  166 + }
  167 +
  168 + parts[i]->offset = parts[i - 1]->offset +
  169 + parts[i - 1]->size;
  170 + }
  171 +
  172 + /* Apply alignment constraints */
  173 + if (parts[i]->alignment != 0U) {
  174 + align_mask = parts[i]->alignment - 1U;
  175 + rem = parts[i]->offset & align_mask;
  176 + if (rem != 0U) {
  177 + parts[i]->offset -= rem;
  178 + parts[i]->offset += parts[i]->alignment;
  179 + }
  180 + }
  181 +
  182 + if (i != 0)
  183 + check_overlap(parts[i - 1], parts[i]);
  184 + }
  185 +}
  186 +
  187 +static int s32g2xx_build_layout(struct program_image *program_image,
  188 + size_t *header_size, void **image)
  189 +{
  190 + uint8_t *image_layout;
  191 + struct image_comp *parts[] = {&program_image->ivt,
  192 + &program_image->boot_data,
  193 + &program_image->dcd,
  194 + };
  195 + size_t last_comp = ARRAY_SIZE(parts) - 1;
  196 +
  197 + program_image->dcd.size = sizeof(dcd_data);
  198 +
  199 + qsort(&parts[0], ARRAY_SIZE(parts), sizeof(parts[0]), image_parts_comp);
  200 +
  201 + /* Compute auto-offsets */
  202 + s32g2xx_compute_dyn_offsets(parts, ARRAY_SIZE(parts));
  203 +
  204 + *header_size = S32V234_HEADER_SIZE;
  205 + if (parts[last_comp]->offset + parts[last_comp]->size > *header_size) {
  206 + perror("S32V234 Header is too large");
  207 + exit(EXIT_FAILURE);
  208 + }
  209 +
  210 + image_layout = calloc(*header_size, sizeof(*image_layout));
  211 + if (!image_layout) {
  212 + perror("Call to calloc() failed");
  213 + return -ENOMEM;
  214 + }
  215 +
  216 + *image = image_layout;
  217 + return 0;
  218 +}
  219 +
  220 +static int s32gen1_vrec_header(struct image_tool_params *tool_params,
  221 + struct image_type_params *type_params)
  222 +{
  223 + size_t header_size;
  224 + void *image = NULL;
  225 +
  226 + s32g2xx_build_layout(&image_layout, &header_size, &image);
  227 + type_params->header_size = header_size;
  228 + type_params->hdr = image;
  229 +
  230 + return 0;
  231 +}
  232 +
  233 +U_BOOT_IMAGE_TYPE(
  234 + s32v2image,
  235 + "NXP S32V234 Boot Image",
  236 + 0,
  237 + NULL,
  238 + NULL,
  239 + NULL,
  240 + s32gen1_print_header,
  241 + s32gen1_set_header,
  242 + NULL,
  243 + s32gen1_check_image_type,
  244 + NULL,
  245 + s32gen1_vrec_header
  246 +);
tools/s32v234image.h
  1 +/* SPDX-License-Identifier: GPL-2.0+ */
  2 +/* Copyright 2019-2020 NXP */
  3 +
  4 +#ifndef S32V234IMAGE_H
  5 +#define S32V234IMAGE_H
  6 +
  7 +#include <asm/types.h>
  8 +#include <generated/autoconf.h>
  9 +
  10 +#define DCD_HEADER (0x500000d2)
  11 +#define DCD_MAXIMUM_SIZE (8192)
  12 +#define DCD_HEADER_LENGTH_OFFSET (1)
  13 +
  14 +#define DCD_COMMAND_HEADER(tag, len, params) ((tag) | \
  15 + (cpu_to_be16((len)) << 8) | \
  16 + (params) << 24)
  17 +#define DCD_WRITE_TAG (0xcc)
  18 +#define DCD_CHECK_TAG (0xcf)
  19 +#define DCD_NOP_TAG (0xc0)
  20 +
  21 +#define PARAMS_DATA_SET BIT(4)
  22 +#define PARAMS_DATA_MASK BIT(3)
  23 +#define PARAMS_BYTES(x) ((x) & 0x7)
  24 +
  25 +#define DCD_WRITE_HEADER(n, params) DCD_COMMAND_HEADER(DCD_WRITE_TAG, \
  26 + 4 + (n) * 8, \
  27 + (params))
  28 +#define DCD_CHECK_HEADER(params) DCD_COMMAND_HEADER(DCD_CHECK_TAG, \
  29 + 16, \
  30 + (params))
  31 +#define DCD_CHECK_HEADER_NO_COUNT(params) \
  32 + DCD_COMMAND_HEADER(DCD_CHECK_TAG, \
  33 + 12, \
  34 + (params))
  35 +#define DCD_NOP_HEADER DCD_COMMAND_HEADER(DCD_NOP_TAG, 4, 0)
  36 +
  37 +#define DCD_ADDR(x) cpu_to_be32((x))
  38 +#define DCD_MASK(x) cpu_to_be32((x))
  39 +#define DCD_COUNT(x) cpu_to_be32((x))
  40 +
  41 +#define IVT_TAG 0xd1
  42 +#define IVT_VERSION 0x50
  43 +
  44 +struct ivt {
  45 + __u8 tag;
  46 + __u16 length;
  47 + __u8 version;
  48 + __u32 entry;
  49 + __u32 reserved1;
  50 + __u32 dcd_pointer;
  51 + __u32 boot_data_pointer;
  52 + __u32 self;
  53 + __u32 reserved2;
  54 + __u32 self_test;
  55 + __u32 reserved3;
  56 + __u32 reserved4;
  57 +} __attribute((packed));
  58 +
  59 +struct boot_data {
  60 + __u32 start;
  61 + __u32 length;
  62 + __u8 reserved2[4];
  63 +} __packed;
  64 +
  65 +struct image_comp {
  66 + size_t offset;
  67 + size_t size;
  68 + size_t alignment;
  69 + uint8_t *data;
  70 +};
  71 +
  72 +struct program_image {
  73 + struct image_comp ivt;
  74 + struct image_comp boot_data;
  75 + struct image_comp dcd;
  76 + __u8 *header;
  77 +};
  78 +
  79 +#endif /* S32V234IMAGE_H */