[flashrom] [Patch] Preliminary general superio support.
Luc Verhaegen
libv at skynet.be
Wed Jan 20 23:02:31 CET 2010
On Wed, Jan 20, 2010 at 04:14:42PM +0100, Luc Verhaegen wrote:
> Very untested and new. Sent in to show off what is being worked on and
> to get first impressions.
>
> Last i tried it worked fine on:
> * Winbond W83627EHF on MSI Fuzzy CN700 (nothing needed, just detection).
> * Winbond W83697HF on Asus 7V8X-MX SE (needing superio rom write enable)
>
> To be tested still:
> * it8705F rom write enable (have shuttle board here that i should still
> test on).
> * it87 spi code (have nonspi board here that i should still test on).
>
> Luc Verhaegen.
> >From f98cbb703f2bbbb918a87eebcd10c4cc1bd457f9 Mon Sep 17 00:00:00 2001
> From: Luc Verhaegen <libv at 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
> +/**
> + *
> + */
> +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},
Guess what i tested here :)
> + {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 */
> +};
Table with the action.
> +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;
> +}
Here we do the detection in a clean way with little noise.
> +++ b/superio.h
> @@ -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 */
Anyway, here is an example of two test runs last weeks:
n the asus A7V8X-MX SE (which up until now required a board enable to init the superio).
With just superio_probe():
> /tmp/flashrom_superio# ./flashrom
> flashrom v0.9.1-runknown
> No coreboot table found.
> Found chipset "VIA VT8235", enabling flash write... OK.
> This chipset supports the following protocols: Non-SPI.
> Superio "Winbond W83697HF" detected on 0x2E.
> Calibrating delay loop... OK.
> No EEPROM/flash device found.
> If you know which flash chip you have, and if this version of flashrom
> supports a similar flash chip, you can try to force read your chip. Run:
> flashrom -f -r -c similar_supported_flash_chip filename
>
> Note: flashrom can never write when the flash chip isn't found automatically.
After adding superio_init(), which runs the initialisation code, when a
superio has been identified and when the init callback is there:
> /tmp/flashrom_superio# ./flashrom
> flashrom v0.9.1-runknown
> No coreboot table found.
> Found chipset "VIA VT8235", enabling flash write... OK.
> This chipset supports the following protocols: Non-SPI.
> Superio "Winbond W83697HF" detected on 0x2E.
> Initialising "Winbond W83697HF" superio
> Calibrating delay loop... OK.
> Found chip "SST SST39SF020A" (256 KB, Parallel) at physical address 0xfffc0000.
> No operations were specified.
SO with the above comment not there, we are already able to scrap 6 board enables!
Luc Verhaegen.
More information about the flashrom
mailing list