2 * This file is part of the superiotool project.
4 * Copyright (C) 2006 Ronald Minnich <rminnich@gmail.com>
5 * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
6 * Copyright (C) 2007 Carl-Daniel Hailfinger
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "superiotool.h"
25 /* Command line options. */
26 int dump = 0, dump_readable = 0, verbose = 0;
28 uint8_t regval(uint16_t port, uint8_t reg)
34 void regwrite(uint16_t port, uint8_t reg, uint8_t val)
40 void enter_conf_mode_winbond_fintek_ite_8787(uint16_t port)
46 void exit_conf_mode_winbond_fintek_ite_8787(uint16_t port)
48 outb(0xaa, port); /* Fintek, Winbond */
49 regwrite(port, 0x02, 0x02); /* ITE */
52 int superio_unknown(const struct superio_registers reg_table[], uint16_t id)
54 return !strncmp(get_superio_name(reg_table, id), "<unknown>", 9);
57 const char *get_superio_name(const struct superio_registers reg_table[],
62 for (i = 0; /* Nothing */; i++) {
63 if (reg_table[i].superio_id == EOT)
66 if ((uint16_t)reg_table[i].superio_id != id)
69 return reg_table[i].name;
75 static void dump_regs(const struct superio_registers reg_table[],
76 int i, int j, uint16_t port)
81 if (reg_table[i].ldn[j].ldn != NOLDN) {
82 printf("LDN 0x%02x ", reg_table[i].ldn[j].ldn);
83 if (reg_table[i].ldn[j].name != NULL)
84 printf("(%s)", reg_table[i].ldn[j].name);
85 regwrite(port, 0x07, reg_table[i].ldn[j].ldn);
87 printf("Register dump:");
90 idx = reg_table[i].ldn[j].idx;
93 for (k = 0; /* Nothing */; k++) {
96 printf("%02x ", idx[k]);
100 for (k = 0; /* Nothing */; k++) {
103 printf("%02x ", regval(port, idx[k]));
107 idx = reg_table[i].ldn[j].def;
108 for (k = 0; /* Nothing */; k++) {
111 else if (idx[k] == NANA)
113 else if (idx[k] == RSVD)
115 else if (idx[k] == MISC) /* TODO */
118 printf("%02x ", idx[k]);
123 void dump_superio(const char *vendor,
124 const struct superio_registers reg_table[],
125 uint16_t port, uint16_t id)
127 int i, j, no_dump_available = 1;
132 for (i = 0; /* Nothing */; i++) {
133 if (reg_table[i].superio_id == EOT)
136 if ((uint16_t)reg_table[i].superio_id != id)
139 for (j = 0; /* Nothing */; j++) {
140 if (reg_table[i].ldn[j].ldn == EOT)
142 no_dump_available = 0;
143 dump_regs(reg_table, i, j, port);
146 if (no_dump_available)
147 printf("No dump available for this Super I/O\n");
151 void dump_superio_readable(uint16_t port)
155 printf("No human-readable dump available for this Super I/O\n");
158 void no_superio_found(const char *vendor, const char *info, uint16_t port)
163 if (inb(port) == 0xff)
164 /* Yes, there's no space between '%s' and 'at'! */
165 printf("Probing for %s Super I/O %sat 0x%x... failed\n",
168 printf("Probing 0x%x, failed (0x%02x), data returns 0x%02x\n",
169 port, inb(port), inb(port + 1));
172 static void print_version(void)
176 strncpy((char *)&tmp,
177 (const char *)&SUPERIOTOOL_VERSION[6],
178 strlen(SUPERIOTOOL_VERSION) - 8);
179 printf("superiotool r%s\n", (char *)&tmp);
182 int main(int argc, char *argv[])
184 int i, j, opt, option_index;
186 const static struct option long_options[] = {
187 {"dump", no_argument, NULL, 'd'},
188 {"dump-readable", no_argument, NULL, 'D'},
189 {"verbose", no_argument, NULL, 'V'},
190 {"version", no_argument, NULL, 'v'},
191 {"help", no_argument, NULL, 'h'},
195 while ((opt = getopt_long(argc, argv, "dDVvh",
196 long_options, &option_index)) != EOF) {
205 /* Print version in --verbose mode. */
218 /* Unknown option. */
226 printf("Superiotool must be run as root.\n");
230 for (i = 0; i < ARRAY_SIZE(superio_ports_table); i++) {
231 for (j = 0; superio_ports_table[i].ports[j] != EOT; j++)
232 superio_ports_table[i].probe_idregs(
233 superio_ports_table[i].ports[j]);