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 + * + * 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)