mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-26 22:52:34 +02:00
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). Corresponding to flashrom svn r1720. Signed-off-by: Vadim Girlin <vadimgirlin@gmail.com> Signed-off-by: Damien Zammit <damien@zamaudio.com> Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at> Tested-by: Damien Zammit <damien@zamaudio.com> Tested-by: Anton Kochkov <anton.kochkov@gmail.com> Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
This commit is contained in:
parent
bdead0d27d
commit
4dd0f906c6
13
flashrom.8
13
flashrom.8
@ -315,6 +315,19 @@ do not match, it will refuse to write the image unless you specify
|
|||||||
.TP
|
.TP
|
||||||
.B ITE IT87 Super I/O
|
.B ITE IT87 Super I/O
|
||||||
.sp
|
.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
|
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
|
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
|
set the I/O base port of the IT87 series SPI controller manually instead of
|
||||||
|
@ -331,9 +331,8 @@ int internal_init(void)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
/* Probe unconditionally for IT87* LPC->SPI translation and for
|
/* Probe unconditionally for ITE Super I/O chips. This enables LPC->SPI translation on IT87* and
|
||||||
* IT87* Parallel write enable.
|
* parallel writes on IT8705F. Also, this handles the manual chip select for Gigabyte's DualBIOS. */
|
||||||
*/
|
|
||||||
init_superio_ite();
|
init_superio_ite();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
47
it87spi.c
47
it87spi.c
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "chipdrivers.h"
|
#include "chipdrivers.h"
|
||||||
#include "programmer.h"
|
#include "programmer.h"
|
||||||
@ -36,7 +37,7 @@
|
|||||||
#define ITE_SUPERIO_PORT1 0x2e
|
#define ITE_SUPERIO_PORT1 0x2e
|
||||||
#define ITE_SUPERIO_PORT2 0x4e
|
#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) */
|
/* use fast 33MHz SPI (<>0) or slow 16MHz (0) */
|
||||||
static int fast_spi = 1;
|
static int fast_spi = 1;
|
||||||
|
|
||||||
@ -124,10 +125,40 @@ static const struct spi_programmer spi_programmer_it87xx = {
|
|||||||
static uint16_t it87spi_probe(uint16_t port)
|
static uint16_t it87spi_probe(uint16_t port)
|
||||||
{
|
{
|
||||||
uint8_t tmp = 0;
|
uint8_t tmp = 0;
|
||||||
char *portpos = NULL;
|
|
||||||
uint16_t flashport = 0;
|
uint16_t flashport = 0;
|
||||||
|
|
||||||
enter_conf_mode_ite(port);
|
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) */
|
/* NOLDN, reg 0x24, mask out lowest bit (suspend) */
|
||||||
tmp = sio_read(port, 0x24) & 0xFE;
|
tmp = sio_read(port, 0x24) & 0xFE;
|
||||||
/* Check if LPC->SPI translation is active. */
|
/* Check if LPC->SPI translation is active. */
|
||||||
@ -163,11 +194,11 @@ static uint16_t it87spi_probe(uint16_t port)
|
|||||||
flashport |= sio_read(port, 0x65);
|
flashport |= sio_read(port, 0x65);
|
||||||
msg_pdbg("Serial flash port 0x%04x\n", flashport);
|
msg_pdbg("Serial flash port 0x%04x\n", flashport);
|
||||||
/* Non-default port requested? */
|
/* Non-default port requested? */
|
||||||
portpos = extract_programmer_param("it87spiport");
|
param = extract_programmer_param("it87spiport");
|
||||||
if (portpos) {
|
if (param) {
|
||||||
char *endptr = NULL;
|
char *endptr = NULL;
|
||||||
unsigned long forced_flashport;
|
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
|
/* Port 0, port >0x1000, unaligned ports and garbage strings
|
||||||
* are rejected.
|
* are rejected.
|
||||||
*/
|
*/
|
||||||
@ -180,7 +211,8 @@ static uint16_t it87spi_probe(uint16_t port)
|
|||||||
msg_perr("Error: it87spiport specified, but no valid "
|
msg_perr("Error: it87spiport specified, but no valid "
|
||||||
"port specified.\nPort must be a multiple of "
|
"port specified.\nPort must be a multiple of "
|
||||||
"0x8 and lie between 0x100 and 0xff8.\n");
|
"0x8 and lie between 0x100 and 0xff8.\n");
|
||||||
free(portpos);
|
exit_conf_mode_ite(port);
|
||||||
|
free(param);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
flashport = (uint16_t)forced_flashport;
|
flashport = (uint16_t)forced_flashport;
|
||||||
@ -190,7 +222,7 @@ static uint16_t it87spi_probe(uint16_t port)
|
|||||||
sio_write(port, 0x65, (flashport & 0xff));
|
sio_write(port, 0x65, (flashport & 0xff));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(portpos);
|
free(param);
|
||||||
exit_conf_mode_ite(port);
|
exit_conf_mode_ite(port);
|
||||||
it8716f_flashport = flashport;
|
it8716f_flashport = flashport;
|
||||||
if (internal_buses_supported & BUS_SPI)
|
if (internal_buses_supported & BUS_SPI)
|
||||||
@ -228,6 +260,7 @@ int init_superio_ite(void)
|
|||||||
case 0x8716:
|
case 0x8716:
|
||||||
case 0x8718:
|
case 0x8718:
|
||||||
case 0x8720:
|
case 0x8720:
|
||||||
|
case 0x8728:
|
||||||
ret |= it87spi_probe(superios[i].port);
|
ret |= it87spi_probe(superios[i].port);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user