Blame view
tools/s32v234image.c
7.15 KB
b7a7aca46 mkimage: Add a de... |
1 2 3 4 5 6 7 8 |
// SPDX-License-Identifier: GPL-2.0+ /* Copyright 2019-2020 NXP */ #include <image.h> #include <generated/autoconf.h> #include <config.h> #include "imagetool.h" #include "s32v234image.h" |
52297eca0 s32v234evb: Add D... |
9 |
#include <asm/arch/clock.h> |
b7a7aca46 mkimage: Add a de... |
10 11 12 13 |
#include <asm/arch/mc_me_regs.h> #include <asm/arch/mc_cgm_regs.h> #define S32V234_AUTO_OFFSET ((size_t)(-1)) |
7aff597da tools:s32v234: hy... |
14 15 16 17 18 19 20 21 |
#ifdef CONFIG_FLASH_BOOT # define S32V234_COMMAND_SEQ_FILL_OFF 20 #endif #ifdef CONFIG_FLASH_BOOT # define S32V234_QSPI_PARAMS_OFFSET 0x200U # define S32V234_QSPI_PARAMS_SIZE 0x200 #endif |
b7a7aca46 mkimage: Add a de... |
22 |
#define S32V234_IVT_OFFSET 0x1000U |
7aff597da tools:s32v234: hy... |
23 24 25 26 27 28 |
#ifdef CONFIG_FLASH_BOOT # define S32V234_HEADER_SIZE 0x2000U #else # define S32V234_HEADER_SIZE 0x1000U #endif |
b7a7aca46 mkimage: Add a de... |
29 |
#define S32V234_INITLOAD_SIZE 0x2000U |
52297eca0 s32v234evb: Add D... |
30 |
#define BIT(nr) (1UL << (nr)) |
b7a7aca46 mkimage: Add a de... |
31 |
static struct program_image image_layout = { |
7aff597da tools:s32v234: hy... |
32 33 34 35 36 37 |
#ifdef CONFIG_FLASH_BOOT .qspi_params = { .offset = S32V234_QSPI_PARAMS_OFFSET, .size = S32V234_QSPI_PARAMS_SIZE, }, #endif |
b7a7aca46 mkimage: Add a de... |
38 |
.ivt = { |
7aff597da tools:s32v234: hy... |
39 40 41 |
#ifdef CONFIG_FLASH_BOOT .offset = S32V234_IVT_OFFSET, #else |
b7a7aca46 mkimage: Add a de... |
42 43 44 45 46 47 48 |
/* The offset is actually 0x1000, but we do not * want to integrate it in the generated image. * This allows writing the image at 0x1000 on * sdcard/qspi, which avoids overwriting the * partition table. */ .offset = 0x0, |
7aff597da tools:s32v234: hy... |
49 |
#endif |
b7a7aca46 mkimage: Add a de... |
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
.size = sizeof(struct ivt), }, .boot_data = { .offset = S32V234_AUTO_OFFSET, .alignment = 0x8U, .size = sizeof(struct boot_data), }, .dcd = { .offset = S32V234_AUTO_OFFSET, .alignment = 0x8U, .size = DCD_MAXIMUM_SIZE, }, }; static uint32_t dcd_data[] = { DCD_HEADER, DCD_WRITE_HEADER(4, PARAMS_BYTES(4)), DCD_ADDR(FXOSC_CTL), DCD_MASK(FXOSC_CTL_FASTBOOT_VALUE), |
52297eca0 s32v234evb: Add D... |
68 69 70 71 72 73 74 |
#ifdef CONFIG_S32V234_FAST_BOOT DCD_ADDR(MC_ME_DRUN_MC), DCD_MASK(DRUN_MC_RESETVAL | MC_ME_RUNMODE_MC_XOSCON | MC_ME_RUNMODE_MC_PLL(ARM_PLL) | MC_ME_RUNMODE_MC_PLL(ENET_PLL) | MC_ME_RUNMODE_MC_SYSCLK(SYSCLK_ARM_PLL_DFS_1)), #else |
b7a7aca46 mkimage: Add a de... |
75 76 77 |
DCD_ADDR(MC_ME_DRUN_MC), DCD_MASK(DRUN_MC_RESETVAL | MC_ME_RUNMODE_MC_XOSCON | MC_ME_RUNMODE_MC_SYSCLK(SYSCLK_FXOSC)), |
52297eca0 s32v234evb: Add D... |
78 |
#endif |
b7a7aca46 mkimage: Add a de... |
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
DCD_ADDR(MC_ME_MCTL), DCD_MASK(MC_ME_MCTL_KEY | MC_ME_MCTL_DRUN), DCD_ADDR(MC_ME_MCTL), DCD_MASK(MC_ME_MCTL_INVERTEDKEY | MC_ME_MCTL_DRUN), }; static struct ivt *get_ivt(struct program_image *image) { return (struct ivt *)image->ivt.data; } static uint8_t *get_dcd(struct program_image *image) { return image->dcd.data; } static struct boot_data *get_boot_data(struct program_image *image) { return (struct boot_data *)image->boot_data.data; } |
b635eb592 s32v234image: Ren... |
100 |
static void s32v234_print_header(const void *header) |
b7a7aca46 mkimage: Add a de... |
101 102 |
{ } |
7aff597da tools:s32v234: hy... |
103 104 105 106 107 108 109 110 111 112 113 |
#ifdef CONFIG_FLASH_BOOT static struct qspi_params *get_qspi_params(struct program_image *image) { return (struct qspi_params *)image->qspi_params.data; } static void s32v234_set_qspi_params(struct qspi_params *qspi_params) { memcpy(qspi_params, &s32v234_qspi_params, sizeof(*qspi_params)); } #endif |
b7a7aca46 mkimage: Add a de... |
114 115 116 117 118 |
static void set_data_pointers(struct program_image *layout, void *header) { uint8_t *data = (uint8_t *)header; layout->ivt.data = data + layout->ivt.offset; |
7aff597da tools:s32v234: hy... |
119 120 121 |
#ifdef CONFIG_FLASH_BOOT layout->qspi_params.data = data + layout->qspi_params.offset; #endif |
b7a7aca46 mkimage: Add a de... |
122 123 124 |
layout->boot_data.data = data + layout->boot_data.offset; layout->dcd.data = data + layout->dcd.offset; } |
b635eb592 s32v234image: Ren... |
125 |
static void s32v234_set_header(void *header, struct stat *sbuf, int unused, |
b7a7aca46 mkimage: Add a de... |
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
struct image_tool_params *tool_params) { uint8_t *dcd; struct ivt *ivt; struct boot_data *boot_data; set_data_pointers(&image_layout, header); dcd = get_dcd(&image_layout); if (sizeof(dcd_data) > DCD_MAXIMUM_SIZE) { fprintf(stderr, "DCD exceeds the maximum size "); exit(EXIT_FAILURE); } memcpy(dcd, &dcd_data[0], sizeof(dcd_data)); *(uint16_t *)(dcd + DCD_HEADER_LENGTH_OFFSET) = cpu_to_be16(sizeof(dcd_data)); ivt = get_ivt(&image_layout); ivt->tag = IVT_TAG; ivt->length = cpu_to_be16(sizeof(struct ivt)); ivt->version = IVT_VERSION; ivt->entry = CONFIG_SYS_TEXT_BASE; ivt->self = ivt->entry - S32V234_INITLOAD_SIZE + S32V234_IVT_OFFSET; |
7aff597da tools:s32v234: hy... |
150 151 152 153 |
ivt->dcd_pointer = ivt->self + image_layout.dcd.offset - image_layout.ivt.offset; ivt->boot_data_pointer = ivt->self + image_layout.boot_data.offset - image_layout.ivt.offset; |
b7a7aca46 mkimage: Add a de... |
154 155 156 157 158 |
boot_data = get_boot_data(&image_layout); boot_data->start = ivt->entry - S32V234_INITLOAD_SIZE; boot_data->length = ROUND(sbuf->st_size + S32V234_INITLOAD_SIZE, 0x1000); |
7aff597da tools:s32v234: hy... |
159 160 161 |
#ifdef CONFIG_FLASH_BOOT s32v234_set_qspi_params(get_qspi_params(&image_layout)); #endif |
b7a7aca46 mkimage: Add a de... |
162 |
} |
b635eb592 s32v234image: Ren... |
163 |
static int s32v234_check_image_type(uint8_t type) |
b7a7aca46 mkimage: Add a de... |
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
{ if (type == IH_TYPE_S32V234IMAGE) return EXIT_SUCCESS; else return EXIT_FAILURE; } static int image_parts_comp(const void *p1, const void *p2) { const struct image_comp **part1 = (typeof(part1))p1; const struct image_comp **part2 = (typeof(part2))p2; if ((*part2)->offset > (*part1)->offset) return -1; if ((*part2)->offset < (*part1)->offset) return 1; return 0; } static void check_overlap(struct image_comp *comp1, struct image_comp *comp2) { size_t end1 = comp1->offset + comp1->size; size_t end2 = comp2->offset + comp2->size; if (end1 > comp2->offset && end2 > comp1->offset) { fprintf(stderr, "Detected overlap between 0x%zx@0x%zx and " "0x%zx@0x%zx ", comp1->size, comp1->offset, comp2->size, comp2->offset); exit(EXIT_FAILURE); } } |
b635eb592 s32v234image: Ren... |
200 |
static void s32v234_compute_dyn_offsets(struct image_comp **parts, |
b7a7aca46 mkimage: Add a de... |
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
size_t n_parts) { size_t i; size_t align_mask; size_t rem; for (i = 0U; i < n_parts; i++) { if (parts[i]->offset == S32V234_AUTO_OFFSET) { if (i == 0) { parts[i]->offset = 0U; continue; } parts[i]->offset = parts[i - 1]->offset + parts[i - 1]->size; } /* Apply alignment constraints */ if (parts[i]->alignment != 0U) { align_mask = parts[i]->alignment - 1U; rem = parts[i]->offset & align_mask; if (rem != 0U) { parts[i]->offset -= rem; parts[i]->offset += parts[i]->alignment; } } if (i != 0) check_overlap(parts[i - 1], parts[i]); } } |
b635eb592 s32v234image: Ren... |
232 |
static int s32v234_build_layout(struct program_image *program_image, |
b7a7aca46 mkimage: Add a de... |
233 234 235 236 237 238 |
size_t *header_size, void **image) { uint8_t *image_layout; struct image_comp *parts[] = {&program_image->ivt, &program_image->boot_data, &program_image->dcd, |
7aff597da tools:s32v234: hy... |
239 240 241 |
#ifdef CONFIG_FLASH_BOOT &program_image->qspi_params, #endif |
b7a7aca46 mkimage: Add a de... |
242 243 244 245 246 247 248 249 |
}; size_t last_comp = ARRAY_SIZE(parts) - 1; program_image->dcd.size = sizeof(dcd_data); qsort(&parts[0], ARRAY_SIZE(parts), sizeof(parts[0]), image_parts_comp); /* Compute auto-offsets */ |
b635eb592 s32v234image: Ren... |
250 |
s32v234_compute_dyn_offsets(parts, ARRAY_SIZE(parts)); |
b7a7aca46 mkimage: Add a de... |
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
*header_size = S32V234_HEADER_SIZE; if (parts[last_comp]->offset + parts[last_comp]->size > *header_size) { perror("S32V234 Header is too large"); exit(EXIT_FAILURE); } image_layout = calloc(*header_size, sizeof(*image_layout)); if (!image_layout) { perror("Call to calloc() failed"); return -ENOMEM; } *image = image_layout; return 0; } |
b635eb592 s32v234image: Ren... |
267 |
static int s32v234_vrec_header(struct image_tool_params *tool_params, |
b7a7aca46 mkimage: Add a de... |
268 269 270 271 |
struct image_type_params *type_params) { size_t header_size; void *image = NULL; |
b635eb592 s32v234image: Ren... |
272 |
s32v234_build_layout(&image_layout, &header_size, &image); |
b7a7aca46 mkimage: Add a de... |
273 274 275 276 277 278 279 280 281 282 283 284 285 |
type_params->header_size = header_size; type_params->hdr = image; return 0; } U_BOOT_IMAGE_TYPE( s32v2image, "NXP S32V234 Boot Image", 0, NULL, NULL, NULL, |
b635eb592 s32v234image: Ren... |
286 287 |
s32v234_print_header, s32v234_set_header, |
b7a7aca46 mkimage: Add a de... |
288 |
NULL, |
b635eb592 s32v234image: Ren... |
289 |
s32v234_check_image_type, |
b7a7aca46 mkimage: Add a de... |
290 |
NULL, |
b635eb592 s32v234image: Ren... |
291 |
s32v234_vrec_header |
b7a7aca46 mkimage: Add a de... |
292 |
); |