svn commit: r214785 - in stable/7/sys: conf x86 x86/pci

John Baldwin jhb at FreeBSD.org
Thu Nov 4 17:07:13 UTC 2010


Author: jhb
Date: Thu Nov  4 17:07:13 2010
New Revision: 214785
URL: http://svn.freebsd.org/changeset/base/214785

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/7/sys/x86/
  stable/7/sys/x86/pci/
     - copied from r211820, head/sys/x86/pci/
Modified:
  stable/7/sys/conf/files.amd64
  stable/7/sys/conf/files.i386
  stable/7/sys/x86/pci/qpi.c
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/conf/files.amd64
==============================================================================
--- stable/7/sys/conf/files.amd64	Thu Nov  4 17:06:54 2010	(r214784)
+++ stable/7/sys/conf/files.amd64	Thu Nov  4 17:07:13 2010	(r214785)
@@ -277,3 +277,7 @@ i386/cpufreq/hwpstate.c		optional	cpufre
 i386/cpufreq/p4tcc.c		optional	cpufreq
 #
 libkern/memset.c		standard
+#
+# x86 shared code between IA32, AMD64 and PC98 architectures
+#
+x86/pci/qpi.c			standard

Modified: stable/7/sys/conf/files.i386
==============================================================================
--- stable/7/sys/conf/files.i386	Thu Nov  4 17:06:54 2010	(r214784)
+++ stable/7/sys/conf/files.i386	Thu Nov  4 17:07:13 2010	(r214785)
@@ -463,3 +463,7 @@ i386/xbox/xbox.c		optional	xbox
 i386/xbox/xboxfb.c		optional	xboxfb
 dev/fb/boot_font.c		optional	xboxfb
 i386/xbox/pic16l.s		optional	xbox
+#
+# x86 shared code between IA32, AMD64 and PC98 architectures
+#
+x86/pci/qpi.c			standard

Modified: stable/7/sys/x86/pci/qpi.c
==============================================================================
--- head/sys/x86/pci/qpi.c	Wed Aug 25 19:12:05 2010	(r211820)
+++ stable/7/sys/x86/pci/qpi.c	Thu Nov  4 17:07:13 2010	(r214785)
@@ -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));
 }


More information about the svn-src-stable-7 mailing list