[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