OLD | NEW |
1 /* | 1 /* |
2 * This file is part of the flashrom project. | 2 * This file is part of the flashrom project. |
3 * | 3 * |
4 * Copyright (C) 2005-2008 coresystems GmbH | 4 * Copyright (C) 2005-2008 coresystems GmbH |
5 * (Written by Stefan Reinauer <stepan@coresystems.de> for coresystems GmbH) | 5 * (Written by Stefan Reinauer <stepan@coresystems.de> for coresystems GmbH) |
6 * | 6 * |
7 * This program is free software; you can redistribute it and/or modify | 7 * This program is free software; you can redistribute it and/or modify |
8 * it under the terms of the GNU General Public License as published by | 8 * it under the terms of the GNU General Public License as published by |
9 * the Free Software Foundation; version 2 of the License. | 9 * the Free Software Foundation; version 2 of the License. |
10 * | 10 * |
(...skipping 21 matching lines...) Expand all Loading... |
32 #endif | 32 #endif |
33 static int romimages = 0; | 33 static int romimages = 0; |
34 | 34 |
35 #define MAX_ROMLAYOUT 64 | 35 #define MAX_ROMLAYOUT 64 |
36 | 36 |
37 typedef struct { | 37 typedef struct { |
38 unsigned int start; | 38 unsigned int start; |
39 unsigned int end; | 39 unsigned int end; |
40 unsigned int included; | 40 unsigned int included; |
41 char name[256]; | 41 char name[256]; |
| 42 char file[256]; /* file[0]=='\0' means not specified. */ |
42 } romlayout_t; | 43 } romlayout_t; |
43 | 44 |
44 static romlayout_t rom_entries[MAX_ROMLAYOUT]; | 45 static romlayout_t rom_entries[MAX_ROMLAYOUT]; |
45 | 46 |
46 #if CONFIG_INTERNAL == 1 /* FIXME: Move the whole block to cbtable.c? */ | 47 #if CONFIG_INTERNAL == 1 /* FIXME: Move the whole block to cbtable.c? */ |
47 static char *def_name = "DEFAULT"; | 48 static char *def_name = "DEFAULT"; |
48 | 49 |
49 int show_id(uint8_t *bios, int size, int force) | 50 int show_id(uint8_t *bios, int size, int force) |
50 { | 51 { |
51 unsigned int *walk; | 52 unsigned int *walk; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 tstr1 = strtok(tempstr, ":"); | 172 tstr1 = strtok(tempstr, ":"); |
172 tstr2 = strtok(NULL, ":"); | 173 tstr2 = strtok(NULL, ":"); |
173 if (!tstr1 || !tstr2) { | 174 if (!tstr1 || !tstr2) { |
174 msg_gerr("Error parsing layout file.\n"); | 175 msg_gerr("Error parsing layout file.\n"); |
175 fclose(romlayout); | 176 fclose(romlayout); |
176 return 1; | 177 return 1; |
177 } | 178 } |
178 rom_entries[romimages].start = strtol(tstr1, (char **)NULL, 16); | 179 rom_entries[romimages].start = strtol(tstr1, (char **)NULL, 16); |
179 rom_entries[romimages].end = strtol(tstr2, (char **)NULL, 16); | 180 rom_entries[romimages].end = strtol(tstr2, (char **)NULL, 16); |
180 rom_entries[romimages].included = 0; | 181 rom_entries[romimages].included = 0; |
| 182 strcpy(rom_entries[romimages].file, ""); |
181 romimages++; | 183 romimages++; |
182 } | 184 } |
183 | 185 |
184 for (i = 0; i < romimages; i++) { | 186 for (i = 0; i < romimages; i++) { |
185 msg_gdbg("romlayout %08x - %08x named %s\n", | 187 msg_gdbg("romlayout %08x - %08x named %s\n", |
186 rom_entries[i].start, | 188 rom_entries[i].start, |
187 rom_entries[i].end, rom_entries[i].name); | 189 rom_entries[i].end, rom_entries[i].name); |
188 } | 190 } |
189 | 191 |
190 fclose(romlayout); | 192 fclose(romlayout); |
191 | 193 |
192 return 0; | 194 return 0; |
193 } | 195 } |
194 #endif | 196 #endif |
195 | 197 |
196 int find_romentry(char *name) | 198 int find_romentry(char *name) |
197 { | 199 { |
198 int i; | 200 int i; |
| 201 char *file = NULL; |
199 | 202 |
200 if (!romimages) | 203 if (!romimages) |
201 return -1; | 204 return -1; |
202 | 205 |
203 » msg_gdbg("Looking for \"%s\"... ", name); | 206 » /* -i <image>[:<file>] */ |
| 207 » if (strtok(name, ":")) { |
| 208 » » file = strtok(NULL, ""); |
| 209 » } |
| 210 » msg_gdbg("Looking for \"%s\" (file=\"%s\")... ", |
| 211 » name, file ? file : "<not specified>"); |
204 | 212 |
205 for (i = 0; i < romimages; i++) { | 213 for (i = 0; i < romimages; i++) { |
206 if (!strcmp(rom_entries[i].name, name)) { | 214 if (!strcmp(rom_entries[i].name, name)) { |
207 rom_entries[i].included = 1; | 215 rom_entries[i].included = 1; |
| 216 snprintf(rom_entries[i].file, |
| 217 sizeof(rom_entries[i].file), |
| 218 "%s", file ? file : ""); |
208 msg_gdbg("found.\n"); | 219 msg_gdbg("found.\n"); |
209 return i; | 220 return i; |
210 } | 221 } |
211 } | 222 } |
212 msg_gdbg("not found.\n"); // Not found. Error. | 223 msg_gdbg("not found.\n"); // Not found. Error. |
213 | 224 |
214 return -1; | 225 return -1; |
215 } | 226 } |
216 | 227 |
217 int find_next_included_romentry(unsigned int start) | 228 int find_next_included_romentry(unsigned int start) |
(...skipping 14 matching lines...) Expand all Loading... |
232 return i; | 243 return i; |
233 /* Entry begins after start. */ | 244 /* Entry begins after start. */ |
234 if (best_start > rom_entries[i].start) { | 245 if (best_start > rom_entries[i].start) { |
235 best_start = rom_entries[i].start; | 246 best_start = rom_entries[i].start; |
236 best_entry = i; | 247 best_entry = i; |
237 } | 248 } |
238 } | 249 } |
239 return best_entry; | 250 return best_entry; |
240 } | 251 } |
241 | 252 |
| 253 static int read_content_from_file(int entry, uint8_t *newcontents) { |
| 254 char *file; |
| 255 FILE *fp; |
| 256 int len; |
| 257 |
| 258 /* If file name is specified for this partition, read file |
| 259 * content to overwrite. */ |
| 260 file = rom_entries[entry].file; |
| 261 len = rom_entries[entry].end - rom_entries[entry].start + 1; |
| 262 if (file[0]) { |
| 263 int numbytes; |
| 264 if ((fp = fopen(file, "rb")) == NULL) { |
| 265 perror(file); |
| 266 return -1; |
| 267 } |
| 268 numbytes = fread(newcontents + rom_entries[entry].start, |
| 269 1, len, fp); |
| 270 fclose(fp); |
| 271 if (numbytes == -1) { |
| 272 perror(file); |
| 273 return -1; |
| 274 } |
| 275 } |
| 276 return 0; |
| 277 } |
| 278 |
242 int handle_romentries(struct flashchip *flash, uint8_t *oldcontents, uint8_t *ne
wcontents) | 279 int handle_romentries(struct flashchip *flash, uint8_t *oldcontents, uint8_t *ne
wcontents) |
243 { | 280 { |
244 unsigned int start = 0; | 281 unsigned int start = 0; |
245 int entry; | 282 int entry; |
246 unsigned int size = flash->total_size * 1024; | 283 unsigned int size = flash->total_size * 1024; |
247 | 284 |
248 /* If no layout file was specified or the layout file was empty, assume | 285 /* If no layout file was specified or the layout file was empty, assume |
249 * that the user wants to flash the complete new image. | 286 * that the user wants to flash the complete new image. |
250 */ | 287 */ |
251 if (!romimages) | 288 if (!romimages) |
252 return 0; | 289 return 0; |
253 /* Non-included romentries are ignored. | 290 /* Non-included romentries are ignored. |
254 * The union of all included romentries is used from the new image. | 291 * The union of all included romentries is used from the new image. |
255 */ | 292 */ |
256 while (start < size) { | 293 while (start < size) { |
| 294 |
257 entry = find_next_included_romentry(start); | 295 entry = find_next_included_romentry(start); |
258 /* No more romentries for remaining region? */ | 296 /* No more romentries for remaining region? */ |
259 if (entry < 0) { | 297 if (entry < 0) { |
260 memcpy(newcontents + start, oldcontents + start, | 298 memcpy(newcontents + start, oldcontents + start, |
261 size - start); | 299 size - start); |
262 break; | 300 break; |
263 } | 301 } |
| 302 |
| 303 /* For non-included region, copy from old content. */ |
264 if (rom_entries[entry].start > start) | 304 if (rom_entries[entry].start > start) |
265 memcpy(newcontents + start, oldcontents + start, | 305 memcpy(newcontents + start, oldcontents + start, |
266 rom_entries[entry].start - start); | 306 rom_entries[entry].start - start); |
| 307 /* For included region, copy from file if specified. */ |
| 308 if (read_content_from_file(entry, newcontents) < 0) return -1; |
| 309 |
267 /* Skip to location after current romentry. */ | 310 /* Skip to location after current romentry. */ |
268 start = rom_entries[entry].end + 1; | 311 start = rom_entries[entry].end + 1; |
269 /* Catch overflow. */ | 312 /* Catch overflow. */ |
270 if (!start) | 313 if (!start) |
271 break; | 314 break; |
272 } | 315 } |
273 | 316 |
274 return 0; | 317 return 0; |
275 } | 318 } |
| 319 |
| 320 static int write_content_to_file(int entry, uint8_t *buf) { |
| 321 char *file; |
| 322 FILE *fp; |
| 323 int len = rom_entries[entry].end - rom_entries[entry].start + 1; |
| 324 |
| 325 file = rom_entries[entry].file; |
| 326 if (file[0]) { /* save to file if name is specified. */ |
| 327 int numbytes; |
| 328 if ((fp = fopen(file, "wb")) == NULL) { |
| 329 perror(file); |
| 330 return -1; |
| 331 } |
| 332 numbytes = fwrite(buf + rom_entries[entry].start, 1, len, fp); |
| 333 fclose(fp); |
| 334 if (numbytes != len) { |
| 335 perror(file); |
| 336 return -1; |
| 337 } |
| 338 } |
| 339 return 0; |
| 340 } |
| 341 |
| 342 int handle_partial_read( |
| 343 struct flashchip *flash, |
| 344 uint8_t *buf, |
| 345 int (*read) (struct flashchip *flash, uint8_t *buf, int start, int len)) { |
| 346 |
| 347 unsigned int start = 0; |
| 348 int entry; |
| 349 unsigned int size = flash->total_size * 1024; |
| 350 int count = 0; |
| 351 |
| 352 /* If no layout file was specified or the layout file was empty, assume |
| 353 * that the user wants to flash the complete new image. |
| 354 */ |
| 355 if (!romimages) |
| 356 return 0; |
| 357 /* Walk through the table and write content to file for those included |
| 358 * partition. */ |
| 359 while (start < size) { |
| 360 int len; |
| 361 |
| 362 entry = find_next_included_romentry(start); |
| 363 /* No more romentries for remaining region? */ |
| 364 if (entry < 0) { |
| 365 break; |
| 366 } |
| 367 ++count; |
| 368 |
| 369 /* read content from flash. */ |
| 370 len = rom_entries[entry].end - rom_entries[entry].start + 1; |
| 371 if (read(flash, buf + rom_entries[entry].start, |
| 372 rom_entries[entry].start, len)) { |
| 373 perror("flash partial read failed."); |
| 374 return -1; |
| 375 } |
| 376 /* If file is specified, write this partition to file. */ |
| 377 if (write_content_to_file(entry, buf) < 0) return -1; |
| 378 |
| 379 /* Skip to location after current romentry. */ |
| 380 start = rom_entries[entry].end + 1; |
| 381 /* Catch overflow. */ |
| 382 if (!start) |
| 383 break; |
| 384 } |
| 385 |
| 386 return count; |
| 387 } |
OLD | NEW |