[coreboot] [Patch] superiotool: add vt1211 support.

Luc Verhaegen libv at skynet.be
Thu Jul 9 16:14:20 CEST 2009


I spent a bit of time on adding support for the vt1211 superio found on 
the epia-m board. It does not add io dumping, yet.

Compared to the rest of the superiotool, this support is highly 
different; i see quite a lot of possibility for superiotool to be 
improved (more on that later in this mail).

This here is the output of superiotool on my vt1211:

VT1211 LDN 0: "Floppy Disk Controller"
    0x30: 0x01    (0x00)    "Activate"
    0x60: 0xFC    (0xFC)    "I/O Base Address"
    0x70: 0x06    (0x06)    "IRQ Select"
    0x74: 0x02    (0x01)    "DRQ Select"
    0xF0: 0x00    (0x00)    "Configuration"
    0xF1: 0x00    (0x00)    "Drive Select"

Notice how it lists one register per line, with:
 index: value (default).
The string is just there because it was easy to add while adding the 
other information.

Why do i prefer 1 register per line as opposed to whole blobs for other 
chipsets:
* we're human and this is easier to read.
* diff is also surprisingly human.

I would like to alter the printing of other superios to the same, one 
per line, output. I have been told on irc that this might break some 
peoples scripts (if there are any), but for humans, this is the sanest 
thing to do.

Further changes that might be good:
* decouple probing from dumping.
* add single value dumping and then also writing (requires tracking of 
RO/WO).
* there are only a few probe routines out there, create a general table
  so that we can tie io_port and the return value of the probe routine
  to an id and thus reduce probing to once per probe routine.
* etc, etc...

Tons of room for improvement and also discussion :)

But first, let's scrutinize this way of outputting and if acceptable, 
also alter the output of other superio dumps. I will be adding IT8103F 
support today, which will also further my view of what needs to be done 
here.

