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");
 

Reply via email to