summaryrefslogtreecommitdiff
path: root/sys
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
parent8bd330d847277812118fc4fcb09902d0bdc7505f (diff)
Perform IOMMU cache flushes on Oberon.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sparc64/dev/iommu.c27
-rw-r--r--sys/arch/sparc64/dev/iommureg.h9
-rw-r--r--sys/arch/sparc64/dev/iommuvar.h4
-rw-r--r--sys/arch/sparc64/dev/psychoreg.h4
-rw-r--r--sys/arch/sparc64/dev/pyro.c6
-rw-r--r--sys/arch/sparc64/dev/schizoreg.h7
6 files changed, 43 insertions, 14 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);
}
diff --git a/sys/arch/sparc64/dev/iommureg.h b/sys/arch/sparc64/dev/iommureg.h
index 53cc1de104a..153c058cf36 100644
--- a/sys/arch/sparc64/dev/iommureg.h
+++ b/sys/arch/sparc64/dev/iommureg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: iommureg.h,v 1.15 2007/05/29 09:53:59 sobrado Exp $ */
+/* $OpenBSD: iommureg.h,v 1.16 2008/07/12 13:08:04 kettenis Exp $ */
/* $NetBSD: iommureg.h,v 1.6 2001/07/20 00:07:13 eeh Exp $ */
/*
@@ -54,6 +54,11 @@ struct iommureg {
volatile u_int64_t iommu_cr; /* IOMMU control register */
volatile u_int64_t iommu_tsb; /* IOMMU TSB base register */
volatile u_int64_t iommu_flush; /* IOMMU flush register */
+ volatile u_int64_t iommu_ctxflush;
+ volatile u_int64_t iommu_reserved[28];
+ volatile u_int64_t iommu_cache_flush;
+ volatile u_int64_t iommu_cache_invalidate;
+ volatile u_int64_t iommu_reserved2[30];
};
/* streaming buffer registers */
@@ -94,7 +99,7 @@ struct iommu_strbuf {
#define IOTTE_STREAM 0x1000000000000000LL /* Is page streamable? */
#define IOTTE_LOCAL 0x0800000000000000LL /* Accesses to same bus segment? */
#define IOTTE_CONTEXT 0x07ff800000000000LL /* context number */
-#define IOTTE_PAMASK 0x000007ffffffe000LL /* Let's assume this is correct (bits 42..13) */
+#define IOTTE_PAMASK 0x00007fffffffe000LL /* Let's assume this is correct (bits 42..13) */
#define IOTTE_C 0x0000000000000010LL /* Accesses to cacheable space */
#define IOTTE_W 0x0000000000000002LL /* Writeable */
#define IOTTE_SOFTWARE 0x0000000000001f80LL /* For software use (bits 12..7) */
diff --git a/sys/arch/sparc64/dev/iommuvar.h b/sys/arch/sparc64/dev/iommuvar.h
index 390f2d697bb..99d233b82de 100644
--- a/sys/arch/sparc64/dev/iommuvar.h
+++ b/sys/arch/sparc64/dev/iommuvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: iommuvar.h,v 1.12 2008/03/09 19:27:56 kettenis Exp $ */
+/* $OpenBSD: iommuvar.h,v 1.13 2008/07/12 13:08:04 kettenis Exp $ */
/* $NetBSD: iommuvar.h,v 1.9 2001/10/07 20:30:41 eeh Exp $ */
/*
@@ -110,6 +110,8 @@ struct iommu_state {
int64_t is_cr; /* Control register value */
struct mutex is_mtx;
struct extent *is_dvmamap; /* DVMA map for this instance */
+ int is_flags;
+#define IOMMU_FLUSH_CACHE 0x00000001
struct strbuf_ctl *is_sb[2]; /* Streaming buffers if any */
diff --git a/sys/arch/sparc64/dev/psychoreg.h b/sys/arch/sparc64/dev/psychoreg.h
index 94e297588da..93a01382129 100644
--- a/sys/arch/sparc64/dev/psychoreg.h
+++ b/sys/arch/sparc64/dev/psychoreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: psychoreg.h,v 1.11 2006/02/06 17:19:31 jmc Exp $ */
+/* $OpenBSD: psychoreg.h,v 1.12 2008/07/12 13:08:04 kettenis Exp $ */
/* $NetBSD: psychoreg.h,v 1.6.4.2 2001/09/13 01:14:40 thorpej Exp $ */
/*
@@ -85,7 +85,7 @@ struct psychoreg {
struct iommureg psy_iommu; /* 1fe.0000.0200,0210 */
- u_int64_t pad3[317];
+ u_int64_t pad3[256];
u_int64_t pcia_slot0_int; /* PCI bus a slot 0 irq map reg */ /* 1fe.0000.0c00 */
u_int64_t pcia_slot1_int; /* PCI bus a slot 1 irq map reg */ /* 1fe.0000.0c08 */
diff --git a/sys/arch/sparc64/dev/pyro.c b/sys/arch/sparc64/dev/pyro.c
index dad704e0491..5570e623027 100644
--- a/sys/arch/sparc64/dev/pyro.c
+++ b/sys/arch/sparc64/dev/pyro.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pyro.c,v 1.13 2008/07/12 12:21:04 kettenis Exp $ */
+/* $OpenBSD: pyro.c,v 1.14 2008/07/12 13:08:04 kettenis Exp $ */
/*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
@@ -240,6 +240,10 @@ pyro_init_iommu(struct pyro_softc *sc, struct pyro_pbm *pbm)
panic("couldn't malloc iommu name");
snprintf(name, 32, "%s dvma", sc->sc_dv.dv_xname);
+ /* On Oberon, we need to flush the cache. */
+ if (sc->sc_oberon)
+ is->is_flags |= IOMMU_FLUSH_CACHE;
+
iommu_init(name, is, tsbsize, iobase);
}
diff --git a/sys/arch/sparc64/dev/schizoreg.h b/sys/arch/sparc64/dev/schizoreg.h
index ef4d5dabcf1..af4344e8026 100644
--- a/sys/arch/sparc64/dev/schizoreg.h
+++ b/sys/arch/sparc64/dev/schizoreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: schizoreg.h,v 1.19 2008/02/10 12:53:01 kettenis Exp $ */
+/* $OpenBSD: schizoreg.h,v 1.20 2008/07/12 13:08:04 kettenis Exp $ */
/*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
@@ -27,9 +27,8 @@
*/
struct schizo_pbm_regs {
volatile u_int64_t _unused1[64]; /* 0x0000 - 0x01ff */
- struct iommureg iommu; /* 0x0200 - 0x0217 */
- volatile u_int64_t iommu_ctxflush; /* 0x0218 - 0x021f */
- volatile u_int64_t _unused2[444];
+ struct iommureg iommu; /* 0x0200 - 0x03ff */
+ volatile u_int64_t _unused2[384];
volatile u_int64_t imap[64];
volatile u_int64_t _unused3[64];
volatile u_int64_t iclr[64];