diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-07-12 13:08:05 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-07-12 13:08:05 +0000 |
commit | 7e51f579a2f0b79689d7b609916a75258fcd93c7 (patch) | |
tree | 82ebefa523b40fcbac02f53be90216b8fac230ca /sys/arch/sparc64/dev/iommu.c | |
parent | 8bd330d847277812118fc4fcb09902d0bdc7505f (diff) |
Perform IOMMU cache flushes on Oberon.
Diffstat (limited to 'sys/arch/sparc64/dev/iommu.c')
-rw-r--r-- | sys/arch/sparc64/dev/iommu.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/sys/arch/sparc64/dev/iommu.c b/sys/arch/sparc64/dev/iommu.c index c9ef4eb2210..50da7b37b2a 100644 --- a/sys/arch/sparc64/dev/iommu.c +++ b/sys/arch/sparc64/dev/iommu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: iommu.c,v 1.49 2007/12/15 18:08:07 deraadt Exp $ */ +/* $OpenBSD: iommu.c,v 1.50 2008/07/12 13:08:04 kettenis Exp $ */ /* $NetBSD: iommu.c,v 1.47 2002/02/08 20:03:45 eeh Exp $ */ /* @@ -263,6 +263,9 @@ iommu_reset(struct iommu_state *is) if (sb->sb_flush) printf(", STC%d enabled", i); } + + if (is->is_flags & IOMMU_FLUSH_CACHE) + IOMMUREG_WRITE(is, iommu_cache_invalidate, -1ULL); } /* @@ -1807,7 +1810,7 @@ iommu_iomap_load_map(struct iommu_state *is, struct iommu_map_state *ims, struct iommu_page_map *ipm = &ims->ims_map; struct iommu_page_entry *e; struct strbuf_ctl *sb = ims->ims_sb; - int i; + int i, slot; if (sb->sb_flush == NULL) flags &= ~BUS_DMA_STREAMING; @@ -1820,6 +1823,14 @@ iommu_iomap_load_map(struct iommu_state *is, struct iommu_map_state *ims, for (i = 0, e = ipm->ipm_map; i < ipm->ipm_pagecnt; ++i, ++e) { e->ipe_va = vmaddr; iommu_enter(is, sb, e->ipe_va, e->ipe_pa, flags); + + /* Flush cache if necessary. */ + slot = IOTSBSLOT(e->ipe_va, is->is_tsbsize); + if (is->is_flags & IOMMU_FLUSH_CACHE && + (i == (ipm->ipm_pagecnt - 1) || (slot % 8) == 7)) + IOMMUREG_WRITE(is, iommu_cache_flush, + is->is_ptsb + slot * 8); + vmaddr += PAGE_SIZE; } @@ -1835,11 +1846,19 @@ iommu_iomap_unload_map(struct iommu_state *is, struct iommu_map_state *ims) struct iommu_page_map *ipm = &ims->ims_map; struct iommu_page_entry *e; struct strbuf_ctl *sb = ims->ims_sb; - int i; + int i, slot; - for (i = 0, e = ipm->ipm_map; i < ipm->ipm_pagecnt; ++i, ++e) + for (i = 0, e = ipm->ipm_map; i < ipm->ipm_pagecnt; ++i, ++e) { iommu_remove(is, sb, e->ipe_va); + /* Flush cache if necessary. */ + slot = IOTSBSLOT(e->ipe_va, is->is_tsbsize); + if (is->is_flags & IOMMU_FLUSH_CACHE && + (i == (ipm->ipm_pagecnt - 1) || (slot % 8) == 7)) + IOMMUREG_WRITE(is, iommu_cache_flush, + is->is_ptsb + slot * 8); + } + return (0); } |