OK, here's the current megapatch. Will split later, right now I just
want to get this out for review.

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

Index: flashrom-rom_decode_check/flash.h
===================================================================
--- flashrom-rom_decode_check/flash.h   (Revision 753)
+++ flashrom-rom_decode_check/flash.h   (Arbeitskopie)
@@ -352,9 +352,17 @@
 void sio_mask(uint16_t port, uint8_t reg, uint8_t data, uint8_t mask);
 int board_flash_enable(const char *vendor, const char *part);
 
+struct decode_sizes {
+       uint32_t parallel;
+       uint32_t lpc;
+       uint32_t fwh;
+       uint32_t spi;
+};
+
 /* chipset_enable.c */
 extern enum chipbustype buses_supported;
 int chipset_flash_enable(void);
+extern struct decode_sizes max_rom_decode;
 
 extern unsigned long flashbase;
 
Index: flashrom-rom_decode_check/chipset_enable.c
===================================================================
--- flashrom-rom_decode_check/chipset_enable.c  (Revision 753)
+++ flashrom-rom_decode_check/chipset_enable.c  (Arbeitskopie)
@@ -41,6 +41,12 @@
  */
 
 enum chipbustype buses_supported = CHIP_BUSTYPE_NONSPI;
+struct decode_sizes max_rom_decode = {
+       .parallel       = 0xffffffff,
+       .lpc            = 0xffffffff,
+       .fwh            = 0xffffffff,
+       .spi            = 0xffffffff
+};
 
 extern int ichspi_lock;
 
@@ -204,34 +210,73 @@
        uint32_t fwh_conf;
        int i;
        char *idsel = NULL;
+       int tmp;
+       int max_decode_fwh_idsel = 0;
+       int max_decode_fwh_decode = 0;
+       int contiguous = 1;
 
-       /* Ignore all legacy ranges below 1 MB. */
+       /* Ignore all legacy ranges below 1 MB.
+        * We currently only support flashing the chip which responds to
+        * IDSEL=0. To support IDSEL!=0, flashbase and decode size calculations
+        * have to be adjusted.
+        */
        /* FWH_SEL1 */
        fwh_conf = pci_read_long(dev, 0xd0);
-       for (i = 7; i >= 0; i--)
+       for (i = 7; i >= 0; i--) {
+               tmp = (fwh_conf >> (i * 4)) & 0xf;
                printf_debug("\n0x%08x/0x%08x FWH IDSEL: 0x%x",
                             (0x1ff8 + i) * 0x80000,
                             (0x1ff0 + i) * 0x80000,
-                            (fwh_conf >> (i * 4)) & 0xf);
+                            tmp);
+               if ((tmp == 0) && contiguous) {
+                       max_decode_fwh_idsel = (8 - i) * 0x80000;
+               } else {
+                       contiguous = 0;
+               }
+       }
        /* FWH_SEL2 */
        fwh_conf = pci_read_word(dev, 0xd4);
-       for (i = 3; i >= 0; i--)
+       for (i = 3; i >= 0; i--) {
+               tmp = (fwh_conf >> (i * 4)) & 0xf;
                printf_debug("\n0x%08x/0x%08x FWH IDSEL: 0x%x",
                             (0xff4 + i) * 0x100000,
                             (0xff0 + i) * 0x100000,
-                            (fwh_conf >> (i * 4)) & 0xf);
+                            tmp);
+               if ((tmp == 0) && contiguous) {
+                       max_decode_fwh_idsel = (8 - i) * 0x100000;
+               } else {
+                       contiguous = 0;
+               }
+       }
+       contiguous = 1;
        /* FWH_DEC_EN1 */
        fwh_conf = pci_read_word(dev, 0xd8);
