Commit b7a7aca466bf18625ab0d84999453e4a5685b751
Committed by
Larisa Grigore
1 parent
144ff8b965
Exists in
smarc_8mq_lf_v2020.04
and in
4 other branches
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
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 |
common/image.c
... | ... | @@ -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 |
include/image.h
... | ... | @@ -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 */ |
tools/Makefile
... | ... | @@ -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 */ |