[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