From 02e19cfdb6d1cf815b7a6f2c5f6524de1c1c4b73 Mon Sep 17 00:00:00 2001 From: hailfinger Date: Tue, 2 Nov 2010 03:12:51 +0000 Subject: Change semantics of image building in the layout code. If a layout file was specified, all regions not mentioned in the layout file were taken from the new image instead of being preserved. If regions overlap, the non-included regions won. New behaviour: If a layout file is specified, only the regions explicitly requested for inclusion will be taken from the new image. If regions overlap, the included regions win. Signed-off-by: Carl-Daniel Hailfinger Acked-by: David Hendricks git-svn-id: https://code.coreboot.org/svn/flashrom/trunk@1223 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- layout.c | 72 +++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/layout.c b/layout.c index b84368a..9ad2f5c 100644 --- a/layout.c +++ b/layout.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "flash.h" #include "programmer.h" @@ -205,33 +206,62 @@ int find_romentry(char *name) return -1; } -int handle_romentries(struct flashchip *flash, uint8_t *oldcontents, uint8_t *newcontents) +int find_next_included_romentry(unsigned int start) { int i; + unsigned int best_start = UINT_MAX; + int best_entry = -1; - // This function does not save flash write cycles. - // - // Also it does not cope with overlapping rom layout - // sections. - // example: - // 00000000:00008fff gfxrom - // 00009000:0003ffff normal - // 00040000:0007ffff fallback - // 00000000:0007ffff all - // - // If you'd specify -i all the included flag of all other - // sections is still 0, so no changes will be made to the - // flash. Same thing if you specify -i normal -i all only - // normal will be updated and the rest will be kept. - + /* First come, first serve for overlapping regions. */ for (i = 0; i < romimages; i++) { - if (rom_entries[i].included) + if (!rom_entries[i].included) continue; - - memcpy(newcontents + rom_entries[i].start, - oldcontents + rom_entries[i].start, - rom_entries[i].end - rom_entries[i].start + 1); + /* Already past the current entry? */ + if (start > rom_entries[i].end) + continue; + /* Inside the current entry? */ + if (start >= rom_entries[i].start) + return i; + /* Entry begins after start. */ + if (best_start > rom_entries[i].start) { + best_start = rom_entries[i].start; + best_entry = i; + } } + return best_entry; +} + +int handle_romentries(struct flashchip *flash, uint8_t *oldcontents, uint8_t *newcontents) +{ + unsigned int start = 0; + int entry; + unsigned int size = flash->total_size * 1024; + /* If no layout file was specified or the layout file was empty, assume + * that the user wants to flash the complete new image. + */ + if (!romimages) + return 0; + /* Non-included romentries are ignored. + * The union of all included romentries is used from the new image. + */ + while (start < size) { + entry = find_next_included_romentry(start); + /* No more romentries for remaining region? */ + if (entry < 0) { + memcpy(newcontents + start, oldcontents + start, + size - start); + break; + } + if (rom_entries[entry].start > start) + memcpy(newcontents + start, oldcontents + start, + rom_entries[entry].start - start); + /* Skip to location after current romentry. */ + start = rom_entries[entry].end + 1; + /* Catch overflow. */ + if (!start) + break; + } + return 0; } -- cgit v1.2.1