Refactor ITE SuperI/O detection/access. The new code reduces duplications and paves the way for generic SuperI/O detection. Additional cost: We enter/exit the SuperI/O configuration mode twice. Once for detecting which SuperI/O it is, and once for actually changing the settings. Additional benefit: This has the potential of allowing some sort of primitive laptop detection (by way of checking whether an EC or a simple SuperI/O is present).
I have added a call to a not yet implemented Winbond SuperI/O detection function inside #if 0 to make extension more straighforward.
This affects most SiS chipsets and IT87 SPI translation, so tests in verbose mode would be appreciated. In theory, functionality should be unchanged.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-superio_ite_refactor/flash.h =================================================================== --- flashrom-superio_ite_refactor/flash.h (Revision 761) +++ flashrom-superio_ite_refactor/flash.h (Arbeitskopie) @@ -388,6 +388,11 @@ #endif
/* internal.c */ +struct superio { + uint16_t vendor; + uint16_t port; + uint16_t model; +}; 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); @@ -395,6 +400,7 @@ uint16_t card_vendor, uint16_t card_device); void get_io_perms(void); void release_io_perms(void); +struct superio probe_superio(void); int internal_init(void); int internal_shutdown(void); void internal_chip_writeb(uint8_t val, chipaddr addr); @@ -611,9 +617,12 @@ int ich_spi_send_multicommand(struct spi_command *cmds);
/* it87spi.c */ +#define SUPERIO_VENDOR_NONE 0x0 +#define SUPERIO_VENDOR_ITE 0x1 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, Index: flashrom-superio_ite_refactor/it87spi.c =================================================================== --- flashrom-superio_ite_refactor/it87spi.c (Revision 761) +++ flashrom-superio_ite_refactor/it87spi.c (Arbeitskopie) @@ -54,19 +54,56 @@ sio_write(port, 0x02, 0x02); }
-static uint16_t find_ite_spi_flash_port(uint16_t port) +uint16_t probe_id_ite(uint16_t port) { - uint8_t tmp = 0; - char *portpos = NULL; - uint16_t id, flashport = 0; + 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);
- /* TODO: Handle more IT87xx if they support flash translation */ - if (0x8716 == id || 0x8718 == id) { + 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; + + i++; + 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: + printf_debug("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; printf("Serial flash segment 0x%08x-0x%08x %sabled\n", @@ -105,18 +142,26 @@ 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: + printf("SuperI/O ID %04hx is not on the controller list.\n", id); } - exit_conf_mode_ite(port); return flashport; }
int it87spi_common_init(void) { - it8716f_flashport = find_ite_spi_flash_port(ITE_SUPERIO_PORT1);
- if (!it8716f_flashport) - it8716f_flashport = find_ite_spi_flash_port(ITE_SUPERIO_PORT2); + struct superio superio;
+ superio = probe_superio_ite(); + if (superio.vendor == SUPERIO_VENDOR_NONE) + return 1; + + it8716f_flashport = find_ite_spi_flash_port(superio.port, superio.model); + if (it8716f_flashport) spi_controller = SPI_CONTROLLER_IT87XX;
Index: flashrom-superio_ite_refactor/chipset_enable.c =================================================================== --- flashrom-superio_ite_refactor/chipset_enable.c (Revision 761) +++ flashrom-superio_ite_refactor/chipset_enable.c (Arbeitskopie) @@ -225,37 +225,40 @@ return ret; }
-static int enable_flash_sis630(struct pci_dev *dev, const char *name) +static int enable_flash_decode_superio(void) { + int ret; uint8_t tmp; - uint16_t siobase; - int ret; + struct superio superio;
- ret = enable_flash_sis540(dev, name); - - /* The same thing on SiS 950 Super I/O side... */ - - /* First probe for Super I/O on config port 0x2e. */ - siobase = 0x2e; - enter_conf_mode_ite(siobase); - - if (INB(siobase + 1) != 0x87) { - /* If that failed, try config port 0x4e. */ - siobase = 0x4e; - enter_conf_mode_ite(siobase); - if (INB(siobase + 1) != 0x87) { - printf("Can not find SuperI/O.\n"); - return -1; - } + superio = probe_superio(); + 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; +}
- /* Enable flash mapping. Works for most old ITE style SuperI/O. */ - tmp = sio_read(siobase, 0x24); - tmp |= 0xfc; - sio_write(siobase, 0x24, tmp); +static int enable_flash_sis630(struct pci_dev *dev, const char *name) +{ + int ret;
- exit_conf_mode_ite(siobase); - + ret = enable_flash_sis540(dev, name); + ret |= enable_flash_decode_superio(); return ret; }
Index: flashrom-superio_ite_refactor/internal.c =================================================================== --- flashrom-superio_ite_refactor/internal.c (Revision 761) +++ flashrom-superio_ite_refactor/internal.c (Arbeitskopie) @@ -122,6 +122,18 @@ #endif }
+struct superio probe_superio(void) +{ + struct superio superio; + + 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 + return superio; +} + int internal_init(void) { int ret = 0;
Hi,
On Mon, Nov 16, 2009 at 2:16 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Refactor ITE SuperI/O detection/access. The new code reduces duplications and paves the way for generic SuperI/O detection. Additional cost: We enter/exit the SuperI/O configuration mode twice. Once for detecting which SuperI/O it is, and once for actually changing the settings. Additional benefit: This has the potential of allowing some sort of primitive laptop detection (by way of checking whether an EC or a simple SuperI/O is present).
I have added a call to a not yet implemented Winbond SuperI/O detection function inside #if 0 to make extension more straighforward.
This affects most SiS chipsets and IT87 SPI translation, so tests in verbose mode would be appreciated. In theory, functionality should be unchanged.
I'm attaching the output of "flashrom -V" on the AsRock K7S8X with r761 plus this patch.
Adrian
Hi,
On Mon, Nov 16, 2009 at 2:16 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Refactor ITE SuperI/O detection/access. The new code reduces duplications and paves the way for generic SuperI/O detection. Additional cost: We enter/exit the SuperI/O configuration mode twice. Once for detecting which SuperI/O it is, and once for actually changing the settings. Additional benefit: This has the potential of allowing some sort of primitive laptop detection (by way of checking whether an EC or a simple SuperI/O is present).
I have added a call to a not yet implemented Winbond SuperI/O detection function inside #if 0 to make extension more straighforward.
This affects most SiS chipsets and IT87 SPI translation, so tests in verbose mode would be appreciated. In theory, functionality should be unchanged.
Output of "flashrom -V" on Elitegroup K7S5A with r761 plus this patch.
Adrian
On Mon, Nov 16, 2009 at 2:16 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Refactor ITE SuperI/O detection/access. The new code reduces duplications and paves the way for generic SuperI/O detection. Additional cost: We enter/exit the SuperI/O configuration mode twice. Once for detecting which SuperI/O it is, and once for actually changing the settings. Additional benefit: This has the potential of allowing some sort of primitive laptop detection (by way of checking whether an EC or a simple SuperI/O is present).
I have added a call to a not yet implemented Winbond SuperI/O detection function inside #if 0 to make extension more straighforward.
This affects most SiS chipsets and IT87 SPI translation, so tests in verbose mode would be appreciated. In theory, functionality should be unchanged.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Adrian Glaubitz <glaubitz at physik.fu-berlin.de>
On Mon, Nov 16, 2009 at 02:16:08AM +0100, Carl-Daniel Hailfinger wrote:
Refactor ITE SuperI/O detection/access. The new code reduces duplications and paves the way for generic SuperI/O detection. Additional cost: We enter/exit the SuperI/O configuration mode twice. Once for detecting which SuperI/O it is, and once for actually changing the settings. Additional benefit: This has the potential of allowing some sort of primitive laptop detection (by way of checking whether an EC or a simple SuperI/O is present).
I have added a call to a not yet implemented Winbond SuperI/O detection function inside #if 0 to make extension more straighforward.
This affects most SiS chipsets and IT87 SPI translation, so tests in verbose mode would be appreciated. In theory, functionality should be unchanged.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
NACK :)
The code in the chipset enable needs to go :)
Apart from that, we need this, we need general superio detection, and the write enables moved out of board_enable.c, plus some gpio line setting code per superio.
For the IT8705, we need to work out what we want to do, there are two similar routines in board_enable.c, and this code below is the third.
We need a single one, and for the time being, it needs to be done depending on a board match.
Also, do we need the ite spi probe before we do flash detection?
So toss out the superio from the chipset enable (patch filed), and then alter the patch here to provide us with more general superio infrastructure :)
We need this.
Luc Verhaegen.
On 08.12.2009 11:52, Luc Verhaegen wrote:
On Mon, Nov 16, 2009 at 02:16:08AM +0100, Carl-Daniel Hailfinger wrote:
Refactor ITE SuperI/O detection/access. The new code reduces duplications and paves the way for generic SuperI/O detection. Additional cost: We enter/exit the SuperI/O configuration mode twice. Once for detecting which SuperI/O it is, and once for actually changing the settings. Additional benefit: This has the potential of allowing some sort of primitive laptop detection (by way of checking whether an EC or a simple SuperI/O is present).
I have added a call to a not yet implemented Winbond SuperI/O detection function inside #if 0 to make extension more straighforward.
This affects most SiS chipsets and IT87 SPI translation, so tests in verbose mode would be appreciated. In theory, functionality should be unchanged.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
NACK :)
Heh.
The code in the chipset enable needs to go :)
#if 0 for now and moved to board_enable.c. Can postpone/drop if you want.
Apart from that, we need this, we need general superio detection, and
Done.
the write enables moved out of board_enable.c,
Not so 100% sure about that. Newer boards may use these settings as GPIOs for other purposes.
plus some gpio line setting code per superio.
True. Separate patch, though.
For the IT8705, we need to work out what we want to do, there are two similar routines in board_enable.c, and this code below is the third.
We need a single one, and for the time being, it needs to be done depending on a board match.
Hmmm. I'd postpone that to a separate patch once we agree upon the architecture and implementation for this one.
Also, do we need the ite spi probe before we do flash detection?
Absolutely. It happens in the board enable code right now, but we can kill a boatload of them if we run the it86spi detection always (well, always in the case a matching superio is present). If we don't run IT87 SPI probe/setup before the first flash access, flashrom will NOT know that SPI is supported, and flashrom will therefore skip all SPI probing. That would effectively disable IT87 SPI completely.
So toss out the superio from the chipset enable (patch filed), and then alter the patch here to provide us with more general superio infrastructure :)
We need this.
Next try. I focused on the generic infrastructure aspect and will leave conversion of non-IT8712/IT8716 code to later patches. SuperI/O detection now happens unconditionally and before the chipset enable. We could run it after chipset enable, but it definitely has to happen before board enable. I don't have a preference either way. The board enable table should contain a struct superio for better matching, but I'll leave that to a separate patch once this is tested and committed.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-superio_ite_refactor/flash.h =================================================================== --- flashrom-superio_ite_refactor/flash.h (Revision 807) +++ flashrom-superio_ite_refactor/flash.h (Arbeitskopie) @@ -331,6 +331,14 @@
/* 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); @@ -340,6 +348,7 @@ 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); @@ -544,6 +553,7 @@ 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, Index: flashrom-superio_ite_refactor/it87spi.c =================================================================== --- flashrom-superio_ite_refactor/it87spi.c (Revision 807) +++ flashrom-superio_ite_refactor/it87spi.c (Arbeitskopie) @@ -54,19 +54,56 @@ sio_write(port, 0x02, 0x02); }
-static uint16_t find_ite_spi_flash_port(uint16_t port) +uint16_t probe_id_ite(uint16_t port) { - uint8_t tmp = 0; - char *portpos = NULL; - uint16_t id, flashport = 0; + 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);
- /* TODO: Handle more IT87xx if they support flash translation */ - if (0x8716 == id || 0x8718 == id) { + 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; + + i++; + 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: + printf_debug("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; printf("Serial flash segment 0x%08x-0x%08x %sabled\n", @@ -105,17 +142,21 @@ 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: + printf("SuperI/O ID %04hx is not on the controller list.\n", id); } - exit_conf_mode_ite(port); return flashport; }
int it87spi_common_init(void) { - it8716f_flashport = find_ite_spi_flash_port(ITE_SUPERIO_PORT1); + if (superio.vendor != SUPERIO_VENDOR_ITE) + return 1;
- if (!it8716f_flashport) - it8716f_flashport = find_ite_spi_flash_port(ITE_SUPERIO_PORT2); + it8716f_flashport = find_ite_spi_flash_port(superio.port, superio.model);
if (it8716f_flashport) spi_controller = SPI_CONTROLLER_IT87XX; @@ -129,6 +170,8 @@ 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; Index: flashrom-superio_ite_refactor/internal.c =================================================================== --- flashrom-superio_ite_refactor/internal.c (Revision 807) +++ flashrom-superio_ite_refactor/internal.c (Arbeitskopie) @@ -125,6 +125,17 @@ }
#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; @@ -142,6 +153,9 @@ */ 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. */ Index: flashrom-superio_ite_refactor/board_enable.c =================================================================== --- flashrom-superio_ite_refactor/board_enable.c (Revision 807) +++ flashrom-superio_ite_refactor/board_enable.c (Arbeitskopie) @@ -66,6 +66,35 @@ 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 + /** * Winbond W83627HF: Raise GPIO24. *
On Fri, Dec 18, 2009 at 05:12:19AM +0100, Carl-Daniel Hailfinger wrote:
On 08.12.2009 11:52, Luc Verhaegen wrote:
On Mon, Nov 16, 2009 at 02:16:08AM +0100, Carl-Daniel Hailfinger wrote:
Refactor ITE SuperI/O detection/access. The new code reduces duplications and paves the way for generic SuperI/O detection. Additional cost: We enter/exit the SuperI/O configuration mode twice. Once for detecting which SuperI/O it is, and once for actually changing the settings. Additional benefit: This has the potential of allowing some sort of primitive laptop detection (by way of checking whether an EC or a simple SuperI/O is present).
I have added a call to a not yet implemented Winbond SuperI/O detection function inside #if 0 to make extension more straighforward.
This affects most SiS chipsets and IT87 SPI translation, so tests in verbose mode would be appreciated. In theory, functionality should be unchanged.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
NACK :)
Heh.
The code in the chipset enable needs to go :)
#if 0 for now and moved to board_enable.c. Can postpone/drop if you want.
Apart from that, we need this, we need general superio detection, and
Done.
the write enables moved out of board_enable.c,
Not so 100% sure about that. Newer boards may use these settings as GPIOs for other purposes.
plus some gpio line setting code per superio.
True. Separate patch, though.
For the IT8705, we need to work out what we want to do, there are two similar routines in board_enable.c, and this code below is the third.
We need a single one, and for the time being, it needs to be done depending on a board match.
Hmmm. I'd postpone that to a separate patch once we agree upon the architecture and implementation for this one.
Also, do we need the ite spi probe before we do flash detection?
Absolutely. It happens in the board enable code right now, but we can kill a boatload of them if we run the it86spi detection always (well, always in the case a matching superio is present). If we don't run IT87 SPI probe/setup before the first flash access, flashrom will NOT know that SPI is supported, and flashrom will therefore skip all SPI probing. That would effectively disable IT87 SPI completely.
So toss out the superio from the chipset enable (patch filed), and then alter the patch here to provide us with more general superio infrastructure :)
We need this.
Next try. I focused on the generic infrastructure aspect and will leave conversion of non-IT8712/IT8716 code to later patches. SuperI/O detection now happens unconditionally and before the chipset enable. We could run it after chipset enable, but it definitely has to happen before board enable. I don't have a preference either way. The board enable table should contain a struct superio for better matching, but I'll leave that to a separate patch once this is tested and committed.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-superio_ite_refactor/flash.h
--- flashrom-superio_ite_refactor/flash.h (Revision 807) +++ flashrom-superio_ite_refactor/flash.h (Arbeitskopie) @@ -331,6 +331,14 @@
/* 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); @@ -340,6 +348,7 @@ 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); @@ -544,6 +553,7 @@ 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, Index: flashrom-superio_ite_refactor/it87spi.c =================================================================== --- flashrom-superio_ite_refactor/it87spi.c (Revision 807) +++ flashrom-superio_ite_refactor/it87spi.c (Arbeitskopie) @@ -54,19 +54,56 @@ sio_write(port, 0x02, 0x02); }
-static uint16_t find_ite_spi_flash_port(uint16_t port) +uint16_t probe_id_ite(uint16_t port) {
- uint8_t tmp = 0;
- char *portpos = NULL;
- uint16_t id, flashport = 0;
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);
- /* TODO: Handle more IT87xx if they support flash translation */
- if (0x8716 == id || 0x8718 == id) {
- 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;
- i++;
- 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:
printf_debug("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:
/* NOLDN, reg 0x24, mask out lowest bit (suspend) */ tmp = sio_read(port, 0x24) & 0xFE; printf("Serial flash segment 0x%08x-0x%08x %sabled\n",enter_conf_mode_ite(port);
@@ -105,17 +142,21 @@ 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:
}printf("SuperI/O ID %04hx is not on the controller list.\n", id);
- exit_conf_mode_ite(port); return flashport;
}
int it87spi_common_init(void) {
- it8716f_flashport = find_ite_spi_flash_port(ITE_SUPERIO_PORT1);
- if (superio.vendor != SUPERIO_VENDOR_ITE)
return 1;
- if (!it8716f_flashport)
it8716f_flashport = find_ite_spi_flash_port(ITE_SUPERIO_PORT2);
it8716f_flashport = find_ite_spi_flash_port(superio.port, superio.model);
if (it8716f_flashport) spi_controller = SPI_CONTROLLER_IT87XX;
@@ -129,6 +170,8 @@ 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;
Index: flashrom-superio_ite_refactor/internal.c
--- flashrom-superio_ite_refactor/internal.c (Revision 807) +++ flashrom-superio_ite_refactor/internal.c (Arbeitskopie) @@ -125,6 +125,17 @@ }
#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; @@ -142,6 +153,9 @@ */ 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.
Index: flashrom-superio_ite_refactor/board_enable.c
--- flashrom-superio_ite_refactor/board_enable.c (Revision 807) +++ flashrom-superio_ite_refactor/board_enable.c (Arbeitskopie) @@ -66,6 +66,35 @@ 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
/**
- Winbond W83627HF: Raise GPIO24.
-- Developer quote of the month: "We are juggling too many chainsaws and flaming arrows and tigers."
This stuff needs a lot of work on top, but as a first start:
Acked-by: Luc Verhaegen libv@skynet.be
Luc Verhaegen.
SuperI/O detection now happens unconditionally and before the chipset enable. We could run it after chipset enable, but it definitely has to happen before board enable because the board enable usually accesses the SuperI/O. With this patch, it is possible to add a struct superio to the board enable table for more accurate matching in case subsystem IDs are ambiguous. This patch focuses on the generic infrastructure aspect and on support for IT8712F/IT8716F.
Thanks go to Adrian Glaubitz and Ward Vandewege for testing earlier versions of this patch.
Ward, this one should actually work. Could you rerun "flashrom -V"?
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net Acked-by: Luc Verhaegen libv@skynet.be Acked-by: Adrian Glaubitz glaubitz@physik.fu-berlin.de
Index: flashrom-superio_ite_refactor/flash.h =================================================================== --- flashrom-superio_ite_refactor/flash.h (Revision 807) +++ flashrom-superio_ite_refactor/flash.h (Arbeitskopie) @@ -331,6 +331,14 @@
/* 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); @@ -340,6 +348,7 @@ 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); @@ -544,6 +553,7 @@ 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, Index: flashrom-superio_ite_refactor/it87spi.c =================================================================== --- flashrom-superio_ite_refactor/it87spi.c (Revision 807) +++ flashrom-superio_ite_refactor/it87spi.c (Arbeitskopie) @@ -54,19 +54,55 @@ sio_write(port, 0x02, 0x02); }
-static uint16_t find_ite_spi_flash_port(uint16_t port) +uint16_t probe_id_ite(uint16_t port) { - uint8_t tmp = 0; - char *portpos = NULL; - uint16_t id, flashport = 0; + 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);
- /* TODO: Handle more IT87xx if they support flash translation */ - if (0x8716 == id || 0x8718 == id) { + 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: + printf_debug("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; printf("Serial flash segment 0x%08x-0x%08x %sabled\n", @@ -105,17 +141,21 @@ 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: + printf("SuperI/O ID %04hx is not on the controller list.\n", id); } - exit_conf_mode_ite(port); return flashport; }
int it87spi_common_init(void) { - it8716f_flashport = find_ite_spi_flash_port(ITE_SUPERIO_PORT1); + if (superio.vendor != SUPERIO_VENDOR_ITE) + return 1;
- if (!it8716f_flashport) - it8716f_flashport = find_ite_spi_flash_port(ITE_SUPERIO_PORT2); + it8716f_flashport = find_ite_spi_flash_port(superio.port, superio.model);
if (it8716f_flashport) spi_controller = SPI_CONTROLLER_IT87XX; @@ -129,6 +169,8 @@ 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; Index: flashrom-superio_ite_refactor/internal.c =================================================================== --- flashrom-superio_ite_refactor/internal.c (Revision 807) +++ flashrom-superio_ite_refactor/internal.c (Arbeitskopie) @@ -125,6 +125,17 @@ }
#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; @@ -142,6 +153,9 @@ */ 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. */ Index: flashrom-superio_ite_refactor/board_enable.c =================================================================== --- flashrom-superio_ite_refactor/board_enable.c (Revision 807) +++ flashrom-superio_ite_refactor/board_enable.c (Arbeitskopie) @@ -66,6 +66,35 @@ 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 + /** * Winbond W83627HF: Raise GPIO24. *
On 19.12.2009 04:15, Carl-Daniel Hailfinger wrote:
SuperI/O detection now happens unconditionally and before the chipset enable. We could run it after chipset enable, but it definitely has to happen before board enable because the board enable usually accesses the SuperI/O. With this patch, it is possible to add a struct superio to the board enable table for more accurate matching in case subsystem IDs are ambiguous. This patch focuses on the generic infrastructure aspect and on support for IT8712F/IT8716F.
Thanks go to Adrian Glaubitz and Ward Vandewege for testing earlier versions of this patch.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net Acked-by: Luc Verhaegen libv@skynet.be Acked-by: Adrian Glaubitz glaubitz@physik.fu-berlin.de
Thanks to Ward Vandewege for testing on Gigabyte GA-M57SLI-S4 2.x with IT87 SPI translation. Log follows:
flashrom v0.9.1-r811 [...] Vendor ID: GIGABYTE, part ID: m57sli Found ITE SuperI/O, id 8716 Found chipset "NVIDIA MCP55", enabling flash write... OK. This chipset supports the following protocols: Non-SPI. Disabling flash write protection for board "GIGABYTE GA-M57SLI-S4"... Serial flash segment 0xfffe0000-0xffffffff enabled Serial flash segment 0x000e0000-0x000fffff enabled Serial flash segment 0xffee0000-0xffefffff disabled Serial flash segment 0xfff80000-0xfffeffff enabled LPC write to serial flash enabled Serial flash pin 29 Serial flash port 0x0820 OK. Calibrating delay loop... 728M loops per second, 100 myus = 0 us. OK. Probing for AMD Am29F010A/B, 128 KB: probe_29f040b: id1 0x7a, id2 0x67 [...] Probing for Atmel AT25DF021, 256 KB: RDID returned 0xc2 0x20 0x13. probe_spi_rdid_generic: id1 0xc2, id2 0x2013
Full log at http://coreboot.pastebin.ca/1723867
Committed in r813.
Regards, Carl-Daniel