[coreboot-gerrit] Patch set updated for coreboot: fe72b91 util/inteltool: Extend to read various bits on VIA systems
Alexandru Gagniuc (mr.nuke.me@gmail.com)
gerrit at coreboot.org
Mon Jun 3 19:47:35 CEST 2013
Alexandru Gagniuc (mr.nuke.me at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1430
-gerrit
commit fe72b9101299ba6ff28cf99ca61a7d1a84f7307e
Author: Alexandru Gagniuc <mr.nuke.me at gmail.com>
Date: Fri Aug 10 03:55:42 2012 -0500
util/inteltool: Extend to read various bits on VIA systems
Reading of configuration bits is implemented via a new featuere called
"quirks". Quirks are device configurations that cannot be accessed
directly. They are implemented as hierarchical configurations in the PCI
or memory address spaces (index/data register pairs). Such configurations
refer to hardware parameters that are board specific. Those parameters
would otherwise be difficult to extract from a system running the
vendor's firmware.
Change-Id: Icbd39eaf7c7da5568732d77dbf2aed135f835754
Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
---
util/inteltool/Makefile | 5 +-
util/inteltool/inteltool.c | 32 ++++++++--
util/inteltool/inteltool.h | 21 ++++++-
util/inteltool/quirks/quirks.c | 115 +++++++++++++++++++++++++++++++++++
util/inteltool/quirks/quirks.h | 37 +++++++++++
util/inteltool/quirks/vx900_quirks.c | 81 ++++++++++++++++++++++++
6 files changed, 282 insertions(+), 9 deletions(-)
diff --git a/util/inteltool/Makefile b/util/inteltool/Makefile
index 2028a4a..e0dfa23 100644
--- a/util/inteltool/Makefile
+++ b/util/inteltool/Makefile
@@ -24,10 +24,11 @@ PROGRAM = inteltool
CC ?= gcc
INSTALL ?= /usr/bin/install
PREFIX ?= /usr/local
-CFLAGS ?= -O2 -g -Wall -W
+CFLAGS ?= -O2 -g -Wall -W -I$(shell pwd)
LDFLAGS += -lpci -lz
-OBJS = inteltool.o cpu.o gpio.o rootcmplx.o powermgt.o memory.o pcie.o amb.o
+OBJS = inteltool.o cpu.o gpio.o rootcmplx.o powermgt.o memory.o pcie.o amb.o \
+ quirks/quirks.c quirks/vx900_quirks.c
OS_ARCH = $(shell uname)
ifeq ($(OS_ARCH), Darwin)
diff --git a/util/inteltool/inteltool.c b/util/inteltool/inteltool.c
index 0618f4b..3b6d02d 100644
--- a/util/inteltool/inteltool.c
+++ b/util/inteltool/inteltool.c
@@ -150,6 +150,13 @@ static const struct {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HM70, "HM70" },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_NM70, "NM70" },
{ PCI_VENDOR_ID_INTEL, 0x2310, "DH89xxCC" },
+ /*
+ * VIA chips go below this line
+ */
+ /* Host bridges/DRAM controllers (Northbridges) */
+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX900, "VX900"},
+ /* Southbridges (LPC controllers) */
+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX900_LPC, "VX900" },
};
#ifndef __DARWIN__
@@ -209,6 +216,7 @@ void print_usage(const char *name)
" -P | --pciexpress: dump northbridge PCIEXBAR registers\n\n"
" -M | --msrs: dump CPU MSRs\n"
" -A | --ambs: dump AMB registers\n"
+ " -q | --quirks: dump special configuration bits\n"
" -a | --all: dump all known registers\n"
"\n");
exit(1);
@@ -226,7 +234,7 @@ int main(int argc, char *argv[])
int dump_gpios = 0, dump_mchbar = 0, dump_rcba = 0;
int dump_pmbase = 0, dump_epbar = 0, dump_dmibar = 0;
int dump_pciexbar = 0, dump_coremsrs = 0, dump_ambs = 0;
- int show_gpio_diffs = 0;
+ int show_gpio_diffs = 0, dump_quirks = 0;
static struct option long_options[] = {
{"version", 0, 0, 'v'},
@@ -241,11 +249,12 @@ int main(int argc, char *argv[])
{"pciexpress", 0, 0, 'P'},
{"msrs", 0, 0, 'M'},
{"ambs", 0, 0, 'A'},
+ {"quirks", 0, 0, 'q'},
{"all", 0, 0, 'a'},
{0, 0, 0, 0}
};
- while ((opt = getopt_long(argc, argv, "vh?gGrpmedPMaA",
+ while ((opt = getopt_long(argc, argv, "vh?gGrpmedPMaAq",
long_options, &option_index)) != EOF) {
switch (opt) {
case 'v':
@@ -294,6 +303,9 @@ int main(int argc, char *argv[])
case 'A':
dump_ambs = 1;
break;
+ case 'q':
+ dump_quirks = 1;
+ break;
case 'h':
case '?':
default:
@@ -347,8 +359,9 @@ int main(int argc, char *argv[])
pci_fill_info(sb, PCI_FILL_IDENT|PCI_FILL_BASES|PCI_FILL_SIZES|PCI_FILL_CLASS);
- if (sb->vendor_id != PCI_VENDOR_ID_INTEL) {
- printf("Not an Intel(R) southbridge.\n");
+ if ((sb->vendor_id != PCI_VENDOR_ID_INTEL) &&
+ (sb->vendor_id != PCI_VENDOR_ID_VIA)) {
+ printf("Not a supported southbridge.\n");
exit(1);
}
@@ -360,8 +373,9 @@ int main(int argc, char *argv[])
pci_fill_info(nb, PCI_FILL_IDENT|PCI_FILL_BASES|PCI_FILL_SIZES|PCI_FILL_CLASS);
- if (nb->vendor_id != PCI_VENDOR_ID_INTEL) {
- printf("Not an Intel(R) northbridge.\n");
+ if ((nb->vendor_id != PCI_VENDOR_ID_INTEL) &&
+ (nb->vendor_id != PCI_VENDOR_ID_VIA)) {
+ printf("Not a supported northbridge.\n");
exit(1);
}
@@ -439,6 +453,12 @@ int main(int argc, char *argv[])
if (dump_ambs) {
print_ambs(nb, pacc);
}
+
+ if (dump_quirks) {
+ print_quirks_north(nb, pacc);
+ print_quirks_south(sb, pacc);
+ }
+
/* Clean up */
pci_free_dev(nb);
// pci_free_dev(sb); // TODO: glibc detected "double free or corruption"
diff --git a/util/inteltool/inteltool.h b/util/inteltool/inteltool.h
index 7872a5f..3108b7c 100644
--- a/util/inteltool/inteltool.h
+++ b/util/inteltool/inteltool.h
@@ -3,6 +3,7 @@
*
* Copyright (C) 2008-2010 by coresystems GmbH
* Copyright (C) 2009 Carl-Daniel Hailfinger
+ * Copyright (C) 2013 Alexandru Gagniuc
*
* 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
@@ -18,6 +19,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#ifndef _INTELTOOL_H
+#define _INTELTOOL_H
+
#include <stdint.h>
#if defined(__GLIBC__)
@@ -36,7 +40,10 @@
#endif
#define INTELTOOL_VERSION "1.0"
-
+\
+/*==============================================================================
+ * = Intel Section
+ *----------------------------------------------------------------------------*/
/* Tested chipsets: */
#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_DEVICE_ID_INTEL_ICH 0x2410
@@ -140,6 +147,14 @@
#define PCI_DEVICE_ID_INTEL_CORE_3RD_GEN 0x0154 /* Ivy Bridge */
#define PCI_DEVICE_ID_INTEL_CORE_4TH_GEN 0x0c04 /* Haswell */
+/*==============================================================================
+ *= VIA Section
+ *----------------------------------------------------------------------------*/
+#define PCI_VENDOR_ID_VIA 0x1106
+#define PCI_DEVICE_ID_VIA_VX900 0x0410
+#define PCI_DEVICE_ID_VIA_VX900_SATA 0x9001
+#define PCI_DEVICE_ID_VIA_VX900_LPC 0x8410
+
#define ARRAY_SIZE(a) ((int)(sizeof(a) / sizeof((a)[0])))
#if !defined(__DARWIN__) && !defined(__FreeBSD__)
@@ -170,3 +185,7 @@ int print_epbar(struct pci_dev *nb);
int print_dmibar(struct pci_dev *nb);
int print_pciexbar(struct pci_dev *nb);
int print_ambs(struct pci_dev *nb, struct pci_access *pacc);
+int print_quirks_north(struct pci_dev *nb, struct pci_access *pacc);
+int print_quirks_south(struct pci_dev *sb, struct pci_access *pacc);
+
+#endif /* _INTELTOOL_H */
diff --git a/util/inteltool/quirks/quirks.c b/util/inteltool/quirks/quirks.c
new file mode 100644
index 0000000..dc529c1
--- /dev/null
+++ b/util/inteltool/quirks/quirks.c
@@ -0,0 +1,115 @@
+/*
+ * viatool - dump all registers on a VIA CPU + chipset based system.
+ *
+ * Copyright (C) 2013 Alexandru Gagniuc
+ *
+ * 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
+ * a long with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "quirks.h"
+#include <inteltool.h>
+#include <stdio.h>
+#include <stddef.h>
+
+extern struct quirk_list vx900_sb_quirk_list;
+
+struct quirk_list *sb_quirks[] = {
+ &vx900_sb_quirk_list,
+ 0,
+};
+
+struct quirk_list *nb_quirks[] = {
+ 0,
+};
+
+int print_quirks(struct pci_dev *sb, struct pci_access *pacc,
+ struct quirk_list **qlists);
+
+int print_quirks_north(struct pci_dev *nb, struct pci_access *pacc)
+{
+ printf("\n====== Northbridge Quirks =======\n\n");
+ return print_quirks(nb, pacc, nb_quirks);
+}
+
+int print_quirks_south(struct pci_dev *sb, struct pci_access *pacc)
+{
+ printf("\n====== Southbridge Quirks =======\n\n");
+ return print_quirks(sb, pacc, sb_quirks);
+}
+
+int print_quirks(struct pci_dev *sb, struct pci_access *pacc,
+ struct quirk_list **qlists)
+{
+ size_t i, j;
+ struct quirk *q;
+ struct quirk_list *qlist;
+ struct pci_dev *dev;
+
+ for (i = 0;; i++) {
+ qlist = qlists[i];
+
+ if (qlist == NULL) {
+ /* OOPS. We've tried all we know, but no quirk */
+ printf("No quirks supported.\n");
+ break;
+ }
+
+ /* Is this the right device ? */
+ if ((qlist->pci_vendor_id != sb->vendor_id) ||
+ qlist->pci_device_id != sb->device_id)
+ continue;
+
+ for (j = 0;; j++) {
+ q = &qlist->dev_quirks[j];
+
+ if (q->pci_device_id == 0)
+ break;
+
+ printf("Probing PCI device %i:%.2x.%i\n",
+ q->pci_bus, q->pci_dev, q->pci_func);
+
+ dev = pci_get_dev(pacc, q->pci_domain, q->pci_bus,
+ q->pci_dev, q->pci_func);
+
+ if (!dev) {
+ perror("Error: no device found\n");
+ continue;
+ }
+
+ pci_fill_info(dev, PCI_FILL_IDENT |
+ PCI_FILL_BASES |
+ PCI_FILL_SIZES | PCI_FILL_CLASS);
+
+ if (dev->device_id != q->pci_device_id) {
+ printf("Expected %.4x:%.4x, got %.4x:%.4x\n",
+ q->pci_vendor_id, q->pci_device_id,
+ dev->vendor_id, dev->device_id);
+ continue;
+ }
+
+ if (!q->quirk_func) {
+ perror("BUG: Quirk missing.\n");
+ continue;
+ }
+
+ q->quirk_func(dev);
+ /* On to next quirk */
+ }
+
+ /* Done. No need to go through the remainder of the list */
+ break;
+ }
+
+ return 0;
+}
diff --git a/util/inteltool/quirks/quirks.h b/util/inteltool/quirks/quirks.h
new file mode 100644
index 0000000..d9b9bbd
--- /dev/null
+++ b/util/inteltool/quirks/quirks.h
@@ -0,0 +1,37 @@
+/*
+ * inteltool - dump all registers on a Intel or VIA CPU + chipset based system.
+ *
+ * Copyright (C) 2013 Alexandru Gagniuc
+ *
+ * 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
+ * a long with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <inteltool.h>
+
+struct quirk {
+ int pci_domain;
+ int pci_bus;
+ int pci_dev;
+ int pci_func;
+ int pci_vendor_id;
+ int pci_device_id;
+ int (*quirk_func) (struct pci_dev * dev);
+};
+
+struct quirk_list {
+ int pci_vendor_id;
+ int pci_device_id;
+ /* NULL-terminated list of quirks */
+ struct quirk *dev_quirks;
+};
diff --git a/util/inteltool/quirks/vx900_quirks.c b/util/inteltool/quirks/vx900_quirks.c
new file mode 100644
index 0000000..6e73886
--- /dev/null
+++ b/util/inteltool/quirks/vx900_quirks.c
@@ -0,0 +1,81 @@
+/*
+ * viatool - dump all registers on a VIA CPU + chipset based system.
+ *
+ * Copyright (C) 2013 Alexandru Gagniuc
+ *
+ * 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
+ * a long with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "quirks.h"
+
+#include <stdio.h>
+
+typedef u8 sata_phy_config[64];
+
+static u32 sata_phy_read32(struct pci_dev *dev, u8 index)
+{
+ /* The SATA PHY control registers are accessed by a funny index/value
+ * scheme. Each byte (0,1,2,3) has its own 4-bit index */
+ index = (index >> 2) & 0xf;
+ u16 i16 = index | (index << 4) | (index << 8) | (index << 12);
+ /* The index */
+ pci_write_word(dev, 0x68, i16);
+ /* The value */
+ return pci_read_long(dev, 0x64);
+}
+
+static void vx900_sata_read_phy_config(struct pci_dev *dev, sata_phy_config cfg)
+{
+ size_t i;
+ u32 *data = (u32 *) cfg;
+ for (i = 0; i < (sizeof(sata_phy_config)) >> 2; i++) {
+ data[i] = sata_phy_read32(dev, i << 2);
+ }
+}
+
+static int quirk_vx900_sata(struct pci_dev *dev)
+{
+ sata_phy_config ephy;
+
+ /* Get all the info in one pass */
+ vx900_sata_read_phy_config(dev, ephy);
+
+ /* Put it on the terminal for the user to read and be done with it */
+ printf("SATA PHY config:\n");
+ unsigned int i;
+ for (i = 0; i < sizeof(sata_phy_config); i++) {
+ if ((i & 0x0f) == 0) {
+ printf("%.2x :", i);
+ }
+ if ((i & 0x0f) == 0x08)
+ printf("| ");
+ printf("%.2x ", ephy[i]);
+ if ((i & 0x0f) == 0x0f) {
+ printf("\n");
+ }
+ }
+ return 0;
+}
+
+static struct quirk vx900_sb_quirks[] = {
+ {0, 0, 0x0f, 0, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX900_SATA,
+ quirk_vx900_sata},
+ {0, 0, 0, 0, 0, 0, 0},
+};
+
+struct quirk_list vx900_sb_quirk_list = {
+ .pci_vendor_id = PCI_VENDOR_ID_VIA,
+ .pci_device_id = PCI_DEVICE_ID_VIA_VX900_LPC,
+ .dev_quirks = vx900_sb_quirks
+};
More information about the coreboot-gerrit
mailing list