Author: stefanct
Date: Sun Aug 31 01:39:51 2014
New Revision: 1847
URL: http://flashrom.org/trac/flashrom/changeset/1847

Log:
Refine physical address mapping of flash chips.

 - Create distinct functions for mapping and unmapping for flash chips.
 - Map only when needed: map before probing and unmap immediately
   after it. Map again when a single chip was probed successfully before
   taking any actual actions and clean up afterwards.
 - Map special function chip registers centrally together with flash space
   instead of within (some) probing methods after successful probes.
 - Save the used base addresses of the mappings in struct flashctx as well.
 - Do not try to (un)map the zero-sized chip definitions that are merely hacks.
   This also fixes the printing of wrong warnings for these chip definitions
   introduced in r1765.

Signed-off-by: Stefan Tauner <[email protected]>
Acked-by: Carl-Daniel Hailfinger <[email protected]>

Modified:
   trunk/82802ab.c
   trunk/cli_classic.c
   trunk/flash.h
   trunk/flashrom.c
   trunk/jedec.c

Modified: trunk/82802ab.c
==============================================================================
--- trunk/82802ab.c     Wed Aug 20 20:56:35 2014        (r1846)
+++ trunk/82802ab.c     Sun Aug 31 01:39:51 2014        (r1847)
@@ -83,9 +83,6 @@
        if (id1 != flash->chip->manufacture_id || id2 != flash->chip->model_id)
                return 0;
 
-       if (flash->chip->feature_bits & FEATURE_REGISTERMAP)
-               map_flash_registers(flash);
-
        return 1;
 }
 

Modified: trunk/cli_classic.c
==============================================================================
--- trunk/cli_classic.c Wed Aug 20 20:56:35 2014        (r1846)
+++ trunk/cli_classic.c Sun Aug 31 01:39:51 2014        (r1847)
@@ -481,8 +481,14 @@
                                ret = 1;
                                goto out_shutdown;
                        }
+                       if (map_flash(&flashes[0]) != 0) {
+                               free(flashes[0].chip);
+                               ret = 1;
+                               goto out_shutdown;
+                       }
                        msg_cinfo("Please note that forced reads most likely 
contain garbage.\n");
                        ret = read_flash_to_file(&flashes[0], filename);
+                       unmap_flash(&flashes[0]);
                        free(flashes[0].chip);
                        goto out_shutdown;
                }
@@ -525,6 +531,12 @@
        if (write_it && !dont_verify_it)
                verify_it = 1;
 
+       /* Map the selected flash chip again. */
+       if (map_flash(fill_flash) != 0) {
+               ret = 1;
+               goto out_shutdown;
+       }
+
        /* FIXME: We should issue an unconditional chip reset here. This can be
         * done once we have a .reset function in struct flashchip.
         * Give the chip time to settle.
@@ -532,6 +544,7 @@
        programmer_delay(100000);
        ret |= doit(fill_flash, force, filename, read_it, write_it, erase_it, 
verify_it);
 
+       unmap_flash(fill_flash);
 out_shutdown:
        programmer_shutdown();
 out:

Modified: trunk/flash.h
==============================================================================
--- trunk/flash.h       Wed Aug 20 20:56:35 2014        (r1846)
+++ trunk/flash.h       Sun Aug 31 01:39:51 2014        (r1847)
@@ -48,9 +48,9 @@
 /* Types and macros regarding the maximum flash space size supported by 
generic code. */
 typedef uint32_t chipoff_t; /* Able to store any addressable offset within a 
supported flash memory. */
 typedef uint32_t chipsize_t; /* Able to store the number of bytes of any 
supported flash memory. */
-#define FL_MAX_CHIPADDR_BITS (24)
-#define FL_MAX_CHIPADDR ((chipoff_t)(1ULL<<FL_MAX_CHIPADDR_BITS)-1)
-#define PRIxCHIPADDR "06"PRIx32
+#define FL_MAX_CHIPOFF_BITS (24)
+#define FL_MAX_CHIPOFF ((chipoff_t)(1ULL<<FL_MAX_CHIPOFF_BITS)-1)
+#define PRIxCHIPOFF "06"PRIx32
 #define PRIuCHIPSIZE PRIu32
 
 int register_shutdown(int (*function) (void *data), void *data);