Luc Verhaegen.
-------------- next part --------------
Index: via.c
===================================================================
--- via.c	(revision 0)
+++ via.c	(revision 0)
@@ -0,0 +1,321 @@
+/*
+ * This file is part of the superiotool project.
+ *
+ * Copyright (C) 2009 Luc Verhaegen <libv at skynet.be>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/*
+ * Supports VIA VT1211.
+ */
+
+#include "superiotool.h"
+
+/*
+ * Low level operations.
+ */
+#define VT1211_REG_IDX  0x2E
+#define VT1211_REG_DATA 0x2F
+
+static void
+vt1211_confmode_enter(void)
+{
+	OUTB(0x87, VT1211_REG_IDX);
+	OUTB(0x87, VT1211_REG_IDX);
+}
+
+static void
+vt1211_confmode_leave(void)
+{
+	OUTB(0xAA, VT1211_REG_IDX);
+}
+
+static unsigned char
+vt1211_read(unsigned char index)
+{
+	OUTB(index, VT1211_REG_IDX);
+	return INB(VT1211_REG_DATA);
+}
+
+static void
+vt1211_write(unsigned char index, unsigned char data)
+{
+	OUTB(index, VT1211_REG_IDX);
+	OUTB(data, VT1211_REG_DATA);
+}
+
+static void
+vt1211_ldn_select(unsigned char ldn)
+{
+	vt1211_write(0x07, ldn);
+}
+
+/*
+ * now define our tables
+ */
+struct vt1211_register {
+	uint8_t index;
+	uint8_t def;
+	char *name;
+};
+
+/* Main registers */
+static struct vt1211_register
+vt1211_configuration_space[] = {
+	{0x07, 0x00, "Logical Device Number"}, /* no default */
+	{0x20, 0x3C, "Device ID"}, /* RO */
+	{0x21, 0x01, "Device Revision"}, /* RO */
+	{0x22, 0x00, "Power Down Control"},
+	{0x23, 0x11, "LPC Wait State Select"},
+	{0x24, 0x00, "GPIO Port 1 Pin Select"},
+	{0x25, 0x00, "GPIO Port 2 Pin Select"},
+	{0x26, 0x00, "GPIO Port 7 Pin Select"},
+	{0x27, 0x00, "UART2 Multi Function Pin Select"},
+	{0x28, 0x00, "MIDI Multi Function Pin Select"},
+	{0x29, 0x00, "HWM Multi Function Pin Select"},
+	{0x2E, 0x00, "Test Mode A (Do Not Program)"},
+	{0x2E, 0x00, "Test Mode B (Do Not Program)"},
+	{0, 0, NULL}
+};
+
+/* Floppy Disk Controller */
+static struct vt1211_register
+vt1211_ldn_0_registers[] = {
+	{0x30, 0x00, "Activate"},
+	{0x60, 0xFC, "I/O Base Address"},
+	{0x70, 0x06, "IRQ Select"},
+	{0x74, 0x01, "DRQ Select"},
+	{0xF0, 0x00, "Configuration"},
+	{0xF1, 0x00, "Drive Select"},
+	{0, 0, NULL}
+};
+
+/* Parallel Port */
+static struct vt1211_register
+vt1211_ldn_1_registers[] = {
+	{0x30, 0x03, "Activate"},
+	{0x60, 0xDE, "I/O Base Address"},
+	{0x70, 0x05, "IRQ Select"},
+	{0x74, 0x00, "DRQ Select"},
+	{0xF0, 0x00, "Control"},
+	{0, 0, NULL}
+};
+
+/* Serial Port 1 */
+static struct vt1211_register
+vt1211_ldn_2_registers[] = {
+	{0x30, 0x00, "Activate"},
+	{0x60, 0xFE, "I/O Base Address"},
+	{0x70, 0x04, "IRQ Select"},
+	{0xF0, 0x00, "Control"},
+	{0, 0, NULL}
+};
+
+/* Serial Port 2 */
+static struct vt1211_register
+vt1211_ldn_3_registers[] = {
+	{0x30, 0x00, "Activate"},
+	{0x60, 0xBE, "I/O Base Address"},
+	{0x70, 0x03, "IRQ Select"},
+	{0xF0, 0x00, "Control"},
+	{0, 0, NULL}
+};
+
+/* MIDI */
+static struct vt1211_register
+vt1211_ldn_6_registers[] = {
+	{0x30, 0x00, "Activate"},
+	{0x60, 0x03, "I/O Base Address (High)"},
+	{0x61, 0x30, "I/O Base Address (Low)"},
+	{0x70, 0x00, "IRQ Select"},
+	{0, 0, NULL}
+};
+
+/* Game Port */
+static struct vt1211_register
+vt1211_ldn_7_registers[] = {
+	{0x30, 0x00, "Activate"},
+	{0x60, 0x02, "I/O Base Address (High)"},
+	{0x61, 0x00, "I/O Base Address (Low)"},
+	{0, 0, NULL}
+};
+
+/* GPIO */
+static struct vt1211_register
+vt1211_ldn_8_registers[] = {
+	{0x30, 0x00, "Activate"},
+	{0x60, 0xE9, "I/O Base Address (High)"},
+	{0x61, 0x00, "I/O Base Address (Low)"},
+	{0x70, 0x00, "Event IRQ Select"},
+	{0xF0, 0x00, "Port Select"},
+	{0xF1, 0x00, "Pin Configuration"},
+	{0xF2, 0x00, "Pin Polarity Define"},
+	{0, 0, NULL}
+};
+
+/* Watchdog Timer */
+static struct vt1211_register vt1211_ldn_9_registers[] = {
+	{0x30, 0x00, "Activate"},
+	{0x60, 0xEA, "I/O Base Address (High)"},
+	{0x61, 0x00, "I/O Base Address (Low)"},
+	{0x70, 0x00, "IRQ Select"},
+	{0xF0, 0x00, "Configuration"},
+	{0, 0, NULL}
+};
+
+/* Wake-Up Controller */
+static struct vt1211_register
+vt1211_ldn_a_registers[] = {
+	{0x30, 0x00, "Activate"},
+	{0x60, 0xEB, "I/O Base Address (High)"},
+	{0x61, 0x00, "I/O Base Address (Low)"},
+	{0x70, 0x00, "IRQ Select"},
+	{0, 0, NULL}
+};
+
+/* Hardware Monitor */
+static struct vt1211_register
+vt1211_ldn_b_registers[] = {
+	{0x30, 0x00, "Activate"},
+	{0x60, 0xEC, "I/O Base Address (High)"},
+	{0x61, 0x00, "I/O Base Address (Low)"},
+	{0x70, 0x00, "IRQ Select"},
+	{0, 0, NULL}
+};
+
+/* Fast IR */
+static struct vt1211_register
+vt1211_ldn_c_registers[] = {
+	{0x30, 0x00, "Activate"},
+	{0x60, 0xE8, "I/O Base Address (High)"},
+	{0x61, 0x00, "I/O Base Address (Low)"},
+	{0x70, 0x00, "IRQ Select"},
+	{0x74, 0x06, "DRQ Select"},
+	{0xF0, 0x00, "DMA Selection"},
+	{0, 0, NULL}
+};
+
+/* ROM */
+static struct vt1211_register
+vt1211_ldn_d_registers[] = {
+	{0x30, 0x01, "Interface Activate"},
+	{0xF0, 0x00, "Decoding Control"},
+	{0, 0, NULL}
+};
+
+struct vt1211_ldn {
+	uint8_t ldn;
+	struct vt1211_register *registers;
+	char *name;
+};
+
+static struct vt1211_ldn vt1211_ldns[] = {
+	{0x00, vt1211_ldn_0_registers, "Floppy Disk Controller"},
+	{0x01, vt1211_ldn_1_registers, "Parallel Port"},
+	{0x02, vt1211_ldn_2_registers, "Serial Port 1"},
+	{0x03, vt1211_ldn_3_registers, "Serial Port 2"},
+	{0x06, vt1211_ldn_6_registers, "MIDI"},
+	{0x07, vt1211_ldn_7_registers, "Game Port"},
+	{0x08, vt1211_ldn_8_registers, "GPIO"},
+	{0x09, vt1211_ldn_9_registers, "Watchdog Timer"},
+	{0x0A, vt1211_ldn_a_registers, "Wake-Up Controller"},
+	{0x0B, vt1211_ldn_b_registers, "Hardware Monitor"},
+	{0x0C, vt1211_ldn_c_registers, "Fast IR"},
+	{0x0D, vt1211_ldn_d_registers, "ROM"},
+	{0, 0, NULL}
+};
+
+/**
+ *
+ */
+static void
+vt1211_dump_all(void)
+{
+	int i, j;
+
+	/* first, dump the main registers */
+	printf("\nVT1211 Configuration Space:\n");
+	vt1211_confmode_enter();
+	for (i = 0; vt1211_configuration_space[i].name; i++)
+		printf("    0x%02X: 0x%02X    (0x%02X)    \"%s\"\n",
+		       vt1211_configuration_space[i].index,
+		       vt1211_read(vt1211_configuration_space[i].index),
+		       vt1211_configuration_space[i].def,
+		       vt1211_configuration_space[i].name);
+	vt1211_confmode_leave();
+
+	/* now go through the logical devices. */
+	for (i = 0; vt1211_ldns[i].name; i++) {
+		printf("\nVT1211 LDN %1X: \"%s\"\n",
+		       vt1211_ldns[i].ldn, vt1211_ldns[i].name);
+		vt1211_confmode_enter();
+		vt1211_ldn_select(vt1211_ldns[i].ldn);
+
+		for (j = 0; vt1211_ldns[i].registers[j].name; j++)
+			printf("    0x%02X: 0x%02X    (0x%02X)    \"%s\"\n",
+			       vt1211_ldns[i].registers[j].index,
+			       vt1211_read(vt1211_ldns[i].registers[j].index),
+			       vt1211_ldns[i].registers[j].def,
+			       vt1211_ldns[i].registers[j].name);
+
+		vt1211_confmode_leave();
+	}
+}
+
+/**
+ *
+ */
+static int
+vt1211_probe(void)
+{
+	uint8_t id, rev;
+
+	vt1211_confmode_enter();
+	id = vt1211_read(0x20);
+	rev = vt1211_read(0x21);
+	vt1211_confmode_leave();
+
+	if (id != 0x3C)
+		return 0;
+
+	printf("Detected VIA VT1211 SuperIO (rev. %02X).\n", rev);
+	return 1;
+}
+
+/**
+ *
+ */
+void
+vt1211_idregs_probe(uint16_t port)
+{
+	if (!vt1211_probe())
+		return;
+
+	chip_found = 1;
+
+	vt1211_dump_all();
+}
+
+/**
+ *
+ */
+void
+vt1211_chips_print(void)
+{
+	printf("VIA VT1211 (dump available)\n");
+}
Index: superiotool.h
===================================================================
--- superiotool.h	(revision 4407)
+++ superiotool.h	(working copy)
@@ -132,6 +132,10 @@
 void probe_idregs_smsc(uint16_t port);
 void print_smsc_chips(void);
 
