summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2014-11-26 09:29:18 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2014-11-26 09:29:18 +0000
commit2b4133a2043cca8c05f1383f58d2952b012ab177 (patch)
tree78d9e5f9a0ee2965d7815013889f8f981d2aedd8
parente224f050289ce337bbd1d6299f622f27b3c71c91 (diff)
Seems Sun^H^H^HOracle is doing something naughty and (deliberately) puts
non-prefetchable BARs of the onboard mpii(4) behind a prefetchable memory range on the bridge it sists behind. Since we rely on the formware to program BARs for us on sparc64, add a workaround to avoid whacking these BARs and make the machine panic later when it tries to access the registers. ok miod@, deraadt@
-rw-r--r--sys/dev/pci/pci.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index e298e833cbf..65aae5d7ca8 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci.c,v 1.107 2014/11/24 13:48:49 kettenis Exp $ */
+/* $OpenBSD: pci.c,v 1.108 2014/11/26 09:29:17 kettenis Exp $ */
/* $NetBSD: pci.c,v 1.31 1997/06/06 23:48:04 thorpej Exp $ */
/*
@@ -848,21 +848,41 @@ pci_reserve_resources(struct pci_attach_args *pa)
break;
}
if (pa->pa_memex && extent_alloc_region(pa->pa_memex,
- base, size, EX_NOWAIT)) {
- printf("%d:%d:%d: mem address conflict 0x%lx/0x%lx\n",
- bus, dev, func, base, size);
- pci_conf_write(pc, tag, reg, 0);
- if (type & PCI_MAPREG_MEM_TYPE_64BIT)
- pci_conf_write(pc, tag, reg + 4, 0);
+ base, size, EX_NOWAIT) == 0) {
+ break;
}
+#ifdef __sparc64__
+ /*
+ * Certain SPARC T5 systems assign
+ * non-prefetchable 64-bit BARs of its onboard
+ * mpii(4) controllers addresses in the
+ * prefetchable memory range. This is
+ * (probably) safe, as reads from the device
+ * registers mapped by these BARs are
+ * side-effect free. So assume the firmware
+ * knows what it is doing.
+ */
+ if (base >= 0x100000000 &&
+ pa->pa_pmemex && extent_alloc_region(pa->pa_pmemex,
+ base, size, EX_NOWAIT) == 0) {
+ break;
+ }
+#endif
+ printf("%d:%d:%d: mem address conflict 0x%lx/0x%lx\n",
+ bus, dev, func, base, size);
+ pci_conf_write(pc, tag, reg, 0);
+ if (type & PCI_MAPREG_MEM_TYPE_64BIT)
+ pci_conf_write(pc, tag, reg + 4, 0);
break;
case PCI_MAPREG_TYPE_IO:
if (pa->pa_ioex && extent_alloc_region(pa->pa_ioex,
- base, size, EX_NOWAIT)) {
- printf("%d:%d:%d: io address conflict 0x%lx/0x%lx\n",
- bus, dev, func, base, size);
- pci_conf_write(pc, tag, reg, 0);
+ base, size, EX_NOWAIT) == 0) {
+ break;
}
+
+ printf("%d:%d:%d: io address conflict 0x%lx/0x%lx\n",
+ bus, dev, func, base, size);
+ pci_conf_write(pc, tag, reg, 0);
break;
}