@@ -209,8 +209,14 @@
 
 struct flashctx {
        struct flashchip *chip;
+       /* FIXME: The memory mappings should be saved in a more structured way. 
*/
+       /* The physical_* fields store the respective addresses in the physical 
address space of the CPU. */
+       uintptr_t physical_memory;
+       /* The virtual_* fields store where the respective physical address is 
mapped into flashrom's address
+        * space. A value equivalent to (chipaddr)ERROR_PTR indicates an 
invalid mapping (or none at all). */
        chipaddr virtual_memory;
-       /* Some flash devices have an additional register space. */
+       /* Some flash devices have an additional register space; semantics are 
like above. */
+       uintptr_t physical_registers;
        chipaddr virtual_registers;
        struct registered_master *mst;
 };
@@ -252,7 +258,8 @@
 /* flashrom.c */
 extern const char flashrom_version[];
 extern const char *chip_to_probe;
-void map_flash_registers(struct flashctx *flash);
+int map_flash(struct flashctx *flash);
+void unmap_flash(struct flashctx *flash);
 int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start, 
unsigned int len);
 int erase_flash(struct flashctx *flash);
 int probe_flash(struct registered_master *mst, int startchip, struct flashctx 
*fill_flash, int force);

Modified: trunk/flashrom.c
==============================================================================
--- trunk/flashrom.c    Wed Aug 20 20:56:35 2014        (r1846)
+++ trunk/flashrom.c    Sun Aug 31 01:39:51 2014        (r1847)
@@ -479,6 +479,7 @@
 void programmer_unmap_flash_region(void *virt_addr, size_t len)
 {
        programmer_table[programmer].unmap_flash_region(virt_addr, len);
+       msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, 
(uintptr_t)virt_addr);
 }
 
 void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
@@ -528,14 +529,6 @@
                programmer_table[programmer].delay(usecs);
 }
 
-void map_flash_registers(struct flashctx *flash)
-{
-       size_t size = flash->chip->total_size * 1024;
-       /* Flash registers live 4 MByte below the flash. */
-       /* FIXME: This is incorrect for nonstandard flashbase. */
-       flash->virtual_registers = (chipaddr)programmer_map_flash_region("flash 
chip registers", (0xFFFFFFFF - 0x400000 - size + 1), size);
-}
-
 int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
                   int unsigned len)
 {
@@ -1052,12 +1045,64 @@
        return limitexceeded;
 }
 
