<div class="gmail_quote">On Thu, Oct 28, 2010 at 10:29 PM, Carl-Daniel Hailfinger <span dir="ltr"><<a href="mailto:c-d.hailfinger.devel.2006@gmx.net">c-d.hailfinger.devel.2006@gmx.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

Index: flashrom-layout_exclude_unspecified_regions/layout.c<br>
===================================================================<br>
--- flashrom-layout_exclude_unspecified_regions/layout.c        (revision 1217)<br>
+++ flashrom-layout_exclude_unspecified_regions/layout.c        (working copy)<br>
@@ -22,6 +22,7 @@<br>
 #include <stdlib.h><br>
 #include <string.h><br>
 #include <ctype.h><br>
+#include <limits.h><br>
 #include "flash.h"<br>
 #include "programmer.h"<br>
<br>
@@ -205,33 +206,62 @@<br>
        return -1;<br>
 }<br>
<br>
-int handle_romentries(struct flashchip *flash, uint8_t *oldcontents, uint8_t *newcontents)<br>
+int find_next_included_romentry(unsigned int start)<br>
 {<br>
        int i;<br>
+       unsigned int best_start = INT_MAX;<br></blockquote><div><br></div><div>Minor nit: Should that be UINT_MAX? Alternatively, maybe ~0 would work without including limits.h.</div><div><br></div><div>Up to you.</div><div>

<br></div><meta http-equiv="content-type" content="text/html; charset=utf-8"><div>On Thu, Oct 28, 2010 at 10:29 PM, Carl-Daniel Hailfinger <span dir="ltr"><<a href="mailto:c-d.hailfinger.devel.2006@gmx.net">c-d.hailfinger.devel.2006@gmx.net</a>></span> wrote: </div>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
+       int best_entry = -1;<br>
<br>
-       // This function does not save flash write cycles.<br>
-       //<br>
-       // Also it does not cope with overlapping rom layout<br>
-       // sections.<br>
-       // example:<br>
-       // 00000000:00008fff gfxrom<br>
-       // 00009000:0003ffff normal<br>
-       // 00040000:0007ffff fallback<br>
-       // 00000000:0007ffff all<br>
-       //<br>
-       // If you'd specify -i all the included flag of all other<br>
-       // sections is still 0, so no changes will be made to the<br>
-       // flash. Same thing if you specify -i normal -i all only<br>
-       // normal will be updated and the rest will be kept.<br>
-<br>
+       /* First come, first serve for overlapping regions. */<br>
        for (i = 0; i < romimages; i++) {<br>
-               if (rom_entries[i].included)<br>
+               if (!rom_entries[i].included)<br>
                        continue;<br>
+               /* Already past the current entry? */<br>
+               if (start > rom_entries[i].end)<br>
+                       continue;<br>
+               /* Inside the current entry? */<br>
+               if (start >= rom_entries[i].start)<br>
+                       return i;<br>
+               /* Entry begins after start. */<br>
+               if (best_start > rom_entries[i].start) {<br>
+                       best_start = rom_entries[i].start;<br>
+                       best_entry = i;<br>
+               }<br>
+       }<br>
+       return best_entry;<br>
+}<br>
<br>
-               memcpy(newcontents + rom_entries[i].start,<br>
-                      oldcontents + rom_entries[i].start,<br>
-                      rom_entries[i].end - rom_entries[i].start + 1);<br>
+int handle_romentries(struct flashchip *flash, uint8_t *oldcontents, uint8_t *newcontents)<br>
+{<br>
+       unsigned int start = 0;<br>
+       int entry;<br>
+       unsigned int size = flash->total_size * 1024;<br>
+<br>
+       /* If no layout file was specified or the layout file was empty, assume<br>
+        * that the user wants to flash the complete new image.<br>
+        */<br>
+       if (!romimages)<br>
+               return 0;<br>
+       /* Non-included romentries are ignored.<br>
+        * The union of all included romentries is used from the new image.<br>
+        */<br>
+       while (start < size) {<br>
+               entry = find_next_included_romentry(start);<br>
+               /* No more romentries for remaining region? */<br>
+               if (entry < 0) {<br>
+                       memcpy(newcontents + start, oldcontents + start,<br>
+                              size - start);<br>
+                       break;<br>
+               }<br>
+               if (rom_entries[entry].start > start)<br>
+                       memcpy(newcontents + start, oldcontents + start,<br>
+                              rom_entries[entry].start - start);<br>
+               /* Skip to location after current romentry. */<br>
+               start = rom_entries[entry].end + 1;<br>
+               /* Catch overflow. */<br>
+               if (!start)<br>
+                       break;<br>
        }<br>
-<br>
+<br>
        return 0;<br>
 }</blockquote><div><br></div><div>Looks good to me. I've also tested this successfully, so:</div><div><br></div><div>Acked-by: David Hendricks <<a href="mailto:dhendrix@google.com">dhendrix@google.com</a>></div>

<div><br></div></div>-- <br>David Hendricks (dhendrix)<br>Systems Software Engineer, Google Inc.<br>