-       for (i = 7; i >= 0; i--)
+       for (i = 7; i >= 0; i--) {
+               tmp = (fwh_conf >> (i + 0x8)) & 0x1;
                printf_debug("\n0x%08x/0x%08x FWH decode %sabled",
                             (0x1ff8 + i) * 0x80000,
                             (0x1ff0 + i) * 0x80000,
-                            (fwh_conf >> (i + 0x8)) & 0x1 ? "en" : "dis");
-       for (i = 3; i >= 0; i--)
+                            tmp ? "en" : "dis");
+               if ((tmp == 0) && contiguous) {
+                       max_decode_fwh_decode = (8 - i) * 0x80000;
+               } else {
+                       contiguous = 0;
+               }
+       }
+       for (i = 3; i >= 0; i--) {
+               tmp = (fwh_conf >> i) & 0x1;
                printf_debug("\n0x%08x/0x%08x FWH decode %sabled",
                             (0xff4 + i) * 0x100000,
                             (0xff0 + i) * 0x100000,
-                            (fwh_conf >> i) & 0x1 ? "en" : "dis");
+                            tmp ? "en" : "dis");
+               if ((tmp == 0) && contiguous) {
+                       max_decode_fwh_decode = (8 - i) * 0x100000;
+               } else {
+                       contiguous = 0;
+               }
+       }
+       max_rom_decode.fwh = min(max_decode_fwh_idsel, max_decode_fwh_decode);
+       printf_debug("\nMaximum FWH chip size: 0x%x bytes", max_rom_decode.fwh);
 
        if (programmer_param)
                idsel = strstr(programmer_param, "fwh_idsel=");
@@ -244,8 +289,13 @@
                printf("\nSetting IDSEL=0x%x for top 16 MB", fwh_conf);
                pci_write_long(dev, 0xd0, fwh_conf);
                pci_write_word(dev, 0xd4, fwh_conf);
+               /* FIXME: Decode settings are not changed. */
        }
 
+       /* If we're called by enable_flash_ich_dc, it will override
+        * buses_supported anyway.
+        */
+       buses_supported = CHIP_BUSTYPE_FWH;
        return enable_flash_ich(dev, name, 0xdc);
 }
 
