summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2014-10-26 16:18:43 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2014-10-26 16:18:43 +0000
commit395b22669041af25c911b3efeda5f1f3cae19027 (patch)
treec9f057c86e19e371dac253821ba60d38061b6ef7
parentb60c3155fbb8b9eab9a7db1d72694f933809d7a0 (diff)
Add resource tracking for PCI ROMs.
ok deraadt@
-rw-r--r--sys/dev/pci/pci.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index ca6eaa22dba..d56ed8249d1 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci.c,v 1.105 2014/09/14 14:17:25 jsg Exp $ */
+/* $OpenBSD: pci.c,v 1.106 2014/10/26 16:18:42 kettenis Exp $ */
/* $NetBSD: pci.c,v 1.31 1997/06/06 23:48:04 thorpej Exp $ */
/*
@@ -797,12 +797,14 @@ pci_reserve_resources(struct pci_attach_args *pa)
pci_chipset_tag_t pc = pa->pa_pc;
pcitag_t tag = pa->pa_tag;
pcireg_t bhlc, blr, type, bir;
+ pcireg_t addr, mask;
bus_addr_t base, limit;
bus_size_t size;
- int reg, reg_start, reg_end;
+ int reg, reg_start, reg_end, reg_rom;
int bus, dev, func;
int sec, sub;
int flags;
+ int s;
pci_decompose_tag(pc, tag, &bus, &dev, &func);
@@ -811,14 +813,17 @@ pci_reserve_resources(struct pci_attach_args *pa)
case 0:
reg_start = PCI_MAPREG_START;
reg_end = PCI_MAPREG_END;
+ reg_rom = PCI_ROM_REG;
break;
case 1: /* PCI-PCI bridge */
reg_start = PCI_MAPREG_START;
reg_end = PCI_MAPREG_PPB_END;
+ reg_rom = 0; /* 0x38 */
break;
case 2: /* PCI-CardBus bridge */
reg_start = PCI_MAPREG_START;
reg_end = PCI_MAPREG_PCB_END;
+ reg_rom = 0;
break;
default:
return (0);
@@ -865,6 +870,28 @@ pci_reserve_resources(struct pci_attach_args *pa)
reg += 4;
}
+ if (reg_rom != 0) {
+ s = splhigh();
+ addr = pci_conf_read(pc, tag, PCI_ROM_REG);
+ pci_conf_write(pc, tag, PCI_ROM_REG, ~PCI_ROM_ENABLE);
+ mask = pci_conf_read(pc, tag, PCI_ROM_REG);
+ pci_conf_write(pc, tag, PCI_ROM_REG, addr);
+ splx(s);
+
+ base = PCI_ROM_ADDR(addr);
+ size = PCI_ROM_SIZE(mask);
+ if (base != 0 && size != 0) {
+ if (pa->pa_pmemex && extent_alloc_region(pa->pa_pmemex,
+ base, size, EX_NOWAIT) &&
+ 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, PCI_ROM_REG, 0);
+ }
+ }
+ }
+
if (PCI_HDRTYPE_TYPE(bhlc) != 1)
return (0);