Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Nov 2010 17:06:55 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r214784 - in stable/8/sys: conf x86 x86/pci
Message-ID:  <201011041706.oA4H6t1d066331@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Thu Nov  4 17:06:54 2010
New Revision: 214784
URL: http://svn.freebsd.org/changeset/base/214784

Log:
  MFC 211820,211821,212292:
  Intel QPI chipsets actually provide extra "non-core" PCI buses that
  provide PCI devices for various hardware such as memory controllers,
  etc.  for each socket.  These PCI buses are not enumerated via ACPI
  however.  Add qpi(4) psuedo bus and Host-PCI bridge drivers to
  enumerate these buses.  Currently the driver uses the CPU ID to
  determine the bridges' presence.

Added:
  stable/8/sys/x86/
  stable/8/sys/x86/pci/
     - copied from r211820, head/sys/x86/pci/
Modified:
  stable/8/sys/conf/files.amd64
  stable/8/sys/conf/files.i386
  stable/8/sys/x86/pci/qpi.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/conf/files.amd64
==============================================================================
--- stable/8/sys/conf/files.amd64	Thu Nov  4 17:01:21 2010	(r214783)
+++ stable/8/sys/conf/files.amd64	Thu Nov  4 17:06:54 2010	(r214784)
@@ -313,3 +313,7 @@ libkern/memset.c		standard
 #
 compat/x86bios/x86bios.c	optional x86bios | atkbd | dpms | vesa
 contrib/x86emu/x86emu.c		optional x86bios | atkbd | dpms | vesa
+#
+# x86 shared code between IA32, AMD64 and PC98 architectures
+#
+x86/pci/qpi.c			standard

Modified: stable/8/sys/conf/files.i386
==============================================================================
--- stable/8/sys/conf/files.i386	Thu Nov  4 17:01:21 2010	(r214783)
+++ stable/8/sys/conf/files.i386	Thu Nov  4 17:06:54 2010	(r214784)
@@ -388,3 +388,7 @@ i386/xbox/pic16l.s		optional xbox
 #
 compat/x86bios/x86bios.c	optional x86bios | atkbd | dpms | vesa
 contrib/x86emu/x86emu.c		optional x86bios | atkbd | dpms | vesa
+#
+# x86 shared code between IA32, AMD64 and PC98 architectures
+#
+x86/pci/qpi.c			standard

Modified: stable/8/sys/x86/pci/qpi.c
==============================================================================
--- head/sys/x86/pci/qpi.c	Wed Aug 25 19:12:05 2010	(r211820)
+++ stable/8/sys/x86/pci/qpi.c	Thu Nov  4 17:06:54 2010	(r214784)
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/pci_cfgreg.h>
 #include <machine/specialreg.h>
 
+#include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
 #include <dev/pci/pcib_private.h>
 #include "pcib_if.h"
@@ -62,7 +63,8 @@ qpi_identify(driver_t *driver, device_t 
 {
 
         /* Check CPUID to ensure this is an i7 CPU of some sort. */
-        if (!(cpu_vendor_id == CPU_VENDOR_INTEL && CPUID_TO_FAMILY(cpu_id) &&
+        if (!(cpu_vendor_id == CPU_VENDOR_INTEL &&
+	    CPUID_TO_FAMILY(cpu_id) == 0x6 &&
 	    (CPUID_TO_MODEL(cpu_id) == 0x1a || CPUID_TO_MODEL(cpu_id) == 0x2c)))
                 return;
 
@@ -83,31 +85,62 @@ qpi_probe(device_t dev)
 	return (BUS_PROBE_SPECIFIC);
 }
 
+/*
+ * Look for a PCI bus with the specified bus address.  If one is found,
+ * add a pcib device and return 0.  Otherwise, return an error code.
+ */
 static int
-qpi_attach(device_t dev)
+qpi_probe_pcib(device_t dev, int bus)
 {
 	struct qpi_device *qdev;
 	device_t child;
+	uint32_t devid;
 
 	/*
-	 * Add two Host-PCI bridge devices, one for PCI bus 254 and
-	 * one for PCI bus 255.
+	 * If a PCI bus already exists for this bus number, then
+	 * fail.
 	 */
-	child = BUS_ADD_CHILD(dev, 0, "pcib", -1);
-	if (child == NULL)
-		panic("%s: failed to add pci bus 254",
-		    device_get_nameunit(dev));
-	qdev = malloc(sizeof(struct qpi_device), M_QPI, M_WAITOK);
-	qdev->qd_pcibus = 254;
-	device_set_ivars(child, qdev);
+	if (pci_find_bsf(bus, 0, 0) != NULL)
+		return (EEXIST);
+
+	/*
+	 * Attempt to read the device id for device 0, function 0 on
+	 * the bus.  A value of 0xffffffff means that the bus is not
+	 * present.
+	 */
+	devid = pci_cfgregread(bus, 0, 0, PCIR_DEVVENDOR, 4);
+	if (devid == 0xffffffff)
+		return (ENOENT);
+
+	if ((devid & 0xffff) != 0x8086) {
+		device_printf(dev,
+		    "Device at pci%d.0.0 has non-Intel vendor 0x%x\n", bus,
+		    devid & 0xffff);
+		return (ENXIO);
+	}
 
 	child = BUS_ADD_CHILD(dev, 0, "pcib", -1);
 	if (child == NULL)
-		panic("%s: failed to add pci bus 255",
-		    device_get_nameunit(dev));
+		panic("%s: failed to add pci bus %d", device_get_nameunit(dev),
+		    bus);
 	qdev = malloc(sizeof(struct qpi_device), M_QPI, M_WAITOK);
-	qdev->qd_pcibus = 255;
+	qdev->qd_pcibus = bus;
 	device_set_ivars(child, qdev);
+	return (0);
+}
+
+static int
+qpi_attach(device_t dev)
+{
+	int bus;
+
+	/*
+	 * Each processor socket has a dedicated PCI bus counting down from
+	 * 255.  We keep probing buses until one fails.
+	 */
+	for (bus = 255;; bus--)
+		if (qpi_probe_pcib(dev, bus) != 0)
+			break;
 
 	return (bus_generic_attach(dev));
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011041706.oA4H6t1d066331>