+void unmap_flash(struct flashctx *flash)
+{
+       if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
+               programmer_unmap_flash_region((void *)flash->virtual_registers, 
flash->chip->total_size * 1024);
+               flash->physical_registers = 0;
+               flash->virtual_registers = (chipaddr)ERROR_PTR;
+       }
+
+       if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
+               programmer_unmap_flash_region((void *)flash->virtual_memory, 
flash->chip->total_size * 1024);
+               flash->physical_memory = 0;
+               flash->virtual_memory = (chipaddr)ERROR_PTR;
+       }
+}
+
+int map_flash(struct flashctx *flash)
+{
+       /* Init pointers to the fail-safe state to distinguish them later from 
legit values. */
+       flash->virtual_memory = (chipaddr)ERROR_PTR;
+       flash->virtual_registers = (chipaddr)ERROR_PTR;
+
+       /* FIXME: This avoids mapping (and unmapping) of flash chip definitions 
with size 0.
+        * These are used for various probing-related hacks that would not map 
successfully anyway and should be
+        * removed ASAP. */
+       if (flash->chip->total_size == 0)
+               return 0;
+
+       const chipsize_t size = flash->chip->total_size * 1024;
+       uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
+       void *addr = programmer_map_flash_region(flash->chip->name, base, size);
+       if (addr == ERROR_PTR) {
+               msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
+                        flash->chip->name, PRIxPTR_WIDTH, base);
+               return 1;
+       }
+       flash->physical_memory = base;
+       flash->virtual_memory = (chipaddr)addr;
+
+       /* FIXME: Special function registers normally live 4 MByte below flash 
space, but it might be somewhere
+        * completely different on some chips and programmers, or not mappable 
at all.
+        * Ignore these problems for now and always report success. */
+       if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
+               base = 0xffffffff - size - 0x400000 + 1;
+               addr = programmer_map_flash_region("flash chip registers", 
base, size);
+               if (addr == ERROR_PTR) {
+                       msg_pdbg2("Could not map flash chip registers %s at 
0x%0*" PRIxPTR ".\n",
+                                flash->chip->name, PRIxPTR_WIDTH, base);
+                       return 0;
+               }
+               flash->physical_registers = base;
+               flash->virtual_registers = (chipaddr)addr;
+       }
+       return 0;
+}
+
 int probe_flash(struct registered_master *mst, int startchip, struct flashctx 
*flash, int force)
 {
        const struct flashchip *chip;
-       unsigned long base = 0;
-       char location[64];
-       uint32_t size;
        enum chipbustype buses_common;
        char *tmp;
 
@@ -1082,9 +1127,8 @@
                memcpy(flash->chip, chip, sizeof(struct flashchip));
                flash->mst = mst;
 
-               size = flash->chip->total_size * 1024;
-               base = flashbase ? flashbase : (0xffffffff - size + 1);
-               flash->virtual_memory = 
(chipaddr)programmer_map_flash_region("flash chip", base, size);
+               if (map_flash(flash) != 0)
+                       return -1;
 
                /* We handle a forced match like a real match, we just avoid 
probing. Note that probe_flash()
                 * is only called with force=1 after normal probing failed.
@@ -1133,8 +1177,7 @@
                        break;
                /* Not the first flash chip detected on this bus, and it's just 
a generic match. Ignore it. */
 notfound:
-               programmer_unmap_flash_region((void *)flash->virtual_memory, 
size);
-               flash->virtual_memory = (chipaddr)NULL;
+               unmap_flash(flash);
                free(flash->chip);
                flash->chip = NULL;
        }
@@ -1142,25 +1185,28 @@
        if (!flash->chip)
                return -1;
 
+
+       tmp = flashbuses_to_text(flash->chip->bustype);
+       msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : 
"Found",
+                 flash->chip->vendor, flash->chip->name, 
flash->chip->total_size, tmp);
+       free(tmp);
 #if CONFIG_INTERNAL == 1
        if (programmer_table[programmer].map_flash_region == physmap)
-               snprintf(location, sizeof(location), "at physical address 
0x%lx", base);
+               msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
+                         PRIxPTR_WIDTH, flash->physical_memory);
        else
 #endif
-               snprintf(location, sizeof(location), "on %s", 
programmer_table[programmer].name);
+               msg_cinfo("on %s.\n", programmer_table[programmer].name);
 
-       tmp = flashbuses_to_text(flash->chip->bustype);
-       msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) %s.\n", force ? 
"Assuming" : "Found",
-                 flash->chip->vendor, flash->chip->name, 
flash->chip->total_size, tmp, location);
-       free(tmp);
-
-       /* Flash registers will not be mapped if the chip was forced. Lock info
-        * may be stored in registers, so avoid lock info printing.
-        */
+       /* Flash registers may more likely not be mapped if the chip was forced.
+        * Lock info may be stored in registers, so avoid lock info printing. */
        if (!force)
                if (flash->chip->printlock)
                        flash->chip->printlock(flash);
 
+       /* Get out of the way for later runs. */
+       unmap_flash(flash);
+
        /* Return position of matching chip. */
        return chip - flashchips;
 }

Modified: trunk/jedec.c
==============================================================================
--- trunk/jedec.c       Wed Aug 20 20:56:35 2014        (r1846)
+++ trunk/jedec.c       Sun Aug 31 01:39:51 2014        (r1847)
@@ -166,9 +166,6 @@
        if (man_id != chip->manufacture_id || dev_id != chip->model_id)
                return 0;
 
-       if (chip->feature_bits & FEATURE_REGISTERMAP)
-               map_flash_registers(flash);
-
        return 1;
 }
 
@@ -287,9 +284,6 @@
        if (largeid1 != chip->manufacture_id || largeid2 != chip->model_id)
                return 0;
 
-       if (chip->feature_bits & FEATURE_REGISTERMAP)
-               map_flash_registers(flash);
-
        return 1;
 }
 

_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to