+/* via.c */
+void vt1211_idregs_probe(uint16_t port);
+void vt1211_chips_print(void);
+
 /* winbond.c */
 void probe_idregs_winbond(uint16_t port);
 void print_winbond_chips(void);
@@ -147,6 +151,7 @@
 	{probe_idregs_ite,	{0x2e, 0x4e, 0x370, EOT}},
 	{probe_idregs_nsc,	{0x2e, 0x4e, 0x15c, EOT}},
 	{probe_idregs_smsc,	{0x2e, 0x4e, 0x162e, 0x164e, 0x3f0, 0x370, EOT}},
+	{vt1211_idregs_probe,   {0x2e, EOT}},
 	{probe_idregs_winbond,	{0x2e, 0x4e, 0x3f0, 0x370, 0x250, EOT}},
 };
 
@@ -159,6 +164,7 @@
 	{print_ite_chips},
 	{print_nsc_chips},
 	{print_smsc_chips},
+	{vt1211_chips_print},
 	{print_winbond_chips},
 };
 
Index: Makefile
===================================================================
--- Makefile	(revision 4407)
+++ Makefile	(working copy)
@@ -32,7 +32,7 @@
 CFLAGS = -O2 -Wall -Werror -Wstrict-prototypes -Wundef -Wstrict-aliasing \
          -Werror-implicit-function-declaration -ansi -pedantic $(SVNDEF)
 
