summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64/dev/iommu.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2008-07-12 13:08:05 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2008-07-12 13:08:05 +0000
commit7e51f579a2f0b79689d7b609916a75258fcd93c7 (patch)
tree82ebefa523b40fcbac02f53be90216b8fac230ca /sys/arch/sparc64/dev/iommu.c
parent8bd330d847277812118fc4fcb09902d0bdc7505f (diff)
Perform IOMMU cache flushes on Oberon.
Diffstat (limited to 'sys/arch/sparc64/dev/iommu.c')
-rw-r--r--sys/arch/sparc64/dev/iommu.c27
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);
}