@@ -258,6 +308,7 @@
 {
        uint32_t mmio_base;
 
+       /* Do we really need no write enable? */
        mmio_base = (pci_read_long(dev, 0xbc)) << 8;
        printf_debug("MMIO base at = 0x%x\n", mmio_base);
        spibar = physmap("VT8237S MMIO registers", mmio_base, 0x70);
@@ -312,8 +363,7 @@
         */
 
        if (ich_generation == 7 && bbs == ICH_STRAP_LPC) {
-               /* Not sure if it speaks LPC as well. */
-               buses_supported = CHIP_BUSTYPE_LPC | CHIP_BUSTYPE_FWH;
+               buses_supported = CHIP_BUSTYPE_FWH;
                /* No further SPI initialization required */
                return ret;
        }
@@ -325,16 +375,14 @@
                spibar_offset = 0x3020;
                break;
        case 8:
-               /* Not sure if it speaks LPC as well. */
-               buses_supported = CHIP_BUSTYPE_LPC | CHIP_BUSTYPE_FWH | 
CHIP_BUSTYPE_SPI;
+               buses_supported = CHIP_BUSTYPE_FWH | CHIP_BUSTYPE_SPI;
                spi_controller = SPI_CONTROLLER_ICH9;
                spibar_offset = 0x3020;
                break;
        case 9:
        case 10:
        default:                /* Future version might behave the same */
-               /* Not sure if it speaks LPC as well. */
-               buses_supported = CHIP_BUSTYPE_LPC | CHIP_BUSTYPE_FWH | 
CHIP_BUSTYPE_SPI;
+               buses_supported = CHIP_BUSTYPE_FWH | CHIP_BUSTYPE_SPI;
                spi_controller = SPI_CONTROLLER_ICH9;
                spibar_offset = 0x3800;
                break;
@@ -515,14 +563,22 @@
 
 #define DECODE_CONTROL_REG2            0x5b    /* F0 index 0x5b */
 #define ROM_AT_LOGIC_CONTROL_REG       0x52    /* F0 index 0x52 */
+#define CS5530_RESET_CONTROL_REG       0x44    /* F0 index 0x44 */
+#define CS5530_USB_SHADOW_REG          0x43    /* F0 index 0x43 */
 
 #define LOWER_ROM_ADDRESS_RANGE                (1 << 0)
 #define ROM_WRITE_ENABLE               (1 << 1)
 #define UPPER_ROM_ADDRESS_RANGE                (1 << 2)
 #define BIOS_ROM_POSITIVE_DECODE       (1 << 5)
+#define CS5530_ISA_MASTER              (1 << 7)
+#define CS5530_ENABLE_SA2320           (1 << 2)
+#define CS5530_ENABLE_SA20             (1 << 6)
 
+       buses_supported = CHIP_BUSTYPE_PARALLEL;
        /* Decode 0x000E0000-0x000FFFFF (128 KB), not just 64 KB, and
         * decode 0xFF000000-0xFFFFFFFF (16 MB), not just 256 KB.
+        * FIXME: Should we really touch the low mapping below 1 MB? Flashrom
+        * ignores that region completely.
         * Make the configured ROM areas writable.
         */
        reg8 = pci_read_byte(dev, ROM_AT_LOGIC_CONTROL_REG);
@@ -536,6 +592,24 @@
        reg8 |= BIOS_ROM_POSITIVE_DECODE;
        pci_write_byte(dev, DECODE_CONTROL_REG2, reg8);
 
+       reg8 = pci_read_byte(dev, CS5530_RESET_CONTROL_REG);
+       if (reg8 & CS5530_ISA_MASTER) {
+               /* We have A0-A23 available. */
+               max_rom_decode.parallel = 16 * 1024 * 1024;
+       } else {
+               reg8 = pci_read_byte(dev, CS5530_USB_SHADOW_REG);
+               if (reg8 & CS5530_ENABLE_SA2320) {
+                       /* We have A0-19, A20-A23 available. */
+                       max_rom_decode.parallel = 16 * 1024 * 1024;
+               } else if (reg8 & CS5530_ENABLE_SA20) {
+                       /* We have A0-19, A20 available. */
+                       max_rom_decode.parallel = 2 * 1024 * 1024;
+               } else {
+                       /* A20 and above are not active. */
+                       max_rom_decode.parallel = 1024 * 1024;
+               }
+       }
+
        return 0;
 }
 
Index: flashrom-rom_decode_check/flashrom.c
===================================================================
--- flashrom-rom_decode_check/flashrom.c        (Revision 753)
+++ flashrom-rom_decode_check/flashrom.c        (Arbeitskopie)
@@ -299,6 +299,15 @@
        return (a > b) ? a : b;
 }
 
+int bitcount(unsigned long a)
+{
+       int i = 0;
+       for (; a != 0; a >>= 1)
+               if (a & 1)
+                       i++;
+       return i;
+}
+
 char *strcat_realloc(char *dest, const char *src)
 {
        dest = realloc(dest, strlen(dest) + strlen(src) + 1);
@@ -398,10 +407,63 @@
        return ret;
 }
 