-OBJS = superiotool.o ali.o fintek.o ite.o nsc.o smsc.o winbond.o
+OBJS = superiotool.o ali.o fintek.o ite.o nsc.o smsc.o via.o winbond.o
 
 all: $(PROGRAM)
 
-------------- next part --------------
superiotool r4375
Detected VIA VT1211 SuperIO (rev. 02).

VT1211 Configuration Space:
    0x07: 0x0D    (0x00)    "Logical Device Number"
    0x20: 0x3C    (0x3C)    "Device ID"
    0x21: 0x02    (0x01)    "Device Revision"
    0x22: 0x00    (0x00)    "Power Down Control"
    0x23: 0x11    (0x11)    "LPC Wait State Select"
    0x24: 0x00    (0x00)    "GPIO Port 1 Pin Select"
    0x25: 0x00    (0x00)    "GPIO Port 2 Pin Select"
    0x26: 0x00    (0x00)    "GPIO Port 7 Pin Select"
    0x27: 0x00    (0x00)    "UART2 Multi Function Pin Select"
    0x28: 0x00    (0x00)    "MIDI Multi Function Pin Select"
    0x29: 0x01    (0x00)    "HWM Multi Function Pin Select"
    0x2E: 0x00    (0x00)    "Test Mode A (Do Not Program)"
    0x2E: 0x00    (0x00)    "Test Mode B (Do Not Program)"

