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