summaryrefslogtreecommitdiff
path: root/sys/arch/amd64
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2005-05-26 19:47:45 +0000
committerJason Wright <jason@cvs.openbsd.org>2005-05-26 19:47:45 +0000
commit720cb452174b7abfc2646245dcf0c3bfd5ece52e (patch)
treef433b3d0cf55ab1888dc6656e79972b559b6cd63 /sys/arch/amd64
parent353d41f2060a8472ece65919c30a3f1bac3aa9a9 (diff)
make all mappings valid/coherent. For pages not currently mapped, fill
the entry with a scribble page. In the future, we'll use this for detecting bad device drivers. Page faults are bad in an iommu =)
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r--sys/arch/amd64/pci/iommu.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/sys/arch/amd64/pci/iommu.c b/sys/arch/amd64/pci/iommu.c
index 57673803e3c..5b72f34de2f 100644
--- a/sys/arch/amd64/pci/iommu.c
+++ b/sys/arch/amd64/pci/iommu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: iommu.c,v 1.1 2005/05/26 17:48:20 jason Exp $ */
+/* $OpenBSD: iommu.c,v 1.2 2005/05/26 19:47:44 jason Exp $ */
/*
* Copyright (c) 2005 Jason L. Wright (jason@thought.net)
@@ -117,6 +117,9 @@ pci_chipset_tag_t gartpc;
pcitag_t garttag;
bus_dma_tag_t gartparent;
paddr_t gartpa;
+paddr_t gartscribpa;
+void *gartscrib;
+u_int32_t gartscribflags;
void amdgart_invalidate_wait(pci_chipset_tag_t, pcitag_t);
void amdgart_invalidate(pci_chipset_tag_t, pcitag_t);
@@ -200,6 +203,16 @@ amdgart_initpte(pci_chipset_tag_t pc, pcitag_t tag, paddr_t base,
TAILQ_INIT(&gartplist);
+ gartscrib = (void *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT);
+ if (gartscrib == NULL) {
+ printf("\nGART: failed to get scribble page");
+ goto err;
+ }
+ pmap_extract(pmap_kernel(), (vaddr_t)gartscrib, &gartscribpa);
+ gartscribflags = GART_PTE_VALID | GART_PTE_COHERENT |
+ ((gartscribpa >> 28) & GART_PTE_PHYSHI) |
+ (gartscribpa & GART_PTE_PHYSLO);
+
err = uvm_pglistalloc(sz, sz, trunc_page(avail_end), sz, sz,
&gartplist, 1, 0);
if (err) {
@@ -240,13 +253,15 @@ amdgart_initpte(pci_chipset_tag_t pc, pcitag_t tag, paddr_t base,
pci_conf_write(NULL, tag, GART_TBLBASE, (pa >> 8) & GART_TBLBASE_MASK);
for (r = 0, pte = gartpt; r < (sz / sizeof(*gartpt)); r++, pte++)
- *pte = 0;
+ *pte = gartscribflags;
amdgart_invalidate(pc, tag);
amdgart_invalidate_wait(pc, tag);
return (0);
err:
+ if (gartscrib)
+ free(gartscrib, M_DEVBUF);
if (!TAILQ_EMPTY(&gartplist))
uvm_pglistfree(&gartplist);
if (gartex != NULL) {
@@ -284,12 +299,6 @@ amdgart_probe(struct pcibus_attach_args *pba)
return;
}
-#if 0
- v = pci_conf_read(pc, tag, MCANB_CTRL);
- v |= MCANB_GARTTBLWKEN;
- pci_conf_write(pc, tag, MCANB_CTRL, v);
-#endif
-
apctl = pci_conf_read(pc, tag, GART_APCTRL);
if (apctl & GART_APCTRL_ENABLE) {
printf("\nBIOS already enabled it, this is hard, no gart.");
@@ -422,7 +431,7 @@ amdgart_iommu_unmap(struct extent *ex, paddr_t pa, psize_t len)
for (idx = 0; idx < alen; idx += PAGE_SIZE) {
pgno = ((base - gartpa) + idx) >> PGSHIFT;
- gartpt[pgno] = GART_PTE_COHERENT;
+ gartpt[pgno] = gartscribflags;
}
return (0);