Module Name: src Committed By: martin Date: Fri Feb 1 11:25:13 UTC 2019
Modified Files: src/sys/dev/pci [netbsd-8]: ppb.c Log Message: Pull up following revision(s) (requested by msaitoh in ticket #1181): sys/dev/pci/ppb.c: revision 1.66 sys/dev/pci/ppb.c: revision 1.67 Explicitly enable bus masterling in case BIOS, UEFI or firmware don't enable it. Might fix PR kern/53811. - If the secondary bus is configured and the bus mastering is not enabled, enable it. Suggested by thorpej@. To generate a diff of this commit: cvs rdiff -u -r1.63 -r1.63.2.1 src/sys/dev/pci/ppb.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/ppb.c diff -u src/sys/dev/pci/ppb.c:1.63 src/sys/dev/pci/ppb.c:1.63.2.1 --- src/sys/dev/pci/ppb.c:1.63 Wed May 10 03:24:31 2017 +++ src/sys/dev/pci/ppb.c Fri Feb 1 11:25:13 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: ppb.c,v 1.63 2017/05/10 03:24:31 msaitoh Exp $ */ +/* $NetBSD: ppb.c,v 1.63.2.1 2019/02/01 11:25:13 martin Exp $ */ /* * Copyright (c) 1996, 1998 Christopher G. Demetriou. All rights reserved. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ppb.c,v 1.63 2017/05/10 03:24:31 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ppb.c,v 1.63.2.1 2019/02/01 11:25:13 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -214,6 +214,7 @@ ppbattach(device_t parent, device_t self char intrbuf[PCI_INTRSTR_LEN]; #endif pcireg_t busdata, reg; + bool second_configured = false; pci_aprint_devinfo(pa, NULL); @@ -350,6 +351,73 @@ ppbattach(device_t parent, device_t self } #endif /* PPB_USEINTR */ + /* Configuration test */ + if (PPB_BUSINFO_SECONDARY(busdata) != 0) { + uint32_t base, limit; + + /* I/O region test */ + reg = pci_conf_read(pc, pa->pa_tag, PCI_BRIDGE_STATIO_REG); + base = (reg & PCI_BRIDGE_STATIO_IOBASE_MASK) << 8; + limit = ((reg >> PCI_BRIDGE_STATIO_IOLIMIT_SHIFT) + & PCI_BRIDGE_STATIO_IOLIMIT_MASK) << 8; + limit |= 0x00000fff; + if (PCI_BRIDGE_IO_32BITS(reg)) { + reg = pci_conf_read(pc, pa->pa_tag, + PCI_BRIDGE_IOHIGH_REG); + base |= ((reg >> PCI_BRIDGE_IOHIGH_BASE_SHIFT) + & 0xffff) << 16; + limit |= ((reg >> PCI_BRIDGE_IOHIGH_LIMIT_SHIFT) + & 0xffff) << 16; + } + if (base < limit) { + second_configured = true; + goto configure; + } + + /* Non-prefetchable memory region test */ + reg = pci_conf_read(pc, pa->pa_tag, PCI_BRIDGE_MEMORY_REG); + base = ((reg >> PCI_BRIDGE_MEMORY_BASE_SHIFT) + & PCI_BRIDGE_MEMORY_BASE_MASK) << 20; + limit = (((reg >> PCI_BRIDGE_MEMORY_LIMIT_SHIFT) + & PCI_BRIDGE_MEMORY_LIMIT_MASK) << 20) | 0x000fffff; + if (base < limit) { + second_configured = true; + goto configure; + } + + /* Prefetchable memory region test */ + reg = pci_conf_read(pc, pa->pa_tag, + PCI_BRIDGE_PREFETCHMEM_REG); + base = ((reg >> PCI_BRIDGE_PREFETCHMEM_BASE_SHIFT) + & PCI_BRIDGE_PREFETCHMEM_BASE_MASK) << 20; + limit = (((reg >> PCI_BRIDGE_PREFETCHMEM_LIMIT_SHIFT) + & PCI_BRIDGE_PREFETCHMEM_LIMIT_MASK) << 20) | 0x000fffff; + if (PCI_BRIDGE_PREFETCHMEM_64BITS(reg)) { + reg = pci_conf_read(pc, pa->pa_tag, + PCI_BRIDGE_IOHIGH_REG); + base |= (uint64_t)pci_conf_read(pc, pa->pa_tag, + PCI_BRIDGE_PREFETCHBASE32_REG) << 32; + limit |= (uint64_t)pci_conf_read(pc, pa->pa_tag, + PCI_BRIDGE_PREFETCHLIMIT32_REG) << 32; + } + if (base < limit) { + second_configured = true; + goto configure; + } + } + +configure: + /* + * If the secondary bus is configured and the bus mastering is not + * enabled, enable it. + */ + if (second_configured) { + reg = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); + if ((reg & PCI_COMMAND_MASTER_ENABLE) == 0) + pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, + reg | PCI_COMMAND_MASTER_ENABLE); + } + if (!pmf_device_register(self, ppb_suspend, ppb_resume)) aprint_error_dev(self, "couldn't establish power handler\n");