On 25.09.2007 01:17, Uwe Hermann wrote:
On Mon, Sep 24, 2007 at 12:10:15PM +0200, Carl-Daniel Hailfinger wrote:
+uint8_t regval(uint16_t port, uint8_t reg)
Why not regread() btw? Just a minor issue.
Straight copy from flashrom. Besides that, val is shorter and sounds nicer.
- if (id == 0x8716) {
/* LDN 0x0, reg 0x24, mask out lowest bit (suspend) */
regwrite(port, 0x07, 0x0);
tmp = regval(port, 0x24) & 0xFE;
Why LDN 0? Isn't that for floppy stuff? 0x24 can be manipulated regardless of any LDN, IIRC.
superiotool output was a bit misleading. LDN 0 isn't needed.
+static void it8716_serial_rdid(uint16_t port) +{
- uint8_t busy, data0, data1, data2;
- do {
busy = inb(0x0820) & 0x80;
- } while (busy);
- /* RDID */
- outb(0x9f, 0x0820 + 1);
Should this be a #define?
No. Old code version. Will send new patch.
- /* Start IO, 33MHz, 3 input bytes, 0 output bytes*/
- outb((0x5<<4)|(0x3<<2)|(0x0), 0x0820);
- do {
busy = inb(0x0820) & 0x80;
- } while (busy);
- data0 = inb(0x0820 + 5);
- data1 = inb(0x0820 + 6);
- data2 = inb(0x0820 + 7);
#defines? SPI_IDATA0 etc.
- printf("RDID returned %02x %02x %02x\n", data0, data1, data2);
- return;
Not needed, the function returns void.
Explicit return statements are nice and this will return a value in the future.
+static int gam57sli_probe_serial_flash(const char *name)
Let's use the full/correct name for the board. In this case: ga_m57sli_s4_probe_serial_flash or gam57slis4_probe_serial_flash (I think the first version is more readable)
This works for all boards with SPI hanging off IT8716F, so more generic name needed.
+{
- uint16_t flashport;
- flashport = find_ite_serial_flash_port(0x2e);
- if (flashport)
it8716_serial_rdid(flashport);
- flashport = find_ite_serial_flash_port(0x4e);
- if (flashport)
it8716_serial_rdid(flashport);
- return 0;
If the function always returns the same value, maybe we should make it return void?
Function must return int unless you change all other probe functions.
struct board_pciid_enable board_pciid_enables[] = {
- {0x10de, 0x0360, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
"gigabyte", "gam57sli", "Gigabyte GA-M57SLI", gam57sli_probe_serial_flash},
"gigabyte", "ga-m57sli-s4", "GIGABYTE GA-M57SLI-S4", ga_m57sli_s4_probe_serial_flash},
(or similar, depending on the above function name)
GIGABYTE is all-caps as they use that form on their website.
ok, done.
Updated patch attached. This one was unfortunately an old version of the code.
Carl-Daniel
Index: util/flashrom/board_enable.c =================================================================== --- util/flashrom/board_enable.c (Revision 2802) +++ util/flashrom/board_enable.c (Arbeitskopie) @@ -4,6 +4,7 @@ * Copyright (C) 2005-2007 coresystems GmbH stepan@coresystems.de * Copyright (C) 2006 Uwe Hermann uwe@hermann-uwe.de * Copyright (C) 2007 Luc Verhaegen libv@skynet.be + * Copyright (C) 2007 Carl-Daniel Hailfinger * * 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 @@ -29,6 +30,104 @@ #include <string.h> #include "flash.h"
+/* Generic Super I/O helper functions */ +uint8_t regval(uint16_t port, uint8_t reg) +{ + outb(reg, port); + return inb(port + 1); +} + +void regwrite(uint16_t port, uint8_t reg, uint8_t val) +{ + outb(reg, port); + outb(val, port + 1); +} + +/* Helper functions for most recent ITE IT87xx Super I/O chips */ +#define CHIP_ID_BYTE1_REG 0x20 +#define CHIP_ID_BYTE2_REG 0x21 +static void enter_conf_mode_ite(uint16_t port) +{ + outb(0x87, port); + outb(0x01, port); + outb(0x55, port); + if (port == 0x2e) + outb(0x55, port); + else + outb(0xaa, port); +} + +static void exit_conf_mode_ite(uint16_t port) +{ + regwrite(port, 0x02, 0x02); +} + +static uint16_t find_ite_serial_flash_port(uint16_t port) +{ + uint8_t tmp = 0; + uint16_t id, flashport = 0; + + enter_conf_mode_ite(port); + + id = regval(port, CHIP_ID_BYTE1_REG) << 8; + id |= regval(port, CHIP_ID_BYTE2_REG); + + /* TODO: Handle more IT87xx if they support flash translation */ + if (id == 0x8716) { + /* NOLDN, reg 0x24, mask out lowest bit (suspend) */ + tmp = regval(port, 0x24) & 0xFE; + printf("Serial flash segment 0x%08x-0x%08x %sabled\n", + 0xFFFE0000, 0xFFFFFFFF, (tmp & 1 << 1) ? "en" : "dis"); + printf("Serial flash segment 0x%08x-0x%08x %sabled\n", + 0x000E0000, 0x000FFFFF, (tmp & 1 << 1) ? "en" : "dis"); + printf("Serial flash segment 0x%08x-0x%08x %sabled\n", + 0xFFEE0000, 0xFFEFFFFF, (tmp & 1 << 2) ? "en" : "dis"); + printf("Serial flash segment 0x%08x-0x%08x %sabled\n", + 0xFFF80000, 0xFFFEFFFF, (tmp & 1 << 3) ? "en" : "dis"); + printf("LPC write to serial flash %sabled\n", + (tmp & 1 << 4) ? "en" : "dis"); + printf("serial flash pin %i\n", (tmp & 1 << 5) ? 87 : 29); + /* LDN 0x7, reg 0x64/0x65 */ + regwrite(port, 0x07, 0x7); + flashport = regval(port, 0x64) << 8; + flashport |= regval(port, 0x65); + } + exit_conf_mode_ite(port); + return flashport; +} + +static void it8716_serial_rdid(uint16_t port) +{ + uint8_t busy, data0, data1, data2; + do { + busy = inb(port) & 0x80; + } while (busy); + /* RDID */ + outb(0x9f, port + 1); + /* Start IO, 33MHz, 3 input bytes, 0 output bytes*/ + outb((0x5<<4)|(0x3<<2)|(0x0), port); + do { + busy = inb(port) & 0x80; + } while (busy); + data0 = inb(port + 5); + data1 = inb(port + 6); + data2 = inb(port + 7); + printf("RDID returned %02x %02x %02x\n", data0, data1, data2); + return; +} + +static int it87xx_probe_serial_flash(const char *name) +{ + uint16_t flashport; + flashport = find_ite_serial_flash_port(0x2e); + if (flashport) + it8716_serial_rdid(flashport); + flashport = find_ite_serial_flash_port(0x4e); + if (flashport) + it8716_serial_rdid(flashport); + return 0; +} + /* * Helper functions for many Winbond Super I/Os of the W836xx range. */ @@ -314,6 +413,8 @@ };
struct board_pciid_enable board_pciid_enables[] = { + {0x10de, 0x0360, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + "gigabyte", "ga-m57sli", "GIGABYTE GA-M57SLI", it87xx_probe_serial_flash}, {0x1022, 0x7468, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, "iwill", "dk8_htx", "IWILL DK8-HTX", w83627hf_gpio24_raise}, {0x1022, 0x746B, 0x1022, 0x36C0, 0x0000, 0x0000, 0x0000, 0x0000,