]>
Commit | Line | Data |
---|---|---|
3decb14a JR |
1 | /* |
2 | * (C) Copyright 2010 | |
3 | * Linaro LTD, www.linaro.org | |
4 | * Author: John Rigby <[email protected]> | |
5 | * Based on TI's signGP.c | |
6 | * | |
7 | * (C) Copyright 2009 | |
8 | * Stefano Babic, DENX Software Engineering, [email protected]. | |
9 | * | |
10 | * (C) Copyright 2008 | |
11 | * Marvell Semiconductor <www.marvell.com> | |
12 | * Written-by: Prafulla Wadaskar <[email protected]> | |
13 | * | |
3765b3e7 | 14 | * SPDX-License-Identifier: GPL-2.0+ |
3decb14a JR |
15 | */ |
16 | ||
f86ed6a8 | 17 | #include "imagetool.h" |
3decb14a JR |
18 | #include <image.h> |
19 | #include "omapimage.h" | |
20 | ||
21 | /* Header size is CH header rounded up to 512 bytes plus GP header */ | |
22 | #define OMAP_CH_HDR_SIZE 512 | |
23 | #define OMAP_GP_HDR_SIZE (sizeof(struct gp_header)) | |
24 | #define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE+OMAP_GP_HDR_SIZE) | |
25 | ||
79b9ebb7 TR |
26 | static int do_swap32 = 0; |
27 | ||
28 | static uint32_t omapimage_swap32(uint32_t data) | |
29 | { | |
30 | uint32_t result = 0; | |
31 | result = (data & 0xFF000000) >> 24; | |
32 | result |= (data & 0x00FF0000) >> 8; | |
33 | result |= (data & 0x0000FF00) << 8; | |
34 | result |= (data & 0x000000FF) << 24; | |
35 | return result; | |
36 | } | |
37 | ||
3decb14a JR |
38 | static uint8_t omapimage_header[OMAP_FILE_HDR_SIZE]; |
39 | ||
40 | static int omapimage_check_image_types(uint8_t type) | |
41 | { | |
42 | if (type == IH_TYPE_OMAPIMAGE) | |
43 | return EXIT_SUCCESS; | |
44 | else { | |
3decb14a JR |
45 | return EXIT_FAILURE; |
46 | } | |
47 | } | |
48 | ||
49 | /* | |
50 | * Only the simplest image type is currently supported: | |
51 | * TOC pointing to CHSETTINGS | |
52 | * TOC terminator | |
53 | * CHSETTINGS | |
54 | * | |
55 | * padding to OMAP_CH_HDR_SIZE bytes | |
56 | * | |
57 | * gp header | |
58 | * size | |
59 | * load_addr | |
60 | */ | |
61 | static int valid_gph_size(uint32_t size) | |
62 | { | |
63 | return size; | |
64 | } | |
65 | ||
66 | static int valid_gph_load_addr(uint32_t load_addr) | |
67 | { | |
68 | return load_addr; | |
69 | } | |
70 | ||
71 | static int omapimage_verify_header(unsigned char *ptr, int image_size, | |
f86ed6a8 | 72 | struct image_tool_params *params) |
3decb14a JR |
73 | { |
74 | struct ch_toc *toc = (struct ch_toc *)ptr; | |
75 | struct gp_header *gph = (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE); | |
79b9ebb7 | 76 | uint32_t offset, size, gph_size, gph_load_addr; |
3decb14a JR |
77 | |
78 | while (toc->section_offset != 0xffffffff | |
79 | && toc->section_size != 0xffffffff) { | |
79b9ebb7 TR |
80 | if (do_swap32) { |
81 | offset = omapimage_swap32(toc->section_offset); | |
82 | size = omapimage_swap32(toc->section_size); | |
83 | } else { | |
84 | offset = toc->section_offset; | |
85 | size = toc->section_size; | |
86 | } | |
3decb14a JR |
87 | if (!offset || !size) |
88 | return -1; | |
89 | if (offset >= OMAP_CH_HDR_SIZE || | |
90 | offset+size >= OMAP_CH_HDR_SIZE) | |
91 | return -1; | |
92 | toc++; | |
93 | } | |
79b9ebb7 TR |
94 | |
95 | if (do_swap32) { | |
96 | gph_size = omapimage_swap32(gph->size); | |
97 | gph_load_addr = omapimage_swap32(gph->load_addr); | |
98 | } else { | |
99 | gph_size = gph->size; | |
100 | gph_load_addr = gph->load_addr; | |
101 | } | |
102 | ||
103 | if (!valid_gph_size(gph_size)) | |
3decb14a | 104 | return -1; |
79b9ebb7 | 105 | if (!valid_gph_load_addr(gph_load_addr)) |
3decb14a JR |
106 | return -1; |
107 | ||
108 | return 0; | |
109 | } | |
110 | ||
111 | static void omapimage_print_section(struct ch_settings *chs) | |
112 | { | |
113 | const char *section_name; | |
114 | ||
115 | if (chs->section_key) | |
116 | section_name = "CHSETTINGS"; | |
117 | else | |
118 | section_name = "UNKNOWNKEY"; | |
119 | ||
120 | printf("%s (%x) " | |
121 | "valid:%x " | |
122 | "version:%x " | |
123 | "reserved:%x " | |
124 | "flags:%x\n", | |
125 | section_name, | |
126 | chs->section_key, | |
127 | chs->valid, | |
128 | chs->version, | |
129 | chs->reserved, | |
130 | chs->flags); | |
131 | } | |
132 | ||
133 | static void omapimage_print_header(const void *ptr) | |
134 | { | |
135 | const struct ch_toc *toc = (struct ch_toc *)ptr; | |
136 | const struct gp_header *gph = | |
137 | (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE); | |
79b9ebb7 | 138 | uint32_t offset, size, gph_size, gph_load_addr; |
3decb14a JR |
139 | |
140 | while (toc->section_offset != 0xffffffff | |
141 | && toc->section_size != 0xffffffff) { | |
79b9ebb7 TR |
142 | if (do_swap32) { |
143 | offset = omapimage_swap32(toc->section_offset); | |
144 | size = omapimage_swap32(toc->section_size); | |
145 | } else { | |
146 | offset = toc->section_offset; | |
147 | size = toc->section_size; | |
148 | } | |
3decb14a JR |
149 | |
150 | if (offset >= OMAP_CH_HDR_SIZE || | |
151 | offset+size >= OMAP_CH_HDR_SIZE) | |
152 | exit(EXIT_FAILURE); | |
153 | ||
154 | printf("Section %s offset %x length %x\n", | |
155 | toc->section_name, | |
156 | toc->section_offset, | |
157 | toc->section_size); | |
158 | ||
159 | omapimage_print_section((struct ch_settings *)(ptr+offset)); | |
160 | toc++; | |
161 | } | |
162 | ||
79b9ebb7 TR |
163 | if (do_swap32) { |
164 | gph_size = omapimage_swap32(gph->size); | |
165 | gph_load_addr = omapimage_swap32(gph->load_addr); | |
166 | } else { | |
167 | gph_size = gph->size; | |
168 | gph_load_addr = gph->load_addr; | |
169 | } | |
170 | ||
171 | if (!valid_gph_size(gph_size)) { | |
172 | fprintf(stderr, "Error: invalid image size %x\n", gph_size); | |
3decb14a JR |
173 | exit(EXIT_FAILURE); |
174 | } | |
175 | ||
79b9ebb7 TR |
176 | if (!valid_gph_load_addr(gph_load_addr)) { |
177 | fprintf(stderr, "Error: invalid image load address %x\n", | |
178 | gph_load_addr); | |
3decb14a JR |
179 | exit(EXIT_FAILURE); |
180 | } | |
181 | ||
79b9ebb7 | 182 | printf("GP Header: Size %x LoadAddr %x\n", gph_size, gph_load_addr); |
3decb14a JR |
183 | } |
184 | ||
185 | static int toc_offset(void *hdr, void *member) | |
186 | { | |
187 | return member - hdr; | |
188 | } | |
189 | ||
190 | static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd, | |
f86ed6a8 | 191 | struct image_tool_params *params) |
3decb14a JR |
192 | { |
193 | struct ch_toc *toc = (struct ch_toc *)ptr; | |
194 | struct ch_settings *chs = (struct ch_settings *) | |
195 | (ptr + 2 * sizeof(*toc)); | |
196 | struct gp_header *gph = (struct gp_header *)(ptr + OMAP_CH_HDR_SIZE); | |
197 | ||
198 | toc->section_offset = toc_offset(ptr, chs); | |
199 | toc->section_size = sizeof(struct ch_settings); | |
200 | strcpy((char *)toc->section_name, "CHSETTINGS"); | |
201 | ||
202 | chs->section_key = KEY_CHSETTINGS; | |
203 | chs->valid = 0; | |
204 | chs->version = 1; | |
205 | chs->reserved = 0; | |
206 | chs->flags = 0; | |
207 | ||
208 | toc++; | |
209 | memset(toc, 0xff, sizeof(*toc)); | |
210 | ||
211 | gph->size = sbuf->st_size - OMAP_FILE_HDR_SIZE; | |
212 | gph->load_addr = params->addr; | |
79b9ebb7 TR |
213 | |
214 | if (strncmp(params->imagename, "byteswap", 8) == 0) { | |
215 | do_swap32 = 1; | |
216 | int swapped = 0; | |
217 | uint32_t *data = (uint32_t *)ptr; | |
218 | ||
219 | while (swapped <= (sbuf->st_size / sizeof(uint32_t))) { | |
220 | *data = omapimage_swap32(*data); | |
221 | swapped++; | |
222 | data++; | |
223 | } | |
224 | } | |
3decb14a JR |
225 | } |
226 | ||
f86ed6a8 | 227 | int omapimage_check_params(struct image_tool_params *params) |
3decb14a JR |
228 | { |
229 | return (params->dflag && (params->fflag || params->lflag)) || | |
230 | (params->fflag && (params->dflag || params->lflag)) || | |
231 | (params->lflag && (params->dflag || params->fflag)); | |
232 | } | |
233 | ||
234 | /* | |
235 | * omapimage parameters | |
236 | */ | |
237 | static struct image_type_params omapimage_params = { | |
238 | .name = "TI OMAP CH/GP Boot Image support", | |
239 | .header_size = OMAP_FILE_HDR_SIZE, | |
240 | .hdr = (void *)&omapimage_header, | |
241 | .check_image_type = omapimage_check_image_types, | |
242 | .verify_header = omapimage_verify_header, | |
243 | .print_header = omapimage_print_header, | |
244 | .set_header = omapimage_set_header, | |
245 | .check_params = omapimage_check_params, | |
246 | }; | |
247 | ||
248 | void init_omap_image_type(void) | |
249 | { | |
f86ed6a8 | 250 | register_image_type(&omapimage_params); |
3decb14a | 251 | } |