aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUwe Hermann <uwe@hermann-uwe.de>2007-09-18 22:24:34 +0000
committerUwe Hermann <uwe@hermann-uwe.de>2007-09-18 22:24:34 +0000
commit6ff6af762158147b3c47bd1701a389622bd043a5 (patch)
tree9d10cba346a875bbfae17d2665c1d46d1cdb3132
parentd8a18a2adbe62aa0928515de1850f8e1722f69b9 (diff)
Superiotool: Add support for the SMSC FDC37N769.
Here's what a register dump looks like on my test system: No Super I/O chip found at 0x002e No Super I/O chip found at 0x004e No Super I/O chip found at 0x002e No Super I/O chip found at 0x004e No Super I/O chip found at 0x002e No Super I/O chip found at 0x004e Super I/O found at 0x03f0: id=0x28, rev=0x01 SMSC FDC37N769 idx 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f val 20 90 80 f4 00 00 ff 00 00 00 40 00 0e 28 01 00 00 00 00 00 02 00 01 03 00 00 00 00 00 00 80 00 00 00 00 00 00 ba 00 00 03 00 00 23 03 03 00 00 def 28 9c 88 70 00 00 ff 00 00 00 00 00 02 28 NA 00 00 80 RR RR NA NA NA 03 RR RR RR RR RR RR 80 00 3c RR RR 00 00 00 00 00 00 00 RR 00 00 03 00 00 Probing 0x0370, failed (0xff), data returns 0xff I'm self-acking this as it's pretty simple stuff, but please let me know if anything could be improved here, or if you think this is not trivial enough to warrant self-acking. Signed-off-by: Uwe Hermann <uwe@hermann-uwe.de> Acked-by: Uwe Hermann <uwe@hermann-uwe.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2781 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
-rw-r--r--util/superiotool/Makefile2
-rw-r--r--util/superiotool/smsc.c89
-rw-r--r--util/superiotool/superiotool.c24
-rw-r--r--util/superiotool/superiotool.h8
4 files changed, 111 insertions, 12 deletions
diff --git a/util/superiotool/Makefile b/util/superiotool/Makefile
index cf96d67c7a..c416f93a7e 100644
--- a/util/superiotool/Makefile
+++ b/util/superiotool/Makefile
@@ -28,7 +28,7 @@ PREFIX = /usr/local
CFLAGS = -O2 -Wall -Werror -Wstrict-prototypes -Wundef -Wstrict-aliasing \
-Werror-implicit-function-declaration
-OBJS = fintek.o ite.o nsc.o superiotool.o
+OBJS = superiotool.o fintek.o ite.o nsc.o smsc.o
all: $(PROGRAM)
diff --git a/util/superiotool/smsc.c b/util/superiotool/smsc.c
new file mode 100644
index 0000000000..805756f7cd
--- /dev/null
+++ b/util/superiotool/smsc.c
@@ -0,0 +1,89 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * 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
+ */
+
+#include "superiotool.h"
+
+#define DEVICE_ID_REG 0x0d
+#define DEVICE_REV_REG 0x0e
+
+const static struct superio_registers reg_table[] = {
+ {0x28, "FDC37N769", {
+ {NOLDN,
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
+ 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,
+ 0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,
+ 0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
+ 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,EOT},
+ {0x28,0x9c,0x88,0x70,0x00,0x00,0xff,0x00,0x00,0x00,
+ 0x00,0x00,0x02,0x28,NANA,0x00,0x00,0x80,RSVD,RSVD,
+ NANA,NANA,NANA,0x03,RSVD,RSVD,RSVD,RSVD,RSVD,RSVD,
+ 0x80,0x00,0x3c,RSVD,RSVD,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,RSVD,0x00,0x00,0x03,0x00,0x00,EOT}},
+ {EOT}}},
+ {EOT}
+};
+
+/* Note: The actual SMSC ID is 16 bits, but we must pass 32 bits here. */
+void dump_smsc(uint32_t port, uint32_t id)
+{
+ switch (id) {
+ case 0x28:
+ dump_superio("SMSC", reg_table, port, id);
+ break;
+ default:
+ printf("Unknown SMSC chip, id=0x%02x\n", id);
+ break;
+ }
+}
+
+void probe_idregs_smsc(uint32_t port)
+{
+ uint16_t id, rev;
+
+ outb(0x55, port); /* Enter configuration mode. */
+
+ /* Read device ID. */
+ id = regval(port, DEVICE_ID_REG);
+ if (id != 0x28) { /* TODO: Support for other SMSC chips. */
+ if (inb(port) != 0xff)
+ printf("No Super I/O chip found at 0x%04x\n", port);
+ else
+ printf("Probing 0x%04x, failed (0x%02x), data returns 0x%02x\n", port, inb(port), inb(port + 1));
+ return;
+ }
+
+ /* Read chip revision. */
+ rev = regval(port, DEVICE_REV_REG);
+
+ printf("Super I/O found at 0x%04x: id=0x%02x, rev=0x%02x\n",
+ port, id, rev);
+
+ switch (id) {
+ case 0x28:
+ dump_smsc(port, id);
+ break;
+ default:
+ printf("No dump for ID 0x%04x\n", id);
+ break;
+ }
+
+ outb(0xaa, port); /* Exit configuration mode. */
+}
+
diff --git a/util/superiotool/superiotool.c b/util/superiotool/superiotool.c
index ad3cd45c34..a5dcb2e753 100644
--- a/util/superiotool/superiotool.c
+++ b/util/superiotool/superiotool.c
@@ -83,8 +83,10 @@ void dump_superio(const char *name, const struct superio_registers reg_table[],
for (k = 0;; k++) {
if (idx[k] == EOT)
break;
- if (idx[k] == NANA)
+ else if (idx[k] == NANA)
printf("NA ");
+ else if (idx[k] == RSVD)
+ printf("RR ");
else
printf("%02x ", idx[k]);
}
@@ -93,13 +95,6 @@ void dump_superio(const char *name, const struct superio_registers reg_table[],
}
}
-void probe_superio(unsigned short port)
-{
- probe_idregs_simple(port);
- probe_idregs_fintek(port);
- probe_idregs_ite(port);
-}
-
int main(int argc, char *argv[])
{
if (iopl(3) < 0) {
@@ -107,8 +102,17 @@ int main(int argc, char *argv[])
exit(1);
}
- probe_superio(0x2e); /* Try 0x2e. */
- probe_superio(0x4e); /* Try 0x4e. */
+ probe_idregs_simple(0x2e);
+ probe_idregs_simple(0x4e);
+
+ probe_idregs_fintek(0x2e);
+ probe_idregs_fintek(0x4e);
+
+ probe_idregs_ite(0x2e);
+ probe_idregs_ite(0x4e);
+
+ probe_idregs_smsc(0x3f0);
+ probe_idregs_smsc(0x370);
return 0;
}
diff --git a/util/superiotool/superiotool.h b/util/superiotool/superiotool.h
index 904007cbdf..229c0d5982 100644
--- a/util/superiotool/superiotool.h
+++ b/util/superiotool/superiotool.h
@@ -24,11 +24,13 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include <sys/io.h>
#define EOT -1 /* End Of Table */
#define NOLDN -2 /* NO LDN needed */
#define NANA -3 /* Not Available */
+#define RSVD -4 /* Reserved */
#define MAXNAMELEN 20 /* Maximum Name Length */
#define MAXLDN 0xa /* Biggest LDN */
#define LDNSIZE (MAXLDN + 3) /* Biggest LDN + 0 + NOLDN + EOT */
@@ -39,7 +41,7 @@ struct superio_registers {
/* Yes, superio_id should be unsigned, but EOT has to be negative. */
signed short superio_id;
const char name[MAXNAMELEN];
- struct ite_ldnidx {
+ struct {
signed short ldn;
signed short idx[IDXSIZE];
signed short def[IDXSIZE];
@@ -65,4 +67,8 @@ void probe_idregs_ite(unsigned short port);
void dump_ns8374(unsigned short port);
void probe_idregs_simple(unsigned short port);
+/* smsc.c */
+void dump_smsc(uint32_t port, uint32_t id);
+void probe_idregs_smsc(uint32_t port);
+
#endif