Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-2-0]: src/sys/arch/x86/x86 Pullup rev 1.20-1.29 (requested by koc...
details: https://anonhg.NetBSD.org/src/rev/18a735ddb406
branches: netbsd-2-0
changeset: 561249:18a735ddb406
user: jmc <jmc%NetBSD.org@localhost>
date: Tue Jun 01 04:30:44 2004 +0000
description:
Pullup rev 1.20-1.29 (requested by kochi in ticket #427)
Lots of fixes to prevents panic's on HT motherboards
diffstat:
sys/arch/x86/x86/mpacpi.c | 450 +++++++++++++++++++++++++++------------------
1 files changed, 272 insertions(+), 178 deletions(-)
diffs (truncated from 707 to 300 lines):
diff -r 586ba7f3e431 -r 18a735ddb406 sys/arch/x86/x86/mpacpi.c
--- a/sys/arch/x86/x86/mpacpi.c Tue Jun 01 04:30:40 2004 +0000
+++ b/sys/arch/x86/x86/mpacpi.c Tue Jun 01 04:30:44 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mpacpi.c,v 1.19 2004/03/24 09:15:38 martin Exp $ */
+/* $NetBSD: mpacpi.c,v 1.19.2.1 2004/06/01 04:30:44 jmc Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mpacpi.c,v 1.19 2004/03/24 09:15:38 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mpacpi.c,v 1.19.2.1 2004/06/01 04:30:44 jmc Exp $");
#include "opt_acpi.h"
#include "opt_mpbios.h"
@@ -62,50 +62,52 @@
#include <machine/i82489var.h>
#include <dev/isa/isareg.h>
#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
#include <dev/pci/ppbreg.h>
-
+#include <dev/acpi/acpica.h>
+#include <dev/acpi/acpireg.h>
#include <dev/acpi/acpivar.h>
#include <dev/acpi/acpi_madt.h>
#include "pci.h"
+#ifdef ACPI_DEBUG_OUTPUT
+#define _COMPONENT ACPI_HARDWARE
+#define _THIS_MODULE "mpacpi"
+#endif
+
+/* XXX room for PCI-to-PCI bus */
+#define BUS_BUFFER (16)
+
#if NPCI > 0
struct mpacpi_pcibus {
TAILQ_ENTRY(mpacpi_pcibus) mpr_list;
- ACPI_HANDLE *mpr_handle; /* Same thing really, but.. */
- int mpr_bus;
- int mpr_level;
+ ACPI_HANDLE mpr_handle; /* Same thing really, but.. */
+ ACPI_BUFFER mpr_buf; /* preserve _PRT */
+ int mpr_bus; /* PCI bus number */
};
-struct mpacpi_walk_status {
- struct mpacpi_pcibus *mpw_mpr;
- struct acpi_softc *mpw_acpi;
-};
-
-TAILQ_HEAD(, mpacpi_pcibus) mpacpi_pcibusses;
+static TAILQ_HEAD(, mpacpi_pcibus) mpacpi_pcibusses;
#endif
-int mpacpi_print(void *, const char *);
-int mpacpi_match(struct device *, struct cfdata *, void *);
+static int mpacpi_print(void *, const char *);
+static int mpacpi_match(struct device *, struct cfdata *, void *);
-/*
- * acpi_madt_walk callbacks
- */
+/* acpi_madt_walk callbacks */
static ACPI_STATUS mpacpi_count(APIC_HEADER *, void *);
static ACPI_STATUS mpacpi_config_cpu(APIC_HEADER *, void *);
static ACPI_STATUS mpacpi_config_ioapic(APIC_HEADER *, void *);
static ACPI_STATUS mpacpi_nonpci_intr(APIC_HEADER *, void *);
#if NPCI > 0
-/*
- * Callbacks for the device namespace walk.
- */
+/* Callbacks for the ACPI namespace walk */
static ACPI_STATUS mpacpi_pcibus_cb(ACPI_HANDLE, UINT32, void *, void **);
+static int mpacpi_derive_bus(ACPI_HANDLE, struct acpi_softc *);
+
static int mpacpi_pcircount(struct mpacpi_pcibus *);
static int mpacpi_pciroute(struct mpacpi_pcibus *);
-static ACPI_STATUS mpacpi_pcihier_cb(ACPI_HANDLE, UINT32, void *, void **);
static int mpacpi_find_pcibusses(struct acpi_softc *);
static void mpacpi_print_pci_intr(int);
@@ -116,22 +118,20 @@
static void mpacpi_print_intr(struct mp_intr_map *);
static void mpacpi_print_isa_intr(int);
-int mpacpi_nioapic;
-int mpacpi_ncpu;
-int mpacpi_nintsrc;
+int mpacpi_nioapic; /* number of ioapics */
+int mpacpi_ncpu; /* number of cpus */
+int mpacpi_nintsrc; /* number of non-device interrupts */
#if NPCI > 0
-int mpacpi_npci;
-int mpacpi_maxpci;
-static int mpacpi_maxbuslevel;
+static int mpacpi_npci;
+static int mpacpi_maxpci;
static int mpacpi_npciroots;
-static int mpacpi_npciknown;
#endif
static int mpacpi_intr_index;
static paddr_t mpacpi_lapic_base = LAPIC_BASE;
-int
+static int
mpacpi_print(void *aux, const char *pnp)
{
struct cpu_attach_args * caa = (struct cpu_attach_args *) aux;
@@ -140,7 +140,7 @@
return (UNCONF);
}
-int
+static int
mpacpi_match(struct device *parent, struct cfdata *cf, void *aux)
{
struct cpu_attach_args * caa = (struct cpu_attach_args *) aux;
@@ -183,7 +183,7 @@
ioapic->sc_pins[pin].ip_map = mpi;
mpi->ioapic_ih = APIC_INT_VIA_APIC |
(ioapic->sc_apicid << APIC_INT_APIC_SHIFT) |
- (pin << APIC_INT_PIN_SHIFT);
+ (pin << APIC_INT_PIN_SHIFT);
mpi->flags = ioapic_nmi->Polarity |
(ioapic_nmi->TriggerMode << 2);
mpi->global_int = ioapic_nmi->Interrupt;
@@ -298,7 +298,6 @@
caa.cpu_func = &mp_cpu_funcs;
config_found_sm(parent, &caa, mpacpi_print,
mpacpi_match);
-
}
}
return AE_OK;
@@ -360,6 +359,17 @@
#if NPCI > 0
+/*
+ * Find all PCI busses from ACPI namespace and construct mpacpi_pcibusses list.
+ *
+ * Note:
+ * We cannot find all PCI busses in the system from ACPI namespace.
+ * For example, a PCI-to-PCI bridge on an add-on PCI card is not
+ * described in the ACPI namespace.
+ * We search valid devices which have _PRT (PCI interrupt routing table)
+ * method.
+ * Such devices are either one of PCI root bridge or PCI-to-PCI bridge.
+ */
static int
mpacpi_find_pcibusses(struct acpi_softc *acpi)
{
@@ -373,107 +383,213 @@
return 0;
}
+static const char * const pciroot_hid[] = {
+ "PNP0A03", /* PCI root bridge */
+ NULL
+};
+
+/*
+ * mpacpi_derive_bus:
+ *
+ * Derive PCI bus number for the ACPI handle.
+ *
+ * If a device is not a PCI root bridge, it doesn't have _BBN method
+ * and we have no direct method to know the bus number.
+ * We have to walk up to search its root bridge and then walk down
+ * to resolve the bus number.
+ */
+static int
+mpacpi_derive_bus(ACPI_HANDLE handle, struct acpi_softc *acpi)
+{
+ ACPI_HANDLE parent, current;
+ ACPI_STATUS rv;
+ ACPI_INTEGER val;
+ ACPI_DEVICE_INFO *devinfo;
+ ACPI_BUFFER buf;
+ struct ac_dev {
+ TAILQ_ENTRY(ac_dev) list;
+ ACPI_HANDLE handle;
+ };
+ TAILQ_HEAD(, ac_dev) dev_list;
+ struct ac_dev *dev;
+ pcireg_t binf, class, dvid;
+ pcitag_t tag;
+ int bus;
+
+ bus = -1;
+ TAILQ_INIT(&dev_list);
+
+ /* first, search parent root bus */
+ for (current = handle;; current = parent) {
+ dev = malloc(sizeof(struct ac_dev), M_TEMP, M_WAITOK|M_ZERO);
+ if (dev == NULL)
+ return -1;
+ dev->handle = current;
+ TAILQ_INSERT_HEAD(&dev_list, dev, list);
+
+ rv = AcpiGetParent(current, &parent);
+ if (ACPI_FAILURE(rv))
+ return -1;
+
+ buf.Pointer = NULL;
+ buf.Length = ACPI_ALLOCATE_BUFFER;
+ rv = AcpiGetObjectInfo(parent, &buf);
+ if (ACPI_FAILURE(rv))
+ return -1;
+
+ devinfo = buf.Pointer;
+ if (acpi_match_hid(devinfo, pciroot_hid)) {
+ rv = acpi_eval_integer(current, METHOD_NAME__BBN, &val);
+ AcpiOsFree(buf.Pointer);
+ if (ACPI_SUCCESS(rv))
+ bus = ACPI_LOWORD(val);
+ else
+ /* assume bus = 0 */
+ bus = 0;
+ break;
+ }
+
+ AcpiOsFree(buf.Pointer);
+ }
+
+ /*
+ * second, we walk down from the root to the target
+ * resolving the bus number
+ */
+ TAILQ_FOREACH(dev, &dev_list, list) {
+ rv = acpi_eval_integer(dev->handle, METHOD_NAME__ADR, &val);
+ if (ACPI_FAILURE(rv))
+ return -1;
+
+ tag = pci_make_tag(acpi->sc_pc, bus,
+ ACPI_HIWORD(val), ACPI_LOWORD(val));
+
+ /* check if this device exists */
+ dvid = pci_conf_read(acpi->sc_pc, tag, PCI_ID_REG);
+ if (PCI_VENDOR(dvid) == PCI_VENDOR_INVALID ||
+ PCI_VENDOR(dvid) == 0)
+ return -1;
+
+ /* check if this is a bridge device */
+ class = pci_conf_read(acpi->sc_pc, tag, PCI_CLASS_REG);
+ if (PCI_CLASS(class) != PCI_CLASS_BRIDGE ||
+ PCI_SUBCLASS(class) != PCI_SUBCLASS_BRIDGE_PCI)
+ return -1;
+
+ /* if this is a bridge, get secondary bus */
+ binf = pci_conf_read(acpi->sc_pc, tag, PPB_REG_BUSINFO);
+ bus = PPB_BUSINFO_SECONDARY(binf);
+ }
+
+ /* cleanup */
+ while (!TAILQ_EMPTY(&dev_list)) {
+ dev = TAILQ_FIRST(&dev_list);
+ TAILQ_REMOVE(&dev_list, dev, list);
+ free(dev, M_TEMP);
+ }
+
+ return bus;
+}
+
/*
* Callback function for a namespace walk through ACPI space, finding all
- * PCI root busses.
+ * PCI root and subordinate busses.
*/
static ACPI_STATUS
-mpacpi_pcibus_cb(ACPI_HANDLE handle, UINT32 level, void *ct, void **status)
+mpacpi_pcibus_cb(ACPI_HANDLE handle, UINT32 level, void *p, void **status)
{
- ACPI_STATUS ret;
+ ACPI_STATUS rv;
ACPI_BUFFER buf;
ACPI_INTEGER val;
+ ACPI_DEVICE_INFO *devinfo;
struct mpacpi_pcibus *mpr;
+ struct acpi_softc *acpi = p;
+
+ buf.Pointer = NULL;
+ buf.Length = ACPI_ALLOCATE_BUFFER;
- ret = acpi_get(handle, &buf, AcpiGetIrqRoutingTable);
- if (ACPI_FAILURE(ret))
+ /* get _HID, _CID and _STA */
+ rv = AcpiGetObjectInfo(handle, &buf);
+ if (ACPI_FAILURE(rv))
Home |
Main Index |
Thread Index |
Old Index