diff options
| author | hannken <hannken@NetBSD.org> | 2016-07-12 09:29:32 +0000 |
|---|---|---|
| committer | hannken <hannken@NetBSD.org> | 2016-07-12 09:29:32 +0000 |
| commit | df080cddd4eb41f57e594cea9906b82d93b9b0b9 (patch) | |
| tree | 9404cb0a4741263ea8dd3653eeffcbef22226f10 /sys/dev | |
| parent | 148c6b7017574274565a966ff6dc29280cd316af (diff) | |
On an Intel E7520 temporarily disable Enhanced Config Access error
detection and reporting during bus scan.
Fixes PR kern/51251: ACPI device probe raises NMI
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/acpi/acpi_mcfg.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/sys/dev/acpi/acpi_mcfg.c b/sys/dev/acpi/acpi_mcfg.c index 6336c51c45b..fce7d82797f 100644 --- a/sys/dev/acpi/acpi_mcfg.c +++ b/sys/dev/acpi/acpi_mcfg.c @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_mcfg.c,v 1.2 2015/10/11 21:49:22 christos Exp $ */ +/* $NetBSD: acpi_mcfg.c,v 1.3 2016/07/12 09:29:32 hannken Exp $ */ /*- * Copyright (C) 2015 NONAKA Kimihiro <nonaka@NetBSD.org> @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_mcfg.c,v 1.2 2015/10/11 21:49:22 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_mcfg.c,v 1.3 2016/07/12 09:29:32 hannken Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -526,6 +526,9 @@ acpimcfg_map_bus(device_t self, pci_chipset_tag_t pc, int bus) struct mcfg_bus *mb; bus_space_handle_t bsh; bus_addr_t baddr; + pcitag_t tag; + pcireg_t reg; + bool is_e7520_mch; int boff; int last_dev, last_func; int i, j; @@ -569,8 +572,29 @@ acpimcfg_map_bus(device_t self, pci_chipset_tag_t pc, int bus) mb->valid_ndevs = 0; mb->last_probed = pci_make_tag(pc, bus, 0, 0); + /* + * On an Intel E7520 we have to temporarily disable + * Enhanced Config Access error detection and reporting + * by setting the appropriate error mask in HI_ERRMASK register. + * + * See "Intel E7520 Memory Controller Hub (MCH) Datasheet", + * Document 303006-002, pg. 82 + */ + tag = pci_make_tag(pc, 0, 0, 1); + reg = pci_conf_read(pc, tag, PCI_ID_REG); + is_e7520_mch = (reg == + PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_E7525_MCHER)); + if (is_e7520_mch) { + reg = pci_conf_read(pc, tag, 0x54); + pci_conf_write(pc, tag, 0x54, reg | 0x20); + } + acpimcfg_scan_bus(sc, pc, bus); + if (is_e7520_mch) { + pci_conf_write(pc, tag, 0x54, reg); + } + /* Unmap extended configration space of all dev/func. */ bus_space_unmap(seg->ms_bst, bsh, ACPIMCFG_SIZE_PER_BUS); memset(mb->bsh, 0, sizeof(mb->bsh)); |
