From f98cbb703f2bbbb918a87eebcd10c4cc1bd457f9 Mon Sep 17 00:00:00 2001
From: Luc Verhaegen <libv@skynet.be>
Date: Tue, 12 Jan 2010 13:57:21 +0100
Subject: [PATCH] WIP.
---
Makefile | 2 +-
board_enable.c | 411 +++++++------------------------------------------
chipset_enable.c | 1 +
flash.h | 37 +----
flashrom.c | 19 ---
internal.c | 20 +--
it87spi.c | 202 ++++--------------------
spi.c | 1 +
superio.c | 454 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
superio.h | 107 +++++++++++++
wbsio_spi.c | 48 ++-----
11 files changed, 676 insertions(+), 626 deletions(-)
create mode 100644 superio.c
create mode 100644 superio.h
@@ -101,7 +101,7 @@ CONFIG_PRINT_WIKI ?= no
ifeq ($(CONFIG_INTERNAL), yes)
FEATURE_CFLAGS += -D'INTERNAL_SUPPORT=1'
-PROGRAMMER_OBJS += chipset_enable.o board_enable.o cbtable.o it87spi.o ichspi.o sb600spi.o wbsio_spi.o
+PROGRAMMER_OBJS += chipset_enable.o board_enable.o cbtable.o it87spi.o ichspi.o sb600spi.o wbsio_spi.o superio.o
NEED_PCI := yes
endif
@@ -27,73 +27,7 @@
#include <string.h>
#include <fcntl.h>
#include "flash.h"
-
-/*
- * Helper functions for many Winbond Super I/Os of the W836xx range.
- */
-/* Enter extended functions */
-void w836xx_ext_enter(uint16_t port)
-{
- OUTB(0x87, port);
- OUTB(0x87, port);
-}
-
-/* Leave extended functions */
-void w836xx_ext_leave(uint16_t port)
-{
- OUTB(0xAA, port);
-}
-
-/* Generic Super I/O helper functions */
-uint8_t sio_read(uint16_t port, uint8_t reg)
-{
- OUTB(reg, port);
- return INB(port + 1);
-}
-
-void sio_write(uint16_t port, uint8_t reg, uint8_t data)
-{
- OUTB(reg, port);
- OUTB(data, port + 1);
-}
-
-void sio_mask(uint16_t port, uint8_t reg, uint8_t data, uint8_t mask)
-{
- uint8_t tmp;
-
- OUTB(reg, port);
- tmp = INB(port + 1) & ~mask;
- OUTB(tmp | (data & mask), port + 1);
-}
-
-/* Not used yet. */
-#if 0
-static int enable_flash_decode_superio(void)
-{
- int ret;
- uint8_t tmp;
-
- switch (superio.vendor) {
- case SUPERIO_VENDOR_NONE:
- ret = -1;
- break;
- case SUPERIO_VENDOR_ITE:
- enter_conf_mode_ite(superio.port);
- /* Enable flash mapping. Works for most old ITE style SuperI/O. */
- tmp = sio_read(superio.port, 0x24);
- tmp |= 0xfc;
- sio_write(superio.port, 0x24, tmp);
- exit_conf_mode_ite(superio.port);
- ret = 0;
- break;
- default:
- printf_debug("Unhandled SuperI/O type!\n");
- ret = -1;
- break;
- }
- return ret;
-}
-#endif
+#include "superio.h"
/**
* Winbond W83627HF: Raise GPIO24.
@@ -102,37 +36,9 @@ static int enable_flash_decode_superio(void)
* - Agami Aruma
* - IWILL DK8-HTX
*/
-static int w83627hf_gpio24_raise(uint16_t port, const char *name)
-{
- w836xx_ext_enter(port);
-
- /* Is this the W83627HF? */
- if (sio_read(port, 0x20) != 0x52) { /* Super I/O device ID reg. */
- fprintf(stderr, "\nERROR: %s: W83627HF: Wrong ID: 0x%02X.\n",
- name, sio_read(port, 0x20));
- w836xx_ext_leave(port);
- return -1;
- }
-
- /* PIN89S: WDTO/GP24 multiplex -> GPIO24 */
- sio_mask(port, 0x2B, 0x10, 0x10);
-
- /* Select logical device 8: GPIO port 2 */
- sio_write(port, 0x07, 0x08);
-
- sio_mask(port, 0x30, 0x01, 0x01); /* Activate logical device. */
- sio_mask(port, 0xF0, 0x00, 0x10); /* GPIO24 -> output */
- sio_mask(port, 0xF2, 0x00, 0x10); /* Clear GPIO24 inversion */
- sio_mask(port, 0xF1, 0x10, 0x10); /* Raise GPIO24 */
-
- w836xx_ext_leave(port);
-
- return 0;
-}
-
-static int w83627hf_gpio24_raise_2e(const char *name)
+static int w83627hf_gpio24_raise(const char *name)
{
- return w83627hf_gpio24_raise(0x2e, name);
+ return superio_gpio_set(24, 1);
}
/**
@@ -142,95 +48,9 @@ static int w83627hf_gpio24_raise_2e(const char *name)
* - MSI K8T Neo2-F
* - MSI K8N-NEO3
*/
-static int w83627thf_gpio4_4_raise(uint16_t port, const char *name)
-{
- w836xx_ext_enter(port);
-
- /* Is this the W83627THF? */
- if (sio_read(port, 0x20) != 0x82) { /* Super I/O device ID reg. */
- fprintf(stderr, "\nERROR: %s: W83627THF: Wrong ID: 0x%02X.\n",
- name, sio_read(port, 0x20));
- w836xx_ext_leave(port);
- return -1;
- }
-
- /* PINxxxxS: GPIO4/bit 4 multiplex -> GPIOXXX */
-
- sio_write(port, 0x07, 0x09); /* Select LDN 9: GPIO port 4 */
- sio_mask(port, 0x30, 0x02, 0x02); /* Activate logical device. */
- sio_mask(port, 0xF4, 0x00, 0x10); /* GPIO4 bit 4 -> output */
- sio_mask(port, 0xF6, 0x00, 0x10); /* Clear GPIO4 bit 4 inversion */
- sio_mask(port, 0xF5, 0x10, 0x10); /* Raise GPIO4 bit 4 */
-
- w836xx_ext_leave(port);
-
- return 0;
-}
-
-static int w83627thf_gpio4_4_raise_2e(const char *name)
-{
- return w83627thf_gpio4_4_raise(0x2e, name);
-}
-
-static int w83627thf_gpio4_4_raise_4e(const char *name)
-{
- return w83627thf_gpio4_4_raise(0x4e, name);
-}
-
-/**
- * w83627: Enable MEMW# and set ROM size to max.
- */
-static void w836xx_memw_enable(uint16_t port)
-{
- w836xx_ext_enter(port);
- if (!(sio_read(port, 0x24) & 0x02)) { /* Flash ROM enabled? */
- /* Enable MEMW# and set ROM size select to max. (4M). */
- sio_mask(port, 0x24, 0x28, 0x28);
- }
- w836xx_ext_leave(port);
-}
-
-/**
- * Suited for:
- * - EPoX EP-8K5A2: VIA KT333 + VT8235.
- * - Albatron PM266A Pro: VIA P4M266A + VT8235.
- * - Shuttle AK31 (all versions): VIA KT266 + VT8233.
- * - ASUS A7V8X-MX SE and A7V400-MX: AMD K7 + VIA KM400A + VT8235
- * - Tyan S2498 (Tomcat K7M): AMD Geode NX + VIA KM400 + VT8237.
- */
-static int w836xx_memw_enable_2e(const char *name)
+static int w83627thf_gpio44_raise(const char *name)
{
- w836xx_memw_enable(0x2E);
-
- return 0;
-}
-
-/**
- *
- */
-static int it8705f_write_enable(uint8_t port, const char *name)
-{
- enter_conf_mode_ite(port);
- sio_mask(port, 0x24, 0x04, 0x04); /* Flash ROM I/F Writes Enable */
- exit_conf_mode_ite(port);
-
- return 0;
-}
-
-/**
- * Suited for:
- * - AOpen vKM400Am-S: VIA KM400 + VT8237 + IT8705F.
- * - Biostar P4M80-M4: VIA P4M800 + VT8237 + IT8705AF
- * - Elitegroup K7S6A: SiS745 + ITE IT8705F
- * - Elitegroup K7VTA3: VIA Apollo KT266/A/333 + VIA VT8235 + ITE IT8705F
- * - GIGABYTE GA-7VT600: VIA KT600 + VT8237 + IT8705
- * - Shuttle AK38N: VIA KT333CF + VIA VT8235 + ITE IT8705F
- *
- * SIS950 superio probably requires the same flash write enable.
- */
-static int it8705f_write_enable_2e(const char *name)
-{
- return it8705f_write_enable(0x2e, name);
+ return superio_gpio_set(44, 1);
}
/**
@@ -307,31 +127,24 @@ static int via_vt823x_gpio9_raise(const char *name)
}
/**
- * Suited for VIAs EPIA M and MII, and maybe other CLE266 based EPIAs.
- *
- * We don't need to do this for EPIA M when using coreboot, GPIO15 is never
- * lowered there.
+ * Suited for:
+ * - MSI KT4V and KT4V-L: AMD K7 + VIA KT400 + VT8235 + W83697HF.
+ * - MSI KT4 Ultra: AMD K7 + VIA KT400 + VT8235 + W83697HF.
*/
-static int via_vt823x_gpio15_raise(const char *name)
+static int via_vt823x_gpio12_raise(const char *name)
{
- return via_vt823x_gpio_set(15, 1);
+ return via_vt823x_gpio_set(12, 1);
}
/**
- * Winbond W83697HF Super I/O + VIA VT8235 southbridge
+ * Suited for VIAs EPIA M and MII, and maybe other CLE266 based EPIAs.
*
- * Suited for:
- * - MSI KT4V and KT4V-L: AMD K7 + VIA KT400 + VT8235
- * - MSI KT4 Ultra: AMD K7 + VIA KT400 + VT8235
+ * We don't need to do this for EPIA M when using coreboot, GPIO15 is never
+ * lowered there.
*/
-static int board_msi_kt4v(const char *name)
+static int via_vt823x_gpio15_raise(const char *name)
{
- int ret;
-
- ret = via_vt823x_gpio_set(12, 1);
- w836xx_memw_enable(0x2E);
-
- return ret;
+ return via_vt823x_gpio_set(15, 1);
}
/**
@@ -973,8 +786,6 @@ static int board_msi_651ml(const char *name)
temp |= (1 << 0); /* Raise output? */
OUTW(temp, base + 0x64);
- w836xx_memw_enable(0x2E);
-
return 0;
}
@@ -1018,16 +829,9 @@ out:
*/
static int board_mitac_6513wu(const char *name)
{
- struct pci_dev *dev;
uint16_t rt_port;
uint8_t val;
- dev = pci_dev_find(0x8086, 0x2410); /* Intel 82801AA ISA bridge */
- if (!dev) {
- fprintf(stderr, "\nERROR: Intel 82801AA ISA bridge not found.\n");
- return -1;
- }
-
rt_port = smsc_find_runtime(0x4e, 0x54 /* LPC47U33x */, 0xa);
if (rt_port == 0)
return -1;
@@ -1050,93 +854,7 @@ static int board_mitac_6513wu(const char *name)
*/
static int board_asus_a7v8x(const char *name)
{
- uint16_t id, base;
- uint8_t tmp;
-
- /* find the IT8703F */
- w836xx_ext_enter(0x2E);
- id = (sio_read(0x2E, 0x20) << 8) | sio_read(0x2E, 0x21);
- w836xx_ext_leave(0x2E);
-
- if (id != 0x8701) {
- fprintf(stderr, "\nERROR: IT8703F SuperIO not found.\n");
- return -1;
- }
-
- /* Get the GP567 IO base */
- w836xx_ext_enter(0x2E);
- sio_write(0x2E, 0x07, 0x0C);
- base = (sio_read(0x2E, 0x60) << 8) | sio_read(0x2E, 0x61);
- w836xx_ext_leave(0x2E);
-
- if (!base) {
- fprintf(stderr, "\nERROR: Failed to read IT8703F SuperIO GPIO"
- " Base.\n");
- return -1;
- }
-
- /* Raise GP51. */
- tmp = INB(base);
- tmp |= 0x02;
- OUTB(tmp, base);
-
- return 0;
-}
-
-/*
- * General routine for raising/dropping GPIO lines on the ITE IT8712F.
- * There is only some limited checking on the port numbers.
- */
-static int
-it8712f_gpio_set(unsigned int line, int raise)
-{
- unsigned int port;
- uint16_t id, base;
- uint8_t tmp;
-
- port = line / 10;
- port--;
- line %= 10;
-
- /* Check line */
- if ((port > 4) || /* also catches unsigned -1 */
- ((port < 4) && (line > 7)) || ((port == 4) && (line > 5))) {
- fprintf(stderr,
- "\nERROR: Unsupported IT8712F GPIO Line %02d.\n", line);
- return -1;
- }
-
- /* find the IT8712F */
- enter_conf_mode_ite(0x2E);
- id = (sio_read(0x2E, 0x20) << 8) | sio_read(0x2E, 0x21);
- exit_conf_mode_ite(0x2E);
-
- if (id != 0x8712) {
- fprintf(stderr, "\nERROR: IT8712F SuperIO not found.\n");
- return -1;
- }
-
- /* Get the GPIO base */
- enter_conf_mode_ite(0x2E);
- sio_write(0x2E, 0x07, 0x07);
- base = (sio_read(0x2E, 0x62) << 8) | sio_read(0x2E, 0x63);
- exit_conf_mode_ite(0x2E);
-
- if (!base) {
- fprintf(stderr, "\nERROR: Failed to read IT8712F SuperIO GPIO"
- " Base.\n");
- return -1;
- }
-
- /* set GPIO. */
- tmp = INB(base + port);
- if (raise)
- tmp |= 1 << line;
- else
- tmp &= ~(1 << line);
- OUTB(tmp, base + port);
-
- return 0;
+ return superio_gpio_set(51, 1);
}
/**
@@ -1144,7 +862,7 @@ it8712f_gpio_set(unsigned int line, int raise)
*/
static int board_asus_a7v600x(const char *name)
{
- return it8712f_gpio_set(32, 1);
+ return superio_gpio_set(32, 1);
}
/**
@@ -1175,62 +893,45 @@ static int board_asus_a7v600x(const char *name)
/* Please keep this list alphabetically ordered by vendor/board name. */
struct board_pciid_enable board_pciid_enables[] = {
- /* first pci-id set [4], second pci-id set [4], coreboot id [2], vendor name board name max_rom_... flash enable */
- {0x8086, 0x2926, 0x147b, 0x1084, 0x11ab, 0x4364, 0x147b, 0x1084, NULL, NULL, "Abit", "IP35", 0, intel_ich_gpio16_raise},
- {0x105a, 0x0d30, 0x105a, 0x4d33, 0x8086, 0x1130, 0x8086, 0, NULL, NULL, "Acorp", "6A815EPD", 0, board_acorp_6a815epd},
- {0x8086, 0x24D4, 0x1849, 0x24D0, 0x8086, 0x24D5, 0x1849, 0x9739, NULL, NULL, "ASRock", "P4i65GV", 0, intel_ich_gpio23_raise},
- {0x1022, 0x746B, 0, 0, 0, 0, 0, 0, "AGAMI", "ARUMA", "agami", "Aruma", 0, w83627hf_gpio24_raise_2e},
- {0x1106, 0x3177, 0x17F2, 0x3177, 0x1106, 0x3148, 0x17F2, 0x3148, NULL, NULL, "Albatron", "PM266A", 0, w836xx_memw_enable_2e},
- {0x1106, 0x3205, 0x1106, 0x3205, 0x10EC, 0x8139, 0xA0A0, 0x0477, NULL, NULL, "AOpen", "vKM400Am-S", 0, it8705f_write_enable_2e},
- {0x1022, 0x2090, 0, 0, 0x1022, 0x2080, 0, 0, "artecgroup", "dbe61", "Artec Group", "DBE61", 0, board_artecgroup_dbe6x},
- {0x1022, 0x2090, 0, 0, 0x1022, 0x2080, 0, 0, "artecgroup", "dbe62", "Artec Group", "DBE62", 0, board_artecgroup_dbe6x},
- {0x1106, 0x3189, 0x1043, 0x807F, 0x1106, 0x3065, 0x1043, 0x80ED, NULL, NULL, "ASUS", "A7V600-X", 0, board_asus_a7v600x},
- {0x1106, 0x3189, 0x1043, 0x807F, 0x1106, 0x3177, 0x1043, 0x808C, NULL, NULL, "ASUS", "A7V8X", 0, board_asus_a7v8x},
- {0x1106, 0x3177, 0x1043, 0x80A1, 0x1106, 0x3205, 0x1043, 0x8118, NULL, NULL, "ASUS", "A7V8X-MX SE", 0, w836xx_memw_enable_2e},
- {0x1106, 0x1336, 0x1043, 0x80ed, 0x1106, 0x3288, 0x1043, 0x8249, NULL, NULL, "ASUS", "M2V-MX", 0, via_vt823x_gpio5_raise},
- {0x8086, 0x1a30, 0x1043, 0x8070, 0x8086, 0x244b, 0x1043, 0x8028, NULL, NULL, "ASUS", "P4B266", 0, intel_ich_gpio22_raise},
- {0x8086, 0x1A30, 0x1043, 0x8025, 0x8086, 0x244B, 0x104D, 0x80F0, NULL, NULL, "ASUS", "P4B266-LM", 0, intel_ich_gpio21_raise},
- {0x8086, 0x2570, 0x1043, 0x80F2, 0x105A, 0x3373, 0x1043, 0x80F5, NULL, NULL, "ASUS", "P4P800-E Deluxe", 0, intel_ich_gpio21_raise},
- {0x10B9, 0x1541, 0, 0, 0x10B9, 0x1533, 0, 0, "asus", "p5a", "ASUS", "P5A", 0, board_asus_p5a},
- {0x10DE, 0x0030, 0x1043, 0x818a, 0x8086, 0x100E, 0x1043, 0x80EE, NULL, NULL, "ASUS", "P5ND2-SLI Deluxe", 0, nvidia_mcp_gpio10_raise},
- {0x1106, 0x3149, 0x1565, 0x3206, 0x1106, 0x3344, 0x1565, 0x1202, NULL, NULL, "Biostar", "P4M80-M4", 0, it8705f_write_enable_2e},
- {0x8086, 0x3590, 0x1028, 0x016c, 0x1000, 0x0030, 0x1028, 0x016c, NULL, NULL, "Dell", "PowerEdge 1850", 0, intel_ich_gpio23_raise},
- {0x1039, 0x5513, 0x1019, 0x0A41, 0x1039, 0x0018, 0, 0, NULL, NULL, "Elitegroup", "K7S6A", 0, it8705f_write_enable_2e},
- {0x1106, 0x3038, 0x1019, 0x0996, 0x1106, 0x3177, 0x1019, 0x0996, NULL, NULL, "Elitegroup", "K7VTA3", 256, it8705f_write_enable_2e},
- {0x1106, 0x3177, 0x1106, 0x3177, 0x1106, 0x3059, 0x1695, 0x3005, NULL, NULL, "EPoX", "EP-8K5A2", 0, w836xx_memw_enable_2e},
- {0x10EC, 0x8139, 0x1695, 0x9001, 0x11C1, 0x5811, 0x1695, 0x9015, NULL, NULL, "EPoX", "EP-8RDA3+", 0, nvidia_mcp_gpio31_raise},
- {0x8086, 0x7110, 0, 0, 0x8086, 0x7190, 0, 0, "epox", "ep-bx3", "EPoX", "EP-BX3", 0, board_epox_ep_bx3},
- {0x1039, 0x0761, 0, 0, 0x10EC, 0x8168, 0, 0, "gigabyte", "2761gxdk", "GIGABYTE", "GA-2761GXDK", 0, it87xx_probe_spi_flash},
- {0x1106, 0x3227, 0x1458, 0x5001, 0x10ec, 0x8139, 0x1458, 0xe000, NULL, NULL, "GIGABYTE", "GA-7VT600", 0, it8705f_write_enable_2e},
- {0x10DE, 0x0050, 0x1458, 0x0C11, 0x10DE, 0x005e, 0x1458, 0x5000, NULL, NULL, "GIGABYTE", "GA-K8N-SLI", 0, nvidia_mcp_gpio21_raise},
- {0x10DE, 0x0360, 0x1458, 0x0C11, 0x10DE, 0x0369, 0x1458, 0x5001, "gigabyte", "m57sli", "GIGABYTE", "GA-M57SLI-S4", 0, it87xx_probe_spi_flash},
- {0x10de, 0x03e0, 0, 0, 0x10DE, 0x03D0, 0, 0, NULL, NULL, "GIGABYTE", "GA-M61P-S3", 0, it87xx_probe_spi_flash},
- {0x1002, 0x4398, 0x1458, 0x5004, 0x1002, 0x4391, 0x1458, 0xb000, NULL, NULL, "GIGABYTE", "GA-MA78G-DS3H", 0, it87xx_probe_spi_flash},
- {0x1002, 0x4398, 0x1458, 0x5004, 0x1002, 0x4391, 0x1458, 0xb002, NULL, NULL, "GIGABYTE", "GA-MA78GM-S2H", 0, it87xx_probe_spi_flash},
- {0x1002, 0x438d, 0x1458, 0x5001, 0x1002, 0x5956, 0x1002, 0x5956, NULL, NULL, "GIGABYTE", "GA-MA790FX-DQ6", 0, it87xx_probe_spi_flash},
- {0x1166, 0x0223, 0x103c, 0x320d, 0x102b, 0x0522, 0x103c, 0x31fa, "hp", "dl145_g3", "HP", "DL145 G3", 0, board_hp_dl145_g3_enable},
- {0x1166, 0x0205, 0x1014, 0x0347, 0x1002, 0x515E, 0x1014, 0x0325, NULL, NULL, "IBM", "x3455", 0, board_ibm_x3455},
- {0x1039, 0x5513, 0x8086, 0xd61f, 0x1039, 0x6330, 0x8086, 0xd61f, NULL, NULL, "Intel", "D201GLY", 0, wbsio_check_for_spi},
- {0x1022, 0x7468, 0, 0, 0, 0, 0, 0, "iwill", "dk8_htx", "IWILL", "DK8-HTX", 0, w83627hf_gpio24_raise_2e},
- {0x8086, 0x27A0, 0, 0, 0x8086, 0x27b8, 0, 0, "kontron", "986lcd-m", "Kontron", "986LCD-M", 0, board_kontron_986lcd_m},
- {0x8086, 0x2411, 0x8086, 0x2411, 0x8086, 0x7125, 0x0e11, 0xb165, NULL, NULL, "Mitac", "6513WU", 0, board_mitac_6513wu},
- {0x13f6, 0x0111, 0x1462, 0x5900, 0x1106, 0x3177, 0x1106, 0, NULL, NULL, "MSI", "MS-6590 (KT4 Ultra)", 0, board_msi_kt4v},
- {0x1106, 0x3149, 0x1462, 0x7094, 0x10ec, 0x8167, 0x1462, 0x094c, NULL, NULL, "MSI", "MS-6702E (K8T Neo2-F)", 0, w83627thf_gpio4_4_raise_2e},
- {0x1106, 0x0571, 0x1462, 0x7120, 0x1106, 0x3065, 0x1462, 0x7120, NULL, NULL, "MSI", "MS-6712 (KT4V)", 0, board_msi_kt4v},
- {0x1039, 0x7012, 0x1462, 0x0050, 0x1039, 0x6325, 0x1462, 0x0058, NULL, NULL, "MSI", "MS-7005 (651M-L)", 0, board_msi_651ml},
- {0x8086, 0x2658, 0x1462, 0x7046, 0x1106, 0x3044, 0x1462, 0x046d, NULL, NULL, "MSI", "MS-7046", 0, intel_ich_gpio19_raise},
- {0x10DE, 0x005E, 0x1462, 0x7135, 0x10DE, 0x0050, 0x1462, 0x7135, "msi", "k8n-neo3", "MSI", "MS-7135 (K8N Neo3)", 0, w83627thf_gpio4_4_raise_4e},
- {0x10DE, 0x005E, 0x1462, 0x7125, 0x10DE, 0x0052, 0x1462, 0x7125, NULL, NULL, "MSI", "K8N Neo4-F", 0, nvidia_mcp_gpio2_raise},
- {0x1106, 0x3099, 0, 0, 0x1106, 0x3074, 0, 0, "shuttle", "ak31", "Shuttle", "AK31", 0, w836xx_memw_enable_2e},
- {0x1106, 0x3104, 0x1297, 0xa238, 0x1106, 0x3059, 0x1297, 0xc063, NULL, NULL, "Shuttle", "AK38N", 256, it8705f_write_enable_2e},
- {0x10DE, 0x0050, 0x1297, 0x5036, 0x1412, 0x1724, 0x1297, 0x5036, NULL, NULL, "Shuttle", "FN25", 0, board_shuttle_fn25},
- {0x1106, 0x3038, 0x0925, 0x1234, 0x1106, 0x3058, 0x15DD, 0x7609, NULL, NULL, "Soyo", "SY-7VCA", 0, board_soyo_sy_7vca},
- {0x8086, 0x1076, 0x8086, 0x1176, 0x1106, 0x3059, 0x10f1, 0x2498, NULL, NULL, "Tyan", "S2498 (Tomcat K7M)", 0, w836xx_memw_enable_2e},
- {0x1106, 0x3177, 0x1106, 0xAA01, 0x1106, 0x3123, 0x1106, 0xAA01, NULL, NULL, "VIA", "EPIA M/MII/...", 0, via_vt823x_gpio15_raise},
- {0x1106, 0x0259, 0x1106, 0x3227, 0x1106, 0x3065, 0x1106, 0x3149, NULL, NULL, "VIA", "EPIA-N/NL", 0, via_vt823x_gpio9_raise},
- {0x1106, 0x5337, 0x1458, 0xb003, 0x1106, 0x287e, 0x1106, 0x337e, NULL, NULL, "VIA", "PC3500G", 0, it87xx_probe_spi_flash},
-
- { 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, 0, NULL}, /* end marker */
+ /* first pci-id set [4], second pci-id set [4], superio, coreboot id [2], vendor name board name max_rom_... flash enable */
+ {0x8086, 0x2926, 0x147b, 0x1084, 0x11ab, 0x4364, 0x147b, 0x1084, WB_W83627DHG, NULL, NULL, "Abit", "IP35", 0, intel_ich_gpio16_raise},
+ {0x105a, 0x0d30, 0x105a, 0x4d33, 0x8086, 0x1130, 0x8086, 0, WB_W83627HF, NULL, NULL, "Acorp", "6A815EPD", 0, board_acorp_6a815epd},
+ {0x8086, 0x24D4, 0x1849, 0x24D0, 0x8086, 0x24D5, 0x1849, 0x9739, WB_W83627HF, NULL, NULL, "ASRock", "P4i65GV", 0, intel_ich_gpio23_raise},
+ {0x1022, 0x746B, 0, 0, 0, 0, 0, 0, WB_W83627HF, "AGAMI", "ARUMA", "agami", "Aruma", 0, w83627hf_gpio24_raise},
+ {0x1022, 0x2090, 0, 0, 0x1022, 0x2080, 0, 0, SIO_NONE, "artecgroup", "dbe61", "Artec Group", "DBE61", 0, board_artecgroup_dbe6x},
+ {0x1022, 0x2090, 0, 0, 0x1022, 0x2080, 0, 0, SIO_NONE, "artecgroup", "dbe62", "Artec Group", "DBE62", 0, board_artecgroup_dbe6x},
+ {0x1106, 0x3189, 0x1043, 0x807F, 0x1106, 0x3065, 0x1043, 0x80ED, ITE_IT8712, NULL, NULL, "ASUS", "A7V600-X", 0, board_asus_a7v600x},
+ {0x1106, 0x3189, 0x1043, 0x807F, 0x1106, 0x3177, 0x1043, 0x808C, ITE_IT8703, NULL, NULL, "ASUS", "A7V8X", 0, board_asus_a7v8x},
+ {0x1106, 0x1336, 0x1043, 0x80ed, 0x1106, 0x3288, 0x1043, 0x8249, ITE_IT8716, NULL, NULL, "ASUS", "M2V-MX", 0, via_vt823x_gpio5_raise},
+ {0x8086, 0x1a30, 0x1043, 0x8070, 0x8086, 0x244b, 0x1043, 0x8028, ITE_IT8708, NULL, NULL, "ASUS", "P4B266", 0, intel_ich_gpio22_raise},
+ {0x8086, 0x1A30, 0x1043, 0x8025, 0x8086, 0x244B, 0x104D, 0x80F0, SIO_UNKNOWN, NULL, NULL, "ASUS", "P4B266-LM", 0, intel_ich_gpio21_raise},
+ {0x8086, 0x2570, 0x1043, 0x80F2, 0x105A, 0x3373, 0x1043, 0x80F5, WB_W83627THF, NULL, NULL, "ASUS", "P4P800-E Deluxe", 0, intel_ich_gpio21_raise},
+ {0x10B9, 0x1541, 0, 0, 0x10B9, 0x1533, 0, 0, SIO_UNKNOWN, "asus", "p5a", "ASUS", "P5A", 0, board_asus_p5a},
+ {0x10DE, 0x0030, 0x1043, 0x818a, 0x8086, 0x100E, 0x1043, 0x80EE, SIO_UNKNOWN, NULL, NULL, "ASUS", "P5ND2-SLI Deluxe", 0, nvidia_mcp_gpio10_raise},
+ {0x8086, 0x3590, 0x1028, 0x016c, 0x1000, 0x0030, 0x1028, 0x016c, SIO_UNKNOWN, NULL, NULL, "Dell", "PowerEdge 1850", 0, intel_ich_gpio23_raise},
+ {0x1106, 0x3038, 0x1019, 0x0996, 0x1106, 0x3177, 0x1019, 0x0996, SIO_UNKNOWN, NULL, NULL, "Elitegroup", "K7VTA3", 256, NULL},
+ {0x10EC, 0x8139, 0x1695, 0x9001, 0x11C1, 0x5811, 0x1695, 0x9015, SIO_UNKNOWN, NULL, NULL, "EPoX", "EP-8RDA3+", 0, nvidia_mcp_gpio31_raise},
+ {0x8086, 0x7110, 0, 0, 0x8086, 0x7190, 0, 0, SIO_UNKNOWN, "epox", "ep-bx3", "EPoX", "EP-BX3", 0, board_epox_ep_bx3},
+ {0x10DE, 0x0050, 0x1458, 0x0C11, 0x10DE, 0x005e, 0x1458, 0x5000, SIO_UNKNOWN, NULL, NULL, "GIGABYTE", "GA-K8N-SLI", 0, nvidia_mcp_gpio21_raise},
+ {0x1166, 0x0223, 0x103c, 0x320d, 0x102b, 0x0522, 0x103c, 0x31fa, SIO_UNKNOWN, "hp", "dl145_g3", "HP", "DL145 G3", 0, board_hp_dl145_g3_enable},
+ {0x1166, 0x0205, 0x1014, 0x0347, 0x1002, 0x515E, 0x1014, 0x0325, SIO_UNKNOWN, NULL, NULL, "IBM", "x3455", 0, board_ibm_x3455},
+ {0x1022, 0x7468, 0, 0, 0, 0, 0, 0, WB_W83627HF, "iwill", "dk8_htx", "IWILL", "DK8-HTX", 0, w83627hf_gpio24_raise},
+ {0x8086, 0x27A0, 0, 0, 0x8086, 0x27b8, 0, 0, SIO_UNKNOWN, "kontron", "986lcd-m", "Kontron", "986LCD-M", 0, board_kontron_986lcd_m},
+ {0x8086, 0x2411, 0x8086, 0x2411, 0x8086, 0x7125, 0x0e11, 0xb165, SIO_UNKNOWN, NULL, NULL, "Mitac", "6513WU", 0, board_mitac_6513wu},
+ {0x13f6, 0x0111, 0x1462, 0x5900, 0x1106, 0x3177, 0x1106, 0, WB_W83697HF, NULL, NULL, "MSI", "MS-6590 (KT4 Ultra)", 0, via_vt823x_gpio12_raise},
+ {0x1106, 0x3149, 0x1462, 0x7094, 0x10ec, 0x8167, 0x1462, 0x094c, WB_W83627THF, NULL, NULL, "MSI", "MS-6702E (K8T Neo2-F)", 0, w83627thf_gpio44_raise},
+ {0x1106, 0x0571, 0x1462, 0x7120, 0x1106, 0x3065, 0x1462, 0x7120, WB_W83697HF, NULL, NULL, "MSI", "MS-6712 (KT4V)", 0, via_vt823x_gpio12_raise},
+ {0x1039, 0x7012, 0x1462, 0x0050, 0x1039, 0x6325, 0x1462, 0x0058, WB_W83697HF, NULL, NULL, "MSI", "MS-7005 (651M-L)", 0, board_msi_651ml},
+ {0x8086, 0x2658, 0x1462, 0x7046, 0x1106, 0x3044, 0x1462, 0x046d, SIO_UNKNOWN, NULL, NULL, "MSI", "MS-7046", 0, intel_ich_gpio19_raise},
+ {0x10DE, 0x005E, 0x1462, 0x7135, 0x10DE, 0x0050, 0x1462, 0x7135, WB_W83627THF, "msi", "k8n-neo3", "MSI", "MS-7135 (K8N Neo3)", 0, w83627thf_gpio44_raise},
+ {0x10DE, 0x005E, 0x1462, 0x7125, 0x10DE, 0x0052, 0x1462, 0x7125, SIO_UNKNOWN, NULL, NULL, "MSI", "K8N Neo4-F", 0, nvidia_mcp_gpio2_raise},
+ {0x1106, 0x3104, 0x1297, 0xa238, 0x1106, 0x3059, 0x1297, 0xc063, SIO_UNKNOWN, NULL, NULL, "Shuttle", "AK38N", 256, NULL},
+ {0x10DE, 0x0050, 0x1297, 0x5036, 0x1412, 0x1724, 0x1297, 0x5036, SIO_UNKNOWN, NULL, NULL, "Shuttle", "FN25", 0, board_shuttle_fn25},
+ {0x1106, 0x3038, 0x0925, 0x1234, 0x1106, 0x3058, 0x15DD, 0x7609, SIO_UNKNOWN, NULL, NULL, "Soyo", "SY-7VCA", 0, board_soyo_sy_7vca},
+ {0x1106, 0x3177, 0x1106, 0xAA01, 0x1106, 0x3123, 0x1106, 0xAA01, VIA_VT1211, NULL, NULL, "VIA", "EPIA M/MII/...", 0, via_vt823x_gpio15_raise},
+ {0x1106, 0x0259, 0x1106, 0x3227, 0x1106, 0x3065, 0x1106, 0x3149, SIO_UNKNOWN, NULL, NULL, "VIA", "EPIA-N/NL", 0, via_vt823x_gpio9_raise},
+
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, 0, NULL}, /* end marker */
};
/**
@@ -33,6 +33,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include "flash.h"
+#include "superio.h"
extern int ichspi_lock;
@@ -55,9 +55,6 @@ enum programmer {
#if SATASII_SUPPORT == 1
PROGRAMMER_SATASII,
#endif
-#if INTERNAL_SUPPORT == 1
- PROGRAMMER_IT87SPI,
-#endif
#if FT2232_SPI_SUPPORT == 1
PROGRAMMER_FT2232SPI,
#endif
@@ -262,6 +259,8 @@ struct board_pciid_enable {
uint16_t second_card_vendor;
uint16_t second_card_device;
+ int superio; /* enum superio_chip */
+
/* The vendor / part name from the coreboot table. */
const char *lb_vendor;
const char *lb_part;
@@ -319,12 +318,16 @@ void print_supported_pcidevs(struct pcidev_status *devs);
#endif
void print_supported_wiki(void);
+#if 0
/* board_enable.c */
void w836xx_ext_enter(uint16_t port);
void w836xx_ext_leave(uint16_t port);
uint8_t sio_read(uint16_t port, uint8_t reg);
void sio_write(uint16_t port, uint8_t reg, uint8_t data);
void sio_mask(uint16_t port, uint8_t reg, uint8_t data, uint8_t mask);
+#endif
+
+/* board enable.c */
int board_flash_enable(const char *vendor, const char *part);
/* chipset_enable.c */
@@ -344,14 +347,6 @@ extern int partvendor_from_cbtable;
/* internal.c */
#if NEED_PCI == 1
-struct superio {
- uint16_t vendor;
- uint16_t port;
- uint16_t model;
-};
-extern struct superio superio;
-#define SUPERIO_VENDOR_NONE 0x0
-#define SUPERIO_VENDOR_ITE 0x1
struct pci_dev *pci_dev_find_filter(struct pci_filter filter);
struct pci_dev *pci_dev_find_vendorclass(uint16_t vendor, uint16_t class);
struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device);
@@ -361,7 +356,6 @@ struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device,
void get_io_perms(void);
void release_io_perms(void);
#if INTERNAL_SUPPORT == 1
-void probe_superio(void);
int internal_init(void);
int internal_shutdown(void);
void internal_chip_writeb(uint8_t val, chipaddr addr);
@@ -593,18 +587,6 @@ int ich_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
int ich_spi_write_256(struct flashchip *flash, uint8_t * buf);
int ich_spi_send_multicommand(struct spi_command *cmds);
-/* it87spi.c */
-extern uint16_t it8716f_flashport;
-void enter_conf_mode_ite(uint16_t port);
-void exit_conf_mode_ite(uint16_t port);
-struct superio probe_superio_ite(void);
-int it87spi_init(void);
-int it87xx_probe_spi_flash(const char *name);
-int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt,
- const unsigned char *writearr, unsigned char *readarr);
-int it8716f_spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len);
-int it8716f_spi_chip_write_256(struct flashchip *flash, uint8_t *buf);
-
/* sb600spi.c */
int sb600_spi_send_command(unsigned int writecnt, unsigned int readcnt,
const unsigned char *writearr, unsigned char *readarr);
@@ -612,13 +594,6 @@ int sb600_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
int sb600_spi_write_1(struct flashchip *flash, uint8_t *buf);
extern uint8_t *sb600_spibar;
-/* wbsio_spi.c */
-int wbsio_check_for_spi(const char *name);
-int wbsio_spi_send_command(unsigned int writecnt, unsigned int readcnt,
- const unsigned char *writearr, unsigned char *readarr);
-int wbsio_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
-int wbsio_spi_write_1(struct flashchip *flash, uint8_t *buf);
-
/* serprog.c */
int serprog_init(void);
int serprog_shutdown(void);
@@ -207,25 +207,6 @@ const struct programmer_entry programmer_table[] = {
},
#endif
-#if INTERNAL_SUPPORT == 1
- {
- .name = "it87spi",
- .init = it87spi_init,
- .shutdown = noop_shutdown,
- .map_flash_region = fallback_map,
- .unmap_flash_region = fallback_unmap,
- .chip_readb = noop_chip_readb,
- .chip_readw = fallback_chip_readw,
- .chip_readl = fallback_chip_readl,
- .chip_readn = fallback_chip_readn,
- .chip_writeb = noop_chip_writeb,
- .chip_writew = fallback_chip_writew,
- .chip_writel = fallback_chip_writel,
- .chip_writen = fallback_chip_writen,
- .delay = internal_delay,
- },
-#endif
-
#if FT2232_SPI_SUPPORT == 1
{
.name = "ft2232spi",
@@ -27,6 +27,8 @@
#include <errno.h>
#include "flash.h"
+#include "superio.h"
+
#if defined(__FreeBSD__) || defined(__DragonFly__)
int io_fd;
#endif
@@ -125,17 +127,6 @@ void release_io_perms(void)
}
#if INTERNAL_SUPPORT == 1
-struct superio superio = {};
-
-void probe_superio(void)
-{
- superio = probe_superio_ite();
-#if 0 /* Winbond SuperI/O code is not yet available. */
- if (superio.vendor == SUPERIO_VENDOR_NONE)
- superio = probe_superio_winbond();
-#endif
-}
-
int internal_init(void)
{
int ret = 0;
@@ -153,9 +144,6 @@ int internal_init(void)
*/
coreboot_init();
- /* Probe for the SuperI/O chip and fill global struct superio. */
- probe_superio();
-
/* try to enable it. Failure IS an option, since not all motherboards
* really need this to be done, etc., etc.
*/
@@ -165,6 +153,10 @@ int internal_init(void)
"will most likely fail.\n");
}
+ /* Probe for the SuperI/O chip and fill global struct superio. */
+ superio_probe();
+ superio_init();
+
board_flash_enable(lb_vendor, lb_part);
/* Even if chipset init returns an error code, we don't want to abort.
@@ -27,167 +27,29 @@
#include <stdlib.h>
#include "flash.h"
#include "spi.h"
+#include "superio.h"
-#define ITE_SUPERIO_PORT1 0x2e
-#define ITE_SUPERIO_PORT2 0x4e
-
-uint16_t it8716f_flashport = 0;
+static uint16_t flashport = 0;
/* use fast 33MHz SPI (<>0) or slow 16MHz (0) */
-int fast_spi = 1;
-
-/* Helper functions for most recent ITE IT87xx Super I/O chips */
-#define CHIP_ID_BYTE1_REG 0x20
-#define CHIP_ID_BYTE2_REG 0x21
-void enter_conf_mode_ite(uint16_t port)
-{
- OUTB(0x87, port);
- OUTB(0x01, port);
- OUTB(0x55, port);
- if (port == ITE_SUPERIO_PORT1)
- OUTB(0x55, port);
- else
- OUTB(0xaa, port);
-}
+static int fast_spi = 1;
-void exit_conf_mode_ite(uint16_t port)
+int it8716_spi_init(uint16_t port)
{
- sio_write(port, 0x02, 0x02);
-}
+ ite_conf_mode_enter(port);
-uint16_t probe_id_ite(uint16_t port)
-{
- uint16_t id;
-
- enter_conf_mode_ite(port);
- id = sio_read(port, CHIP_ID_BYTE1_REG) << 8;
- id |= sio_read(port, CHIP_ID_BYTE2_REG);
- exit_conf_mode_ite(port);
-
- return id;
-}
-
-struct superio probe_superio_ite(void)
-{
- struct superio ret = {};
- uint16_t ite_ports[] = {ITE_SUPERIO_PORT1, ITE_SUPERIO_PORT2, 0};
- uint16_t *i = ite_ports;
-
- ret.vendor = SUPERIO_VENDOR_ITE;
- for (; *i; i++) {
- ret.port = *i;
- ret.model = probe_id_ite(ret.port);
- switch (ret.model >> 8) {
- case 0x82:
- case 0x86:
- case 0x87:
- msg_pinfo("Found ITE SuperI/O, id %04hx\n",
- ret.model);
- return ret;
- }
- }
-
- /* No good ID found. */
- ret.vendor = SUPERIO_VENDOR_NONE;
- ret.port = 0;
- ret.model = 0;
- return ret;
-}
-
-static uint16_t find_ite_spi_flash_port(uint16_t port, uint16_t id)
-{
- uint8_t tmp = 0;
- char *portpos = NULL;
- uint16_t flashport = 0;
-
- switch (id) {
- case 0x8716:
- case 0x8718:
- enter_conf_mode_ite(port);
- /* NOLDN, reg 0x24, mask out lowest bit (suspend) */
- tmp = sio_read(port, 0x24) & 0xFE;
- msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n",
- 0xFFFE0000, 0xFFFFFFFF, (tmp & 1 << 1) ? "en" : "dis");
- msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n",
- 0x000E0000, 0x000FFFFF, (tmp & 1 << 1) ? "en" : "dis");
- msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n",
- 0xFFEE0000, 0xFFEFFFFF, (tmp & 1 << 2) ? "en" : "dis");
- msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n",
- 0xFFF80000, 0xFFFEFFFF, (tmp & 1 << 3) ? "en" : "dis");
- msg_pdbg("LPC write to serial flash %sabled\n",
- (tmp & 1 << 4) ? "en" : "dis");
- /* The LPC->SPI force write enable below only makes sense for
- * non-programmer mode.
- */
- /* If any serial flash segment is enabled, enable writing. */
- if ((tmp & 0xe) && (!(tmp & 1 << 4))) {
- msg_pdbg("Enabling LPC write to serial flash\n");
- tmp |= 1 << 4;
- sio_write(port, 0x24, tmp);
- }
- msg_pdbg("Serial flash pin %i\n", (tmp & 1 << 5) ? 87 : 29);
+ if (sio_read(port, 0x24) & 0x10) {
/* LDN 0x7, reg 0x64/0x65 */
sio_write(port, 0x07, 0x7);
flashport = sio_read(port, 0x64) << 8;
flashport |= sio_read(port, 0x65);
- msg_pdbg("Serial flash port 0x%04x\n", flashport);
- if (programmer_param && !strlen(programmer_param)) {
- free(programmer_param);
- programmer_param = NULL;
- }
- if (programmer_param && (portpos = strstr(programmer_param, "port="))) {
- portpos += 5;
- flashport = strtol(portpos, (char **)NULL, 0);
- msg_pinfo("Forcing serial flash port 0x%04x\n", flashport);
- sio_write(port, 0x64, (flashport >> 8));
- sio_write(port, 0x65, (flashport & 0xff));
- }
- exit_conf_mode_ite(port);
- break;
- /* TODO: Handle more IT87xx if they support flash translation */
- default:
- msg_pinfo("SuperI/O ID %04hx is not on the controller list.\n", id);
- }
- return flashport;
-}
-
-int it87spi_common_init(void)
-{
- if (superio.vendor != SUPERIO_VENDOR_ITE)
- return 1;
-
- it8716f_flashport = find_ite_spi_flash_port(superio.port, superio.model);
-
- if (it8716f_flashport)
- spi_controller = SPI_CONTROLLER_IT87XX;
-
- return (!it8716f_flashport);
-}
-
-int it87spi_init(void)
-{
- int ret;
-
- get_io_perms();
- /* Probe for the SuperI/O chip and fill global struct superio. */
- probe_superio();
- ret = it87spi_common_init();
- if (!ret) {
- buses_supported = CHIP_BUSTYPE_SPI;
- } else {
- buses_supported = CHIP_BUSTYPE_NONE;
+ if (flashport) {
+ spi_controller = SPI_CONTROLLER_IT87XX;
+ buses_supported = CHIP_BUSTYPE_SPI;
+ }
}
- return ret;
-}
-int it87xx_probe_spi_flash(const char *name)
-{
- int ret;
-
- ret = it87spi_common_init();
- if (!ret)
- buses_supported |= CHIP_BUSTYPE_SPI;
- return ret;
+ return 0;
}
/*
@@ -206,7 +68,7 @@ int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt,
int i;
do {
- busy = INB(it8716f_flashport) & 0x80;
+ busy = INB(flashport) & 0x80;
} while (busy);
if (readcnt > 3) {
msg_pinfo("%s called with unsupported readcnt %i.\n",
@@ -215,27 +77,27 @@ int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt,
}
switch (writecnt) {
case 1:
- OUTB(writearr[0], it8716f_flashport + 1);
+ OUTB(writearr[0], flashport + 1);
writeenc = 0x0;
break;
case 2:
- OUTB(writearr[0], it8716f_flashport + 1);
- OUTB(writearr[1], it8716f_flashport + 7);
+ OUTB(writearr[0], flashport + 1);
+ OUTB(writearr[1], flashport + 7);
writeenc = 0x1;
break;
case 4:
- OUTB(writearr[0], it8716f_flashport + 1);
- OUTB(writearr[1], it8716f_flashport + 4);
- OUTB(writearr[2], it8716f_flashport + 3);
- OUTB(writearr[3], it8716f_flashport + 2);
+ OUTB(writearr[0], flashport + 1);
+ OUTB(writearr[1], flashport + 4);
+ OUTB(writearr[2], flashport + 3);
+ OUTB(writearr[3], flashport + 2);
writeenc = 0x2;
break;
case 5:
- OUTB(writearr[0], it8716f_flashport + 1);
- OUTB(writearr[1], it8716f_flashport + 4);
- OUTB(writearr[2], it8716f_flashport + 3);
- OUTB(writearr[3], it8716f_flashport + 2);
- OUTB(writearr[4], it8716f_flashport + 7);
+ OUTB(writearr[0], flashport + 1);
+ OUTB(writearr[1], flashport + 4);
+ OUTB(writearr[2], flashport + 3);
+ OUTB(writearr[3], flashport + 2);
+ OUTB(writearr[4], flashport + 7);
writeenc = 0x3;
break;
default:
@@ -249,15 +111,15 @@ int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt,
* We can't use writecnt directly, but have to use a strange encoding.
*/
OUTB(((0x4 + (fast_spi ? 1 : 0)) << 4)
- | ((readcnt & 0x3) << 2) | (writeenc), it8716f_flashport);
+ | ((readcnt & 0x3) << 2) | (writeenc), flashport);
if (readcnt > 0) {
do {
- busy = INB(it8716f_flashport) & 0x80;
+ busy = INB(flashport) & 0x80;
} while (busy);
for (i = 0; i < readcnt; i++)
- readarr[i] = INB(it8716f_flashport + 5 + i);
+ readarr[i] = INB(flashport + 5 + i);
}
return 0;
@@ -274,12 +136,12 @@ static int it8716f_spi_page_program(struct flashchip *flash, int block, uint8_t
if (result)
return result;
/* FIXME: The command below seems to be redundant or wrong. */
- OUTB(0x06, it8716f_flashport + 1);
- OUTB(((2 + (fast_spi ? 1 : 0)) << 4), it8716f_flashport);
+ OUTB(0x06, flashport + 1);
+ OUTB(((2 + (fast_spi ? 1 : 0)) << 4), flashport);
for (i = 0; i < 256; i++) {
chip_writeb(buf[256 * block + i], bios + 256 * block + i);
}
- OUTB(0, it8716f_flashport);
+ OUTB(0, flashport);
/* Wait until the Write-In-Progress bit is cleared.
* This usually takes 1-10 ms, so wait in 1 ms steps.
*/
@@ -297,7 +159,7 @@ int it8716f_spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int
int total_size = 1024 * flash->total_size;
fast_spi = 0;
- if ((programmer == PROGRAMMER_IT87SPI) || (total_size > 512 * 1024)) {
+ if (total_size > 512 * 1024) {
spi_read_chunked(flash, buf, start, len, 3);
} else {
read_memmapped(flash, buf, start, len);
@@ -315,7 +177,7 @@ int it8716f_spi_chip_write_256(struct flashchip *flash, uint8_t *buf)
* IT8716F only allows maximum of 512 kb SPI chip size for memory
* mapped access.
*/
- if ((programmer == PROGRAMMER_IT87SPI) || (total_size > 512 * 1024)) {
+ if (total_size > 512 * 1024) {
spi_chip_write_1(flash, buf);
} else {
spi_disable_blockprotect();
@@ -26,6 +26,7 @@
#include "flash.h"
#include "flashchips.h"
#include "spi.h"
+#include "superio.h" /* for it87spi and wbsio */
enum spi_controller spi_controller = SPI_CONTROLLER_NONE;
void *spibar = NULL;
new file mode 100644
@@ -0,0 +1,454 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+
+
+#include "hwaccess.h"
+
+#include "flash.h" /* GRR! */
+
+#include "superio.h"
+
+/* Preset global variables. */
+struct superio *superio = NULL;
+uint16_t superio_port = 0;
+
+#include "flash.h"
+
+/**
+ *
+ */
+char *superio_chip_name(enum superio_chip chip)
+{
+ struct {
+ enum superio_chip chip;
+ char *name;
+ } superio_chip_name[] = {
+ {ITE_IT8703, "ITE IT8703"},
+ {ITE_IT8705, "ITE IT8705"},
+ {ITE_IT8712, "ITE IT8712"},
+ {ITE_IT8716, "ITE IT8716"},
+ {ITE_IT8718, "ITE IT8718"},
+ {VIA_VT1211, "VIA VT1211"},
+ {WB_W83627DHG, "Winbond W83627DHG"},
+ {WB_W83627EHF, "Winbond W83627EHF/EF/EHG/EG"},
+ {WB_W83627HF, "Winbond W83627HF"},
+ {WB_W83627THF, "Winbond W83627THF"},
+ {WB_W83697HF, "Winbond W83697HF"},
+ {SIO_NONE, NULL},
+ };
+ int i;
+
+ for (i = 0; superio_chip_name[i].name; i++)
+ if (superio_chip_name[i].chip == chip)
+ return superio_chip_name[i].name;
+
+ return "Unknown";
+}
+
+/* Generic Super I/O helper functions */
+uint8_t
+sio_read(uint16_t port, uint8_t reg)
+{
+ OUTB(reg, port);
+ return INB(port + 1);
+}
+
+void
+sio_write(uint16_t port, uint8_t reg, uint8_t data)
+{
+ OUTB(reg, port);
+ OUTB(data, port + 1);
+}
+
+void
+sio_mask(uint16_t port, uint8_t reg, uint8_t data, uint8_t mask)
+{
+ uint8_t tmp;
+
+ OUTB(reg, port);
+ tmp = INB(port + 1) & ~mask;
+ OUTB(tmp | (data & mask), port + 1);
+}
+
+/*
+ * Helper functions for many Winbond Super I/Os of the W836xx range.
+ */
+/* Enter extended functions */
+void
+w836xx_ext_enter(uint16_t port)
+{
+ OUTB(0x87, port);
+ OUTB(0x87, port);
+}
+
+/* Leave extended functions */
+void
+w836xx_ext_leave(uint16_t port)
+{
+ OUTB(0xAA, port);
+}
+
+/**
+ *
+ */
+static uint16_t
+w836xx_detect(uint16_t port)
+{
+ uint16_t id;
+
+ w836xx_ext_enter(port);
+ id = sio_read(port, 0x20);
+ w836xx_ext_leave(port);
+
+ return id;
+}
+
+/**
+ * Only sets gpio24 for now.
+ */
+static int
+w83627hf_gpio_set(uint16_t port, int gpio, int raise)
+{
+ if (gpio != 24) {
+ fprintf(stderr, "\nERROR: Only gpio24 is supported.\n");
+ return 1;
+ }
+
+
+ w836xx_ext_enter(port);
+
+ /* PIN89S: WDTO/GP24 multiplex -> GPIO24 */
+ sio_mask(port, 0x2B, 0x10, 0x10);
+
+ /* Select logical device 8: GPIO port 2 */
+ sio_write(port, 0x07, 0x08);
+
+ sio_mask(port, 0x30, 0x01, 0x01); /* Activate logical device. */
+ sio_mask(port, 0xF0, 0x00, 0x10); /* GPIO24 -> output */
+ sio_mask(port, 0xF2, 0x00, 0x10); /* Clear GPIO24 inversion */
+
+ if (raise)
+ sio_mask(port, 0xF1, 0x10, 0x10);
+ else
+ sio_mask(port, 0xF1, 0, 0x10);
+
+ w836xx_ext_leave(port);
+
+ return 0;
+}
+
+/**
+ * Only raises gpio44 for now.
+ */
+static int
+w83627thf_gpio_set(uint16_t port, int gpio, int raise)
+{
+ if (gpio != 44) {
+ fprintf(stderr, "\nERROR: Only gpio44 is supported.\n");
+ return 1;
+ }
+
+ w836xx_ext_enter(port);
+
+ /* PINxxxxS: GPIO4/bit 4 multiplex -> GPIOXXX */
+
+ sio_write(port, 0x07, 0x09); /* Select LDN 9: GPIO port 4 */
+ sio_mask(port, 0x30, 0x02, 0x02); /* Activate logical device. */
+ sio_mask(port, 0xF4, 0x00, 0x10); /* GPIO4 bit 4 -> output */
+ sio_mask(port, 0xF6, 0x00, 0x10); /* Clear GPIO4 bit 4 inversion */
+ sio_mask(port, 0xF5, 0x10, 0x10); /* Raise GPIO4 bit 4 */
+
+ w836xx_ext_leave(port);
+
+ return 0;
+}
+
+#if 0
+/**
+ * w83697hf: Enable MEMW# and set ROM size to max.
+ */
+static int
+w83697hf_memw_enable(uint16_t port)
+{
+ w836xx_ext_enter(port);
+ if (!(sio_read(port, 0x24) & 0x02)) { /* Flash ROM enabled? */
+ /* Enable MEMW# and set ROM size select to max. (4M). */
+ sio_mask(port, 0x24, 0x28, 0x28);
+ }
+ w836xx_ext_leave(port);
+
+ return 0;
+}
+#endif
+
+/*
+ *
+ * ITE functions.
+ *
+ */
+
+/**
+ *
+ */
+void
+ite_conf_mode_enter(uint16_t port)
+{
+ OUTB(0x87, port);
+ OUTB(0x01, port);
+ OUTB(0x55, port);
+ if (port == 0x2E)
+ OUTB(0x55, port);
+ else
+ OUTB(0xaa, port);
+}
+
+/**
+ *
+ */
+void
+ite_conf_mode_exit(uint16_t port)
+{
+ sio_write(port, 0x02, 0x02);
+}
+
+/**
+ *
+ */
+static uint16_t
+it87xx_detect(uint16_t port)
+{
+ uint16_t id;
+
+ ite_conf_mode_enter(port);
+ id = (sio_read(port, 0x20) << 8) | sio_read(port, 0x21);
+ ite_conf_mode_exit(port);
+
+ return id;
+}
+
+/**
+ *
+ */
+static int
+it8705f_write_enable(uint16_t port)
+{
+ ite_conf_mode_enter(port);
+ sio_mask(port, 0x24, 0x04, 0x04); /* Flash ROM I/F Writes Enable */
+ ite_conf_mode_exit(port);
+
+ return 0;
+}
+
+/**
+ * Only raises gpio51 for now.
+ */
+static int
+it8703_gpio_set(uint16_t port, int gpio, int raise)
+{
+ uint16_t base;
+ uint8_t tmp;
+
+ if (gpio != 51) {
+ fprintf(stderr, "\nERROR: Only gpio51 is supported.\n");
+ return -1;
+ }
+
+ /* Get the GP567 IO base */
+ w836xx_ext_enter(port);
+ sio_write(port, 0x07, 0x0C);
+ base = (sio_read(port, 0x60) << 8) | sio_read(port, 0x61);
+ w836xx_ext_leave(port);
+
+ if (!base) {
+ fprintf(stderr, "\nERROR: Failed to read IT8703F SuperIO GPIO"
+ " Base.\n");
+ return -1;
+ }
+
+ /* Raise GP51. */
+ tmp = INB(base);
+ if (raise)
+ tmp |= 0x02;
+ else
+ tmp &= ~0x02;
+ OUTB(tmp, base);
+
+ return 0;
+}
+
+/*
+ * General routine for raising/dropping GPIO lines on the ITE IT8712F.
+ * There is only some limited checking on the port numbers.
+ */
+static int
+it8712f_gpio_set(uint16_t port, int gpio, int raise)
+{
+ unsigned int block;
+ uint16_t base;
+ uint8_t tmp;
+
+ block = gpio / 10;
+ block--;
+ gpio %= 10;
+
+ /* Check gpio */
+ if ((block > 4) || /* also catches unsigned -1 */
+ ((block < 4) && (gpio > 7)) || ((block == 4) && (gpio > 5))) {
+ fprintf(stderr,
+ "\nERROR: Unsupported IT8712F GPIO %02d.\n", gpio);
+ return -1;
+ }
+
+ /* Get the GPIO base */
+ ite_conf_mode_enter(port);
+ sio_write(port, 0x07, 0x07);
+ base = (sio_read(port, 0x62) << 8) | sio_read(port, 0x63);
+ ite_conf_mode_exit(port);
+
+ if (!base) {
+ fprintf(stderr, "\nERROR: Failed to read IT8712F SuperIO GPIO"
+ " Base.\n");
+ return -1;
+ }
+
+ /* set GPIO. */
+ tmp = INB(base + block);
+ if (raise)
+ tmp |= 1 << gpio;
+ else
+ tmp &= ~(1 << gpio);
+ OUTB(tmp, base + block);
+
+ return 0;
+}
+
+/**
+ *
+ */
+static struct superio superios[] = {
+ {it87xx_detect, 0x8701, ITE_IT8703, NULL, it8703_gpio_set},
+ {it87xx_detect, 0x8705, ITE_IT8705, it8705f_write_enable, NULL},
+ {it87xx_detect, 0x8712, ITE_IT8712, NULL, it8712f_gpio_set},
+ {it87xx_detect, 0x8716, ITE_IT8716, it8716_spi_init, NULL},
+ {it87xx_detect, 0x8718, ITE_IT8718, it8716_spi_init, NULL},
+ {w836xx_detect, 0x3C, VIA_VT1211, NULL, NULL},
+ {w836xx_detect, 0x52, WB_W83627HF, NULL, w83627hf_gpio_set},
+ //{w836xx_detect, 0x60, WB_W83697HF, w83697hf_memw_enable, NULL},
+ {w836xx_detect, 0x82, WB_W83627THF, NULL, w83627thf_gpio_set},
+ {w836xx_detect, 0x88, WB_W83627EHF, NULL, NULL},
+ {w836xx_detect, 0xA0, WB_W83627DHG, w83627dhg_spi_init, NULL},
+
+ {NULL, 0, SIO_NONE, NULL, NULL} /* end marker */
+};
+
+/*
+ *
+ * High level routines.
+ *
+ */
+
+/*
+ *
+ */
+int
+superio_probe(void)
+{
+ struct superio_detect {
+ uint16_t port;
+ uint16_t (*detect) (uint16_t port);
+ char *name;
+ } superio_detects[] = {
+ {0x2E, w836xx_detect, "Winbond W836xx"},
+ {0x4E, w836xx_detect, "Winbond W836xx"},
+ {0x2E, it87xx_detect, "ITE IT87xx"},
+ {0x4E, it87xx_detect, "ITE IT87xx"},
+
+ {0, NULL} /* end marker */
+ };
+
+ int i, j;
+ uint16_t id;
+
+ for (i = 0; superio_detects[i].detect; i++) {
+
+ id = superio_detects[i].detect(superio_detects[i].port);
+ if ((id == 0xFF) || (id == 0xFFFF))
+ continue;
+
+ msg_pdbg("Superio detection for \"%s\" on 0x%X"
+ " returned 0x%0X\n", superio_detects[i].name,
+ superio_detects[i].port, id);
+
+ for (j = 0; superios[j].detect; j++) {
+ if ((superios[j].detect == superio_detects[i].detect) &&
+ (id == superios[j].id)) {
+ superio = &superios[j];
+ superio_port = superio_detects[i].port;
+ break;
+ }
+ }
+
+ if (!superio)
+ msg_perr("No matching superio found for \"%s\" (0x%X) :"
+ " 0x%0X\n", superio_detects[i].name,
+ superio_detects[i].port, id);
+ }
+
+ if (superio)
+ msg_pinfo("Superio \"%s\" detected on 0x%0X.\n",
+ superio_chip_name(superio->chip), superio_port);
+ else
+ msg_pdbg("No Superio chip detected.\n");
+
+ return 0;
+}
+
+/*
+ *
+ */
+int
+superio_init(void)
+{
+ if (!superio || !superio->init)
+ return 0; /* not an error */
+
+ printf("Initialising \"%s\" superio.\n",
+ superio_chip_name(superio->chip));
+
+ return superio->init(superio_port);
+}
+
+/*
+ *
+ */
+int
+superio_gpio_set(int gpio, int raise)
+{
+ if (!superio || !superio->gpio_set) {
+ printf("Error: Unable to set gpio line on superio.\n");
+ return 1;
+ }
+
+ printf("Setting GPIO%d(%X) on superio \"%s\" to %s\n",
+ gpio, gpio, superio_chip_name(superio->chip),
+ raise ? "high" : "low");
+
+ return superio->gpio_set(superio_port, gpio, raise);
+}
new file mode 100644
@@ -0,0 +1,107 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef HAVE_SUPERIO_H
+#define HAVE_SUPERIO_H 1
+
+/*
+ *
+ */
+enum superio_chip {
+ SIO_NONE = 0,
+
+ /* ITE */
+ ITE_IT8703,
+ ITE_IT8705,
+ ITE_IT8708,
+ ITE_IT8712,
+ ITE_IT8716,
+ ITE_IT8718,
+
+ /* A lonesome VIA superio */
+ VIA_VT1211,
+
+ /* Winbond */
+ WB_W83627DHG,
+ WB_W83627EHF,
+ WB_W83627HF,
+ WB_W83627THF,
+ WB_W83697HF,
+
+ SIO_UNKNOWN
+};
+
+/*
+ *
+ */
+struct superio {
+ uint16_t (*detect) (uint16_t port);
+ uint16_t id;
+
+ enum superio_chip chip;
+
+ int (*init) (uint16_t port);
+ int (*gpio_set) (uint16_t port, int gpio, int raise);
+};
+
+struct superio *superio;
+uint16_t superio_port;
+
+uint8_t sio_read(uint16_t port, uint8_t reg);
+void sio_write(uint16_t port, uint8_t reg, uint8_t data);
+void sio_mask(uint16_t port, uint8_t reg, uint8_t data, uint8_t mask);
+
+void w836xx_ext_enter(uint16_t port);
+void w836xx_ext_leave(uint16_t port);
+
+void ite_conf_mode_enter(uint16_t port);
+void ite_conf_mode_exit(uint16_t port);
+
+/*
+ * High level calls.
+ */
+int superio_probe(void);
+int superio_init(void);
+int superio_gpio_set(int gpio, int raise);
+
+/*
+ *
+ * Will someone please pour the programmer infrastructure in a struct with
+ * callbacks that gets created by the init functions below? This lack of
+ * abstraction now causes us to have to include horrible flash.h before
+ * this file.
+ *
+ */
+
+/*
+ * it87spi.c
+ */
+int it8716_spi_init(uint16_t port);
+int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+ const unsigned char *writearr, unsigned char *readarr);
+int it8716f_spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len);
+int it8716f_spi_chip_write_256(struct flashchip *flash, uint8_t *buf);
+
+/*
+ * wbsio_spi.c
+ */
+int w83627dhg_spi_init(uint16_t port);
+int wbsio_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+ const unsigned char *writearr, unsigned char *readarr);
+int wbsio_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
+int wbsio_spi_write_1(struct flashchip *flash, uint8_t *buf);
+
+#endif /* HAVE_SUPERIO_H */
@@ -21,52 +21,28 @@
#include <string.h>
#include "flash.h"
#include "spi.h"
-
-#define WBSIO_PORT1 0x2e
-#define WBSIO_PORT2 0x4e
+#include "superio.h"
static uint16_t wbsio_spibase = 0;
-static uint16_t wbsio_get_spibase(uint16_t port)
+int w83627dhg_spi_init(uint16_t port)
{
- uint8_t id;
- uint16_t flashport = 0;
-
w836xx_ext_enter(port);
- id = sio_read(port, 0x20);
- if (id != 0xa0) {
- msg_perr("\nW83627 not found at 0x%x, id=0x%02x want=0xa0.\n", port, id);
- goto done;
- }
- if (0 == (sio_read(port, 0x24) & 2)) {
- msg_perr("\nW83627 found at 0x%x, but SPI pins are not enabled. (CR[0x24] bit 1=0)\n", port);
- goto done;
- }
+ if (sio_read(port, 0x24) & 0x02) { /* Are SPI pins enabled? */
+ sio_write(port, 0x07, 0x06); /* LDN 6 */
+ if (sio_read(port, 0x30) & 0x01) { /* SPI enabled? */
+ wbsio_spibase = (sio_read(port, 0x62) << 8) |
+ sio_read(port, 0x63);
- sio_write(port, 0x07, 0x06);
- if (0 == (sio_read(port, 0x30) & 1)) {
- msg_perr("\nW83627 found at 0x%x, but SPI is not enabled. (LDN6[0x30] bit 0=0)\n", port);
- goto done;
- }
+ msg_pspew("\nwbsio_spibase = 0x%x\n", wbsio_spibase);
- flashport = (sio_read(port, 0x62) << 8) | sio_read(port, 0x63);
+ buses_supported |= CHIP_BUSTYPE_SPI;
+ spi_controller = SPI_CONTROLLER_WBSIO;
+ }
+ }
-done:
w836xx_ext_leave(port);
- return flashport;
-}
-
-int wbsio_check_for_spi(const char *name)
-{
- if (0 == (wbsio_spibase = wbsio_get_spibase(WBSIO_PORT1)))
- if (0 == (wbsio_spibase = wbsio_get_spibase(WBSIO_PORT2)))
- return 1;
-
- msg_pspew("\nwbsio_spibase = 0x%x\n", wbsio_spibase);
-
- buses_supported |= CHIP_BUSTYPE_SPI;
- spi_controller = SPI_CONTROLLER_WBSIO;
return 0;
}
--
1.6.0.2