VT1211 LDN 0: "Floppy Disk Controller"
    0x30: 0x01    (0x00)    "Activate"
    0x60: 0xFC    (0xFC)    "I/O Base Address"
    0x70: 0x06    (0x06)    "IRQ Select"
    0x74: 0x02    (0x01)    "DRQ Select"
    0xF0: 0x00    (0x00)    "Configuration"
    0xF1: 0x00    (0x00)    "Drive Select"

VT1211 LDN 1: "Parallel Port"
    0x30: 0x00    (0x03)    "Activate"
    0x60: 0xDE    (0xDE)    "I/O Base Address"
    0x70: 0x07    (0x05)    "IRQ Select"
    0x74: 0x00    (0x00)    "DRQ Select"
    0xF0: 0x80    (0x00)    "Control"

VT1211 LDN 2: "Serial Port 1"
    0x30: 0x01    (0x00)    "Activate"
    0x60: 0xFE    (0xFE)    "I/O Base Address"
    0x70: 0x04    (0x04)    "IRQ Select"
    0xF0: 0x00    (0x00)    "Control"

VT1211 LDN 3: "Serial Port 2"
    0x30: 0x01    (0x00)    "Activate"
    0x60: 0xBE    (0xBE)    "I/O Base Address"
    0x70: 0x03    (0x03)    "IRQ Select"
    0xF0: 0x00    (0x00)    "Control"

VT1211 LDN 6: "MIDI"
    0x30: 0x00    (0x00)    "Activate"
    0x60: 0x03    (0x03)    "I/O Base Address (High)"
    0x61: 0x30    (0x30)    "I/O Base Address (Low)"
    0x70: 0x00    (0x00)    "IRQ Select"

VT1211 LDN 7: "Game Port"
    0x30: 0x01    (0x00)    "Activate"
    0x60: 0x00    (0x02)    "I/O Base Address (High)"
    0x61: 0x00    (0x00)    "I/O Base Address (Low)"

VT1211 LDN 8: "GPIO"
    0x30: 0x00    (0x00)    "Activate"
    0x60: 0xE9    (0xE9)    "I/O Base Address (High)"
    0x61: 0x00    (0x00)    "I/O Base Address (Low)"
    0x70: 0x00    (0x00)    "Event IRQ Select"
    0xF0: 0x00    (0x00)    "Port Select"
    0xF1: 0x00    (0x00)    "Pin Configuration"
    0xF2: 0x00    (0x00)    "Pin Polarity Define"

VT1211 LDN 9: "Watchdog Timer"
    0x30: 0x00    (0x00)    "Activate"
    0x60: 0xEA    (0xEA)    "I/O Base Address (High)"
    0x61: 0x00    (0x00)    "I/O Base Address (Low)"
    0x70: 0x00    (0x00)    "IRQ Select"
    0xF0: 0x02    (0x00)    "Configuration"

VT1211 LDN A: "Wake-Up Controller"
    0x30: 0x00    (0x00)    "Activate"
    0x60: 0xEB    (0xEB)    "I/O Base Address (High)"
    0x61: 0x00    (0x00)    "I/O Base Address (Low)"
    0x70: 0x00    (0x00)    "IRQ Select"

VT1211 LDN B: "Hardware Monitor"
    0x30: 0x01    (0x00)    "Activate"
    0x60: 0x60    (0xEC)    "I/O Base Address (High)"
    0x61: 0x00    (0x00)    "I/O Base Address (Low)"
    0x70: 0x02    (0x00)    "IRQ Select"

VT1211 LDN C: "Fast IR"
    0x30: 0x00    (0x00)    "Activate"
    0x60: 0x00    (0xE8)    "I/O Base Address (High)"
    0x61: 0x00    (0x00)    "I/O Base Address (Low)"
    0x70: 0x00    (0x00)    "IRQ Select"
    0x74: 0x09    (0x06)    "DRQ Select"
    0xF0: 0x00    (0x00)    "DMA Selection"

VT1211 LDN D: "ROM"
    0x30: 0x01    (0x01)    "Interface Activate"
    0xF0: 0x00    (0x00)    "Decoding Control"


More information about the coreboot mailing list