Author: stefanct
Date: Sat Aug 24 14:18:17 2013
New Revision: 1720
URL: http://flashrom.org/trac/flashrom/changeset/1720

Log:
IT87: Add ability to select between chips on GIGABYTE DualBIOS boards.

Thanks to Vadim Girlin for finding out how to do that.
This is known to work on GA-MA770-UD3, GA-B75M-D3V, GA-B75N and
GA-H61M-S1 (only M_BIOS is populated).

Signed-off-by: Vadim Girlin <[email protected]>
Signed-off-by: Damien Zammit <[email protected]>
Signed-off-by: Stefan Tauner <[email protected]>
Tested-by: Damien Zammit <[email protected]>
Tested-by: Anton Kochkov <[email protected]>
Acked-by: Stefan Tauner <[email protected]>

Modified:
   trunk/flashrom.8
   trunk/internal.c
   trunk/it87spi.c

Modified: trunk/flashrom.8
==============================================================================
--- trunk/flashrom.8    Sat Aug 24 04:10:18 2013        (r1719)
+++ trunk/flashrom.8    Sat Aug 24 14:18:17 2013        (r1720)
@@ -315,6 +315,19 @@
 .TP
 .B ITE IT87 Super I/O
 .sp
+If your mainboard is manufactured by GIGABYTE and supports DualBIOS it is very 
likely that it uses an
+ITE IT87 series Super I/O to switch between the two flash chips. Only one of 
them can be accessed at a time
+and you can manually select which one to use with the
+.sp
+.B "  flashrom \-p internal:dualbiosindex=chip"
+.sp
+syntax where
+.B chip
+is the index of the chip to use (0 = main, 1 = backup). You can check which 
one is currently selected by
+leaving out the
+.B chip
+parameter.
+.sp
 If your mainboard uses an ITE IT87 series Super I/O for LPC<->SPI flash bus
 translation, flashrom should autodetect that configuration. If you want to
 set the I/O base port of the IT87 series SPI controller manually instead of

Modified: trunk/internal.c
==============================================================================
--- trunk/internal.c    Sat Aug 24 04:10:18 2013        (r1719)
+++ trunk/internal.c    Sat Aug 24 14:18:17 2013        (r1720)
@@ -331,9 +331,8 @@
                return ret;
 
 #if defined(__i386__) || defined(__x86_64__)
-       /* Probe unconditionally for IT87* LPC->SPI translation and for
-        * IT87* Parallel write enable.
-        */
+       /* Probe unconditionally for ITE Super I/O chips. This enables LPC->SPI 
translation on IT87* and
+        * parallel writes on IT8705F. Also, this handles the manual chip 
select for Gigabyte's DualBIOS. */
        init_superio_ite();
 #endif
 

Modified: trunk/it87spi.c
==============================================================================
--- trunk/it87spi.c     Sat Aug 24 04:10:18 2013        (r1719)
+++ trunk/it87spi.c     Sat Aug 24 14:18:17 2013        (r1720)
@@ -27,6 +27,7 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <errno.h>
 #include "flash.h"
 #include "chipdrivers.h"
 #include "programmer.h"
@@ -36,7 +37,7 @@
 #define ITE_SUPERIO_PORT1      0x2e
 #define ITE_SUPERIO_PORT2      0x4e
 
-uint16_t it8716f_flashport = 0;
+static uint16_t it8716f_flashport = 0;
 /* use fast 33MHz SPI (<>0) or slow 16MHz (0) */
 static int fast_spi = 1;
 
@@ -124,10 +125,40 @@
 static uint16_t it87spi_probe(uint16_t port)
 {
        uint8_t tmp = 0;
-       char *portpos = NULL;
        uint16_t flashport = 0;
 
        enter_conf_mode_ite(port);
+       
+       char *param = extract_programmer_param("dualbiosindex");
+       if (param != NULL) {
+               sio_write(port, 0x07, 0x07); /* Select GPIO LDN */
+               tmp = sio_read(port, 0xEF);
+               if (*param == '\0') { /* Print current setting only. */
+                       free(param);
+               } else {
+                       char *dualbiosindex_suffix;
+                       errno = 0;
+                       long chip_index = strtol(param, &dualbiosindex_suffix, 
0);
+                       free(param);
+                       if (errno != 0 || *dualbiosindex_suffix != '\0' || 
chip_index < 0 || chip_index > 1) {
+                               msg_perr("DualBIOS: Invalid chip index 
requested - choose 0 or 1.\n");
+                               exit_conf_mode_ite(port);
+                               return 1;
+                       }
+                       if (chip_index != (tmp & 1)) {
+                               msg_pdbg("DualBIOS: Previous chip index: %d\n", 
tmp & 1);
+                               sio_write(port, 0xEF, (tmp & 0xFE) | 
chip_index);
+                               tmp = sio_read(port, 0xEF);
+                               if ((tmp & 1) != chip_index) {
+                                       msg_perr("DualBIOS: Chip selection 
failed.\n");
+                                       exit_conf_mode_ite(port);
+                                       return 1;
+                               }
+                       }
+               }
+               msg_pinfo("DualBIOS: Selected chip: %d\n", tmp & 1);
+       }
+
        /* NOLDN, reg 0x24, mask out lowest bit (suspend) */
        tmp = sio_read(port, 0x24) & 0xFE;
        /* Check if LPC->SPI translation is active. */
@@ -163,11 +194,11 @@
        flashport |= sio_read(port, 0x65);
        msg_pdbg("Serial flash port 0x%04x\n", flashport);
        /* Non-default port requested? */
-       portpos = extract_programmer_param("it87spiport");
-       if (portpos) {
+       param = extract_programmer_param("it87spiport");
+       if (param) {
                char *endptr = NULL;
                unsigned long forced_flashport;
-               forced_flashport = strtoul(portpos, &endptr, 0);
+               forced_flashport = strtoul(param, &endptr, 0);
                /* Port 0, port >0x1000, unaligned ports and garbage strings
                 * are rejected.
                 */
@@ -180,7 +211,8 @@
                        msg_perr("Error: it87spiport specified, but no valid "
                                 "port specified.\nPort must be a multiple of "
                                 "0x8 and lie between 0x100 and 0xff8.\n");
-                       free(portpos);
+                       exit_conf_mode_ite(port);
+                       free(param);
                        return 1;
                } else {
                        flashport = (uint16_t)forced_flashport;
@@ -190,7 +222,7 @@
                        sio_write(port, 0x65, (flashport & 0xff));
                }
        }
-       free(portpos);
+       free(param);
        exit_conf_mode_ite(port);
        it8716f_flashport = flashport;
        if (internal_buses_supported & BUS_SPI)
@@ -228,6 +260,7 @@
                case 0x8716:
                case 0x8718:
                case 0x8720:
+               case 0x8728:
                        ret |= it87spi_probe(superios[i].port);
                        break;
                default:

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

Reply via email to