+int check_max_decode(enum chipbustype buses, unsigned int size, int warn)
+{
+       int limitexceeded = 0;
+       if ((buses & CHIP_BUSTYPE_PARALLEL) &&
+           (max_rom_decode.parallel < size)) {
+               limitexceeded++;
+               printf_debug("Chip size %u is bigger than supported "
+                            "size %u of chipset/board/programmer "
+                            "for Parallel interface, "
+                            "probe/read/erase/write may fail. ", size,
+                            max_rom_decode.parallel);
+       }
+       if ((buses & CHIP_BUSTYPE_LPC) &&
+           (max_rom_decode.lpc < size)) {
+               limitexceeded++;
+               printf_debug("Chip size %u is bigger than supported "
+                            "size %u of chipset/board/programmer "
+                            "for LPC interface, "
+                            "probe/read/erase/write may fail. ", size,
+                            max_rom_decode.lpc);
+       }
+       if ((buses & CHIP_BUSTYPE_FWH) &&
+           (max_rom_decode.fwh < size)) {
+               limitexceeded++;
+               printf_debug("Chip size %u is bigger than supported "
+                            "size %u of chipset/board/programmer "
+                            "for FWH interface, "
+                            "probe/read/erase/write may fail. ", size,
+                            max_rom_decode.fwh);
+       }
+       if ((buses & CHIP_BUSTYPE_SPI) &&
+           (max_rom_decode.spi < size)) {
+               limitexceeded++;
+               printf_debug("Chip size %u is bigger than supported "
+                            "size %u of chipset/board/programmer "
+                            "for SPI interface, "
+                            "probe/read/erase/write may fail. ", size,
+                            max_rom_decode.spi);
+       }
+       if (!limitexceeded)
+               return 0;
+       /* Sometimes chip and programmer have more than one bus in common,
+        * and the limit is not exceeded on all buses. Tell the user.
+        */
+       if (bitcount(buses) > limitexceeded)
+               printf_debug("There is at least one common chip/programmer "
+                            "interface which can support a chip of this size. "
+                            "You can try --force at your own risk.\n");
+       return 1;
+}
+
 struct flashchip *probe_flash(struct flashchip *first_flash, int force)
 {
        struct flashchip *flash;
-       unsigned long base = 0, size;
+       unsigned long base = 0;
+       unsigned int size;
+       enum chipbustype buses_common;
        char *tmp;
 
        for (flash = first_flash; flash && flash->name; flash++) {
@@ -413,7 +475,8 @@
                        printf_debug("failed! flashrom has no probe function 
for this flash chip.\n");
                        continue;
                }
-               if (!(buses_supported & flash->bustype)) {
+               buses_common = buses_supported & flash->bustype;
+               if (!buses_common) {
                        tmp = flashbuses_to_text(buses_supported);
                        printf_debug("skipped. Host bus type %s ", tmp);
                        free(tmp);
@@ -424,6 +487,7 @@
                }
 
                size = flash->total_size * 1024;
+               check_max_decode(buses_common, size, 0);
 
                base = flashbase ? flashbase : (0xffffffff - size + 1);
                flash->virtual_memory = 
(chipaddr)programmer_map_flash_region("flash chip", base, size);
@@ -975,6 +1039,14 @@
                verify_it = 1;
 
        size = flash->total_size * 1024;
+       if (check_max_decode((buses_supported & flash->bustype), size, 1) &&
+           (!force)) {
+               fprintf(stderr, "This chip is too big for this programmer. "
+                       "Details are given in verbose mode. You can override "
+                       "this check with --force.");
+               programmer_shutdown();
+               return 1;
+       }
        buf = (uint8_t *) calloc(size, sizeof(char));
 
        if (erase_it) {
Index: flashrom-rom_decode_check/board_enable.c
===================================================================
--- flashrom-rom_decode_check/board_enable.c    (Revision 753)
+++ flashrom-rom_decode_check/board_enable.c    (Arbeitskopie)
@@ -804,16 +804,24 @@
 }
 
 /**
- * Suited for:
- *   - Shuttle AK38N: VIA KT333CF + VIA VT8235 + ITE IT8705F
- *   - Elitegroup K7VTA3: VIA Apollo KT266/A/333 + VIA VT8235 + ITE IT8705F
+ * Suited for: Elitegroup K7VTA3: VIA Apollo KT266/A/333 + VIA VT8235 + ITE 
IT8705F
  */
-static int it8705f_write_enable_2e(const char *name)
+static int elitegroup_k7vta3(const char *name)
 {
+       max_rom_decode.parallel = 256 * 1024;
        return it8705f_write_enable(0x2e, name);
 }
 
 /**
+ * Suited for: Shuttle AK38N: VIA KT333CF + VIA VT8235 + ITE IT8705F
+ */
+static int shuttle_ak38n(const char *name)
+{
+       max_rom_decode.parallel = 256 * 1024;
+       return it8705f_write_enable(0x2e, name);
+}
+
+/**
  * Find the runtime registers of an SMSC Super I/O, after verifying its
  * chip ID.
  *
@@ -1079,7 +1087,7 @@
        {0x10DE, 0x0030, 0x1043, 0x818a,  0x8086, 0x100E, 0x1043, 0x80EE, NULL, 
        NULL,          "ASUS",        "P5ND2-SLI Deluxe",   
board_asus_p5nd2_sli},
        {0x1106, 0x3149, 0x1565, 0x3206,  0x1106, 0x3344, 0x1565, 0x1202, NULL, 
        NULL,          "Biostar",     "P4M80-M4",           
it8705_rom_write_enable},
        {0x8086, 0x3590, 0x1028, 0x016c,  0x1000, 0x0030, 0x1028, 0x016c, NULL, 
        NULL,          "Dell",        "PowerEdge 1850",     ich5_gpio23_raise},
-       {0x1106, 0x3038, 0x1019, 0x0996,  0x1106, 0x3177, 0x1019, 0x0996, NULL, 
        NULL,          "Elitegroup",  "K7VTA3",             
it8705f_write_enable_2e},
+       {0x1106, 0x3038, 0x1019, 0x0996,  0x1106, 0x3177, 0x1019, 0x0996, NULL, 
        NULL,          "Elitegroup",  "K7VTA3",             elitegroup_k7vta3},
        {0x1106, 0x3177, 0x1106, 0x3177,  0x1106, 0x3059, 0x1695, 0x3005, NULL, 
        NULL,          "EPoX",        "EP-8K5A2",           
board_epox_ep_8k5a2},
        {0x10EC, 0x8139, 0x1695, 0x9001,  0x11C1, 0x5811, 0x1695, 0x9015, NULL, 
        NULL,          "EPoX",        "EP-8RDA3+",          
board_epox_ep_8rda3plus},
        {0x8086, 0x7110,      0,      0,  0x8086, 0x7190,      0,      0, 
"epox",       "ep-bx3",      "EPoX",        "EP-BX3",             
board_epox_ep_bx3},
@@ -1105,7 +1113,7 @@
        {0x1106, 0x0571, 0x1462, 0x7120,       0,      0,      0,      0, 
"msi",        "kt4v",        "MSI",         "MS-6712 (KT4V)",     
board_msi_kt4v},
        {0x8086, 0x2658, 0x1462, 0x7046,  0x1106, 0x3044, 0x1462, 0x046d, NULL, 
        NULL,          "MSI",         "MS-7046",            ich6_gpio19_raise},
        {0x10de, 0x005e,      0,      0,       0,      0,      0,      0, 
"msi",        "k8n-neo3",    "MSI",         "MS-7135 (K8N Neo3)", 
w83627thf_gpio4_4_raise_4e},
-       {0x1106, 0x3104, 0x1297, 0xa238,  0x1106, 0x3059, 0x1297, 0xc063, NULL, 
        NULL,          "Shuttle",     "AK38N",              
it8705f_write_enable_2e},
+       {0x1106, 0x3104, 0x1297, 0xa238,  0x1106, 0x3059, 0x1297, 0xc063, NULL, 
        NULL,          "Shuttle",     "AK38N",              shuttle_ak38n},
        {0x10DE, 0x0050, 0x1297, 0x5036,  0x1412, 0x1724, 0x1297, 0x5036, NULL, 
        NULL,          "Shuttle",     "FN25",               board_shuttle_fn25},
        {0x1106, 0x3038, 0x0925, 0x1234,  0x1106, 0x3058, 0x15DD, 0x7609, NULL, 
        NULL,          "Soyo",        "SY-7VCA",            board_soyo_sy_7vca},
        {0x8086, 0x1076, 0x8086, 0x1176,  0x1106, 0x3059, 0x10f1, 0x2498, NULL, 
        NULL,          "Tyan",        "S2498 (Tomcat K7M)", 
board_asus_a7v8x_mx},


-- 
Developer quote of the week: 
"We are juggling too many chainsaws and flaming arrows and tigers."


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

Reply via email to