diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2005-05-26 19:47:45 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2005-05-26 19:47:45 +0000 |
commit | 720cb452174b7abfc2646245dcf0c3bfd5ece52e (patch) | |
tree | f433b3d0cf55ab1888dc6656e79972b559b6cd63 /sys/arch | |
parent | 353d41f2060a8472ece65919c30a3f1bac3aa9a9 (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')
-rw-r--r-- | sys/arch/amd64/pci/iommu.c | 27 |
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); |