summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/sparc64/include/iommuvar.h9
-rw-r--r--sys/sparc64/pci/psycho.c2
-rw-r--r--sys/sparc64/sbus/sbus.c20
-rw-r--r--sys/sparc64/sparc64/iommu.c353
4 files changed, 160 insertions, 224 deletions
diff --git a/sys/sparc64/include/iommuvar.h b/sys/sparc64/include/iommuvar.h
index 12ef946..32eb432 100644
--- a/sys/sparc64/include/iommuvar.h
+++ b/sys/sparc64/include/iommuvar.h
@@ -43,12 +43,9 @@
* per-IOMMU state
*/
struct iommu_state {
- vm_offset_t is_ptsb; /* TSB physical address */
- u_int64_t *is_tsb; /* TSB virtual address */
int is_tsbsize; /* 0 = 8K, ... */
u_int64_t is_dvmabase;
int64_t is_cr; /* IOMMU control register value */
- struct rman is_dvma_rman; /* DVMA map for this instance */
vm_offset_t is_flushpa[2];
volatile int64_t *is_flushva[2];
@@ -71,12 +68,14 @@ struct iommu_state {
bus_addr_t is_dtag; /* tag diagnostics access */
bus_addr_t is_ddram; /* data ram diag. access */
bus_addr_t is_dqueue; /* LRU queue diag. access */
- bus_addr_t is_dva; /* VA diag. register */
+ bus_addr_t is_dva; /* VA diag. register */
bus_addr_t is_dtcmp; /* tag compare diag. access */
+
+ STAILQ_ENTRY(iommu_state) is_link;
};
/* interfaces for PCI/SBUS code */
-void iommu_init(char *, struct iommu_state *, int, u_int32_t);
+void iommu_init(char *, struct iommu_state *, int, u_int32_t, int);
void iommu_reset(struct iommu_state *);
void iommu_enter(struct iommu_state *, vm_offset_t, vm_offset_t, int);
void iommu_remove(struct iommu_state *, vm_offset_t, size_t);
diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c
index 901639e..65a94d1 100644
--- a/sys/sparc64/pci/psycho.c
+++ b/sys/sparc64/pci/psycho.c
@@ -846,7 +846,7 @@ psycho_iommu_init(struct psycho_softc *sc, int tsbsize)
panic("couldn't malloc iommu name");
snprintf(name, 32, "%s dvma", device_get_name(sc->sc_dev));
- iommu_init(name, is, tsbsize, iobase);
+ iommu_init(name, is, tsbsize, iobase, 0);
}
static void
diff --git a/sys/sparc64/sbus/sbus.c b/sys/sparc64/sbus/sbus.c
index 8825630..593fda6 100644
--- a/sys/sparc64/sbus/sbus.c
+++ b/sys/sparc64/sbus/sbus.c
@@ -297,7 +297,6 @@ sbus_probe(device_t dev)
bus_size_t size;
char *name, *cname, *t;
phandle_t child, node = nexus_get_node(dev);
- u_long da;
u_int64_t mr;
int intr, clock, rid, vec, i;
@@ -421,7 +420,12 @@ sbus_probe(device_t dev)
panic("sbus_probe: couldn't malloc iommu name");
snprintf(name, 32, "%s dvma", device_get_name(dev));
- iommu_init(name, &sc->sc_is, 0, -1);
+ /*
+ * Note: the SBus IOMMU ignores the high bits of an address, so a NULL
+ * DMA pointer will be translated by the first page of the IOTSB.
+ * To detect bugs we'll allocate and ignore the first entry.
+ */
+ iommu_init(name, &sc->sc_is, 0, -1, 1);
/* Enable the over-temperature and power-fail intrrupts. */
rid = 0;
@@ -446,18 +450,6 @@ sbus_probe(device_t dev)
/* Initialize the counter-timer. */
sparc64_counter_init(sc->sc_bustag, sc->sc_bushandle, SBR_TC0);
-#ifdef INVARIANTS
- da = sc->sc_is.is_dvmabase / IO_PAGE_SIZE;
- /*
- * Note: the SBUS IOMMU ignores the high bits of an address, so a NULL
- * DMA pointer will be translated by the first page of the IOTSB.
- * To detect bugs we'll allocate and ignore the first entry.
- */
- if (rman_reserve_resource(&sc->sc_is.is_dvma_rman, da, da, 1, 0,
- NULL) == NULL)
- panic("sbus_probe: can't toss first dvma page");
-#endif /* INVARIANTS */
-
/*
* Loop through ROM children, fixing any relative addresses
* and then configuring each device.
diff --git a/sys/sparc64/sparc64/iommu.c b/sys/sparc64/sparc64/iommu.c
index c7acdf4..a6c79b3 100644
--- a/sys/sparc64/sparc64/iommu.c
+++ b/sys/sparc64/sparc64/iommu.c
@@ -111,6 +111,10 @@
/*
* UltraSPARC IOMMU support; used by both the sbus and pci code.
+ * Currently, the IOTSBs are synchronized, because determining the bus the map
+ * is to be loaded for is not possible with the current busdma code.
+ * The code is structured so that the IOMMUs can be easily divorced when that
+ * is fixed.
*/
#include "opt_iommu.h"
@@ -132,26 +136,36 @@
#include <machine/iommuvar.h>
-#ifdef IOMMU_DEBUG
-#define IDB_BUSDMA 0x1
-#define IDB_IOMMU 0x2
-#define IDB_INFO 0x4
-#define IDB_SYNC 0x8
-int iommudebug = 0xff;
-#define DPRINTF(l, s) do { if (iommudebug & l) printf s; } while (0)
-#else
-#define DPRINTF(l, s)
+MALLOC_DEFINE(M_IOMMU, "dvmamem", "IOMMU DVMA Buffers");
+
+static int iommu_strbuf_flush_sync(struct iommu_state *);
+#ifdef IOMMU_DIAG
+static void iommu_diag(struct iommu_state *, vm_offset_t va);
#endif
-MALLOC_DEFINE(M_IOMMU, "dvmamem", "IOMMU DVMA Buffers");
+/*
+ * The following 4 variables need to be moved to the per-IOMMU state once
+ * the IOTSBs are divorced.
+ * LRU queue handling for lazy resource allocation.
+ */
+static STAILQ_HEAD(, bus_dmamap) iommu_maplruq =
+ STAILQ_HEAD_INITIALIZER(iommu_maplruq);
-#define iommu_strbuf_flush(i,v) do { \
- if ((i)->is_sb[0] != 0) \
- IOMMU_WRITE8((i), is_sb[0], ISR_PGFLUSH, (v)); \
- if ((i)->is_sb[1] != 0) \
- IOMMU_WRITE8((i), is_sb[1], ISR_PGFLUSH, (v)); \
-} while (0)
+/* DVMA memory rman. */
+static struct rman iommu_dvma_rman;
+/* Virtual and physical address of the TSB. */
+static u_int64_t *iommu_tsb;
+static vm_offset_t iommu_ptsb;
+
+/* List of all IOMMUs. */
+static STAILQ_HEAD(, iommu_state) iommu_insts =
+ STAILQ_HEAD_INITIALIZER(iommu_insts);
+
+/*
+ * Helpers. Some of these take unused iommu states as parameters, to ease the
+ * transition to divorced TSBs.
+ */
#define IOMMU_READ8(is, reg, off) \
bus_space_read_8((is)->is_bustag, (is)->is_bushandle, \
(is)->reg + (off))
@@ -166,17 +180,56 @@ MALLOC_DEFINE(M_IOMMU, "dvmamem", "IOMMU DVMA Buffers");
#define IOMMU_SIZE_ROUNDUP(sz) \
(round_io_page(sz) + IO_PAGE_SIZE)
-static int iommu_strbuf_flush_done(struct iommu_state *);
-#ifdef IOMMU_DIAG
-static void iommu_diag(struct iommu_state *, vm_offset_t va);
-#endif
+#define IOMMU_SET_TTE(is, va, tte) \
+ (iommu_tsb[IOTSBSLOT(va)] = (tte))
+
+static __inline void
+iommu_tlb_flush(struct iommu_state *is, bus_addr_t va)
+{
+ struct iommu_state *it;
+
+ /*
+ * Since the TSB is shared for now, the TLBs of all IOMMUs
+ * need to be flushed.
+ */
+ STAILQ_FOREACH(it, &iommu_insts, is_link)
+ IOMMU_WRITE8(it, is_iommu, IMR_FLUSH, va);
+}
+
+
+#define IOMMU_HAS_SB(is) \
+ ((is)->is_sb[0] != 0 || (is)->is_sb[1] != 0)
+
+static __inline void
+iommu_strbuf_flushpg(struct iommu_state *is, bus_addr_t va)
+{
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ if (is->is_sb[i] != 0)
+ IOMMU_WRITE8(is, is_sb[i], ISR_PGFLUSH, va);
+ }
+}
+
+static __inline void
+iommu_strbuf_flush(struct iommu_state *is, bus_addr_t va, int sync)
+{
+ struct iommu_state *it;
+
+ /*
+ * Need to flush the streaming buffers of all IOMMUs, we cannot
+ * determine which one was used for the transaction.
+ */
+ STAILQ_FOREACH(it, &iommu_insts, is_link) {
+ iommu_strbuf_flushpg(it, va);
+ if (sync)
+ iommu_strbuf_flush_sync(it);
+ }
+}
/*
* LRU queue handling for lazy resource allocation.
*/
-static STAILQ_HEAD(, bus_dmamap) iommu_maplruq =
- STAILQ_HEAD_INITIALIZER(iommu_maplruq);
-
static __inline void
iommu_map_insq(bus_dmamap_t map)
{
@@ -197,15 +250,17 @@ iommu_map_remq(bus_dmamap_t map)
}
/*
- * initialise the UltraSPARC IOMMU (SBUS or PCI):
+ * initialise the UltraSPARC IOMMU (SBus or PCI):
* - allocate and setup the iotsb.
* - enable the IOMMU
* - initialise the streaming buffers (if they exist)
* - create a private DVMA map.
*/
void
-iommu_init(char *name, struct iommu_state *is, int tsbsize, u_int32_t iovabase)
+iommu_init(char *name, struct iommu_state *is, int tsbsize, u_int32_t iovabase,
+ int resvpg)
{
+ struct iommu_state *first;
vm_size_t size;
vm_offset_t offs;
int i;
@@ -227,37 +282,52 @@ iommu_init(char *name, struct iommu_state *is, int tsbsize, u_int32_t iovabase)
if (iovabase == -1)
is->is_dvmabase = IOTSB_VSTART(is->is_tsbsize);
- /*
- * Allocate memory for I/O pagetables. They need to be physically
- * contiguous.
- */
size = PAGE_SIZE << is->is_tsbsize;
- is->is_tsb = contigmalloc(size, M_DEVBUF, M_NOWAIT, 0, ~0UL, PAGE_SIZE,
- 0);
- if (is->is_tsb == 0)
- panic("iommu_init: no memory");
- is->is_ptsb = pmap_kextract((vm_offset_t)is->is_tsb);
-
- bzero(is->is_tsb, size);
-
-#ifdef IOMMU_DEBUG
- if (iommudebug & IDB_INFO) {
- printf("iommu regs at offsets: cr=%#lx tsb=%#lx flush=%#lx\n",
- (u_long)is->is_iommu + IMR_CTL,
- (u_long)is->is_iommu + IMR_TSB,
- (u_long)is->is_iommu + IMR_FLUSH);
- printf("iommu cr=%lx tsb=%lx\n",
- (u_long)IOMMU_READ8(is, is_iommu, IMR_CTL),
- (u_long)IOMMU_READ8(is, is_iommu, IMR_TSB))
- printf("TSB base %p phys %lx\n", (void *)is->is_tsb,
- (unsigned long)is->is_ptsb);
+ printf("DVMA map: %#lx to %#lx\n",
+ is->is_dvmabase, is->is_dvmabase +
+ (size << (IO_PAGE_SHIFT - IOTTE_SHIFT)) - 1);
+
+ if (STAILQ_EMPTY(&iommu_insts)) {
+ /*
+ * First IOMMU to be registered; set up resource mamangement
+ * and allocate TSB memory.
+ */
+ iommu_dvma_rman.rm_type = RMAN_ARRAY;
+ iommu_dvma_rman.rm_descr = "DVMA Memory";
+ if (rman_init(&iommu_dvma_rman) != 0 ||
+ rman_manage_region(&iommu_dvma_rman,
+ (is->is_dvmabase >> IO_PAGE_SHIFT) + resvpg,
+ (is->is_dvmabase + (size <<
+ (IO_PAGE_SHIFT - IOTTE_SHIFT))) >> IO_PAGE_SHIFT) != 0)
+ panic("iommu_init: can't initialize dvma rman");
+ /*
+ * Allocate memory for I/O page tables. They need to be
+ * physically contiguous.
+ */
+ iommu_tsb = contigmalloc(size, M_DEVBUF, M_NOWAIT, 0, ~0UL,
+ PAGE_SIZE, 0);
+ if (iommu_tsb == 0)
+ panic("iommu_init: contigmalloc failed");
+ iommu_ptsb = pmap_kextract((vm_offset_t)iommu_tsb);
+ bzero(iommu_tsb, size);
+ } else {
+ /*
+ * Not the first IOMMU; just check that the parameters match
+ * those of the first one.
+ */
+ first = STAILQ_FIRST(&iommu_insts);
+ if (is->is_tsbsize != first->is_tsbsize ||
+ is->is_dvmabase != first->is_dvmabase) {
+ panic("iommu_init: secondary IOMMU state does not "
+ "match primary");
+ }
}
-#endif
+ STAILQ_INSERT_TAIL(&iommu_insts, is, is_link);
/*
* Initialize streaming buffer, if it is there.
*/
- if (is->is_sb[0] != 0 || is->is_sb[1] != 0) {
+ if (IOMMU_HAS_SB(is)) {
/*
* Find two 64-byte blocks in is_flush that are aligned on
* a 64-byte boundary for flushing.
@@ -274,23 +344,6 @@ iommu_init(char *name, struct iommu_state *is, int tsbsize, u_int32_t iovabase)
* now actually start up the IOMMU
*/
iommu_reset(is);
-
- /*
- * Now all the hardware's working we need to setup dvma resource
- * management.
- */
- printf("DVMA map: %#lx to %#lx\n",
- is->is_dvmabase, is->is_dvmabase +
- (size << (IO_PAGE_SHIFT - IOTTE_SHIFT)) - 1);
-
- is->is_dvma_rman.rm_type = RMAN_ARRAY;
- is->is_dvma_rman.rm_descr = "DVMA Memory";
- if (rman_init(&is->is_dvma_rman) != 0 ||
- rman_manage_region(&is->is_dvma_rman,
- is->is_dvmabase >> IO_PAGE_SHIFT,
- (is->is_dvmabase +
- (size << (IO_PAGE_SHIFT - IOTTE_SHIFT))) >> IO_PAGE_SHIFT))
- panic("iommu_init: can't initialize dvma rman");
}
/*
@@ -303,7 +356,7 @@ iommu_reset(struct iommu_state *is)
{
int i;
- IOMMU_WRITE8(is, is_iommu, IMR_TSB, is->is_ptsb);
+ IOMMU_WRITE8(is, is_iommu, IMR_TSB, iommu_ptsb);
/* Enable IOMMU in diagnostic mode */
IOMMU_WRITE8(is, is_iommu, IMR_CTL, is->is_cr | IOMMUCR_DE);
@@ -335,19 +388,9 @@ iommu_enter(struct iommu_state *is, vm_offset_t va, vm_offset_t pa, int flags)
tte = MAKEIOTTE(pa, !(flags & BUS_DMA_NOWRITE),
!(flags & BUS_DMA_NOCACHE), (flags & BUS_DMA_STREAMING));
- /* Is the streamcache flush really needed? */
- if (is->is_sb[0] != 0 || is->is_sb[1] != 0) {
- iommu_strbuf_flush(is, va);
- iommu_strbuf_flush_done(is);
- }
- DPRINTF(IDB_IOMMU, ("Clearing TSB slot %d for va %p\n",
- (int)IOTSBSLOT(va), (void *)(u_long)va));
- is->is_tsb[IOTSBSLOT(va)] = tte;
- IOMMU_WRITE8(is, is_iommu, IMR_FLUSH, va);
- DPRINTF(IDB_IOMMU, ("iommu_enter: va %lx pa %lx TSB[%lx]@%p=%lx\n",
- va, (long)pa, (u_long)IOTSBSLOT(va),
- (void *)(u_long)&is->is_tsb[IOTSBSLOT(va)],
- (u_long)tte));
+ iommu_strbuf_flush(is, va, 1);
+ IOMMU_SET_TTE(is, va, tte);
+ iommu_tlb_flush(is, va);
#ifdef IOMMU_DIAG
iommu_diag(is, va);
#endif
@@ -356,8 +399,6 @@ iommu_enter(struct iommu_state *is, vm_offset_t va, vm_offset_t pa, int flags)
/*
* iommu_remove: removes mappings created by iommu_enter
* Only demap from IOMMU if flag is set.
- *
- * XXX: this function needs better internal error checking.
*/
void
iommu_remove(struct iommu_state *is, vm_offset_t va, vm_size_t len)
@@ -366,54 +407,18 @@ iommu_remove(struct iommu_state *is, vm_offset_t va, vm_size_t len)
#ifdef IOMMU_DIAG
iommu_diag(is, va);
#endif
-#ifdef DIAGNOSTIC
- if (va < is->is_dvmabase)
- panic("iommu_remove: va 0x%lx not in DVMA space", (u_long)va);
- if ((long)(va + len) < (long)va) {
- panic("iommu_remove: va 0x%lx + len 0x%lx wraps",
- (long)va, (long)len);
- }
- if (len & ~0xfffffff)
- panic("iommu_remove: ridiculous len 0x%lx", (u_long)len);
-#endif
+
+ KASSERT(va >= is->is_dvmabase,
+ ("iommu_remove: va 0x%lx not in DVMA space", (u_long)va));
+ KASSERT(va + len >= va,
+ ("iommu_remove: va 0x%lx + len 0x%lx wraps", (long)va, (long)len));
va = trunc_io_page(va);
- DPRINTF(IDB_IOMMU, ("iommu_remove: va %lx TSB[%lx]@%p\n",
- va, (u_long)IOTSBSLOT(va),
- &is->is_tsb[IOTSBSLOT(va)]));
while (len > 0) {
- DPRINTF(IDB_IOMMU, ("iommu_remove: clearing TSB slot %d for va "
- "%p size %lx\n", (int)IOTSBSLOT(va),
- (void *)(u_long)va, (u_long)len));
- if (is->is_sb[0] != 0 || is->is_sb[1] != 0) {
- DPRINTF(IDB_IOMMU, ("iommu_remove: flushing va %p "
- "TSB[%lx]@%p=%lx, %lu bytes left\n",
- (void *)(u_long)va,
- (long)IOTSBSLOT(va),
- (void *)(u_long)&is->is_tsb[
- IOTSBSLOT(va)],
- (long)(is->is_tsb[IOTSBSLOT(va)]),
- (u_long)len));
- iommu_strbuf_flush(is, va);
- if (len <= IO_PAGE_SIZE)
- iommu_strbuf_flush_done(is);
- DPRINTF(IDB_IOMMU, ("iommu_remove: flushed va %p "
- "TSB[%lx]@%p=%lx, %lu bytes left\n",
- (void *)(u_long)va,
- (long)IOTSBSLOT(va),
- (void *)(u_long)&is->is_tsb[
- IOTSBSLOT(va)],
- (long)(is->is_tsb[IOTSBSLOT(va)]),
- (u_long)len));
- }
-
- if (len <= IO_PAGE_SIZE)
- len = 0;
- else
- len -= IO_PAGE_SIZE;
-
- is->is_tsb[IOTSBSLOT(va)] = 0;
- IOMMU_WRITE8(is, is_iommu, IMR_FLUSH, va);
+ iommu_strbuf_flush(is, va, len <= IO_PAGE_SIZE);
+ len -= ulmin(len, IO_PAGE_SIZE);
+ IOMMU_SET_TTE(is, va, 0);
+ iommu_tlb_flush(is, va);
va += IO_PAGE_SIZE;
}
}
@@ -424,8 +429,8 @@ iommu_decode_fault(struct iommu_state *is, vm_offset_t phys)
bus_addr_t va;
long idx;
- idx = phys - is->is_ptsb;
- if (phys < is->is_ptsb ||
+ idx = phys - iommu_ptsb;
+ if (phys < iommu_ptsb ||
idx > (PAGE_SIZE << is->is_tsbsize))
return;
va = is->is_dvmabase +
@@ -434,12 +439,12 @@ iommu_decode_fault(struct iommu_state *is, vm_offset_t phys)
}
static int
-iommu_strbuf_flush_done(struct iommu_state *is)
+iommu_strbuf_flush_sync(struct iommu_state *is)
{
struct timeval cur, end;
int i;
- if (is->is_sb[0] == 0 && is->is_sb[1] == 0)
+ if (!IOMMU_HAS_SB(is))
return (0);
/*
@@ -470,10 +475,6 @@ iommu_strbuf_flush_done(struct iommu_state *is)
end.tv_usec = 500000;
timevaladd(&end, &cur);
- DPRINTF(IDB_IOMMU, ("iommu_strbuf_flush_done: flush = %lx, %lx at "
- "va = %p pa = %lx now=%lx:%lx\n", (long)*is->is_flushva[0],
- (long)*is->is_flushva[1], is->is_flushva[0],
- (long)is->is_flushpa[0], cur.tv_sec, cur.tv_usec));
while ((!*is->is_flushva[0] || !*is->is_flushva[1]) &&
timevalcmp(&cur, &end, <=))
microtime(&cur);
@@ -484,7 +485,6 @@ iommu_strbuf_flush_done(struct iommu_state *is)
*is->is_flushva[0], *is->is_flushva[1], is->is_flushpa[0]);
}
#endif
- DPRINTF(IDB_IOMMU, ("iommu_strbuf_flush_done: flushed\n"));
return (*is->is_flushva[0] && *is->is_flushva[1]);
}
@@ -507,7 +507,7 @@ iommu_dvma_valloc(bus_dma_tag_t t, struct iommu_state *is, bus_dmamap_t map,
panic("iommu_dvmamap_load: illegal boundary specified");
bound = ulmax(t->boundary >> IO_PAGE_SHIFT, 1);
map->dvmaresv = 0;
- map->res = rman_reserve_resource_bound(&is->is_dvma_rman, 0L,
+ map->res = rman_reserve_resource_bound(&iommu_dvma_rman, 0L,
t->lowaddr, sgsize, bound >> IO_PAGE_SHIFT,
RF_ACTIVE | rman_make_alignment_flags(align), NULL);
if (map->res == NULL)
@@ -629,12 +629,8 @@ iommu_dvmamap_load(bus_dma_tag_t pt, bus_dma_tag_t dt, struct iommu_state *is,
#endif
bus_dmamap_unload(dt, map);
}
- if (buflen > dt->maxsize) {
- DPRINTF(IDB_BUSDMA,
- ("iommu_dvmamap_load(): error %d > %d -- "
- "map size exceeded!\n", (int)buflen, (int)map->buflen));
+ if (buflen > dt->maxsize)
return (EINVAL);
- }
maxsize = IOMMU_SIZE_ROUNDUP(buflen);
if (maxsize > map->dvmaresv) {
@@ -693,11 +689,6 @@ iommu_dvmamap_load(bus_dma_tag_t pt, bus_dma_tag_t dt, struct iommu_state *is,
if (buflen < sgsize)
sgsize = buflen;
- DPRINTF(IDB_BUSDMA,
- ("iommu_dvmamap_load: map %p loading va %p "
- "dva %lx at pa %lx\n",
- map, (void *)vaddr, (long)dvmaddr,
- (long)(curaddr & ~(PAGE_SIZE - 1))));
iommu_enter(is, trunc_io_page(dvmaddr), trunc_io_page(curaddr),
flags);
@@ -739,9 +730,6 @@ iommu_dvmamap_unload(bus_dma_tag_t pt, bus_dma_tag_t dt, struct iommu_state *is,
map, (int)map->buflen, (unsigned long)map->start);
}
- DPRINTF(IDB_BUSDMA,
- ("iommu_dvmamap_unload: map %p removing va %lx size "
- "%lx\n", map, (long)map->start, (long)map->buflen));
iommu_remove(is, map->start, map->buflen);
map->buflen = 0;
iommu_map_insq(map);
@@ -758,62 +746,20 @@ iommu_dvmamap_sync(bus_dma_tag_t pt, bus_dma_tag_t dt, struct iommu_state *is,
va = (vm_offset_t)map->buf;
len = map->buflen;
- if ((op & BUS_DMASYNC_PREREAD) != 0) {
- DPRINTF(IDB_SYNC,
- ("iommu_dvmamap_sync: syncing va %p len %lu "
- "BUS_DMASYNC_PREREAD\n", (void *)(u_long)va, (u_long)len));
+ if ((op & BUS_DMASYNC_PREREAD) != 0)
membar(Sync);
- }
- if ((op & BUS_DMASYNC_POSTREAD) != 0) {
- DPRINTF(IDB_SYNC,
- ("iommu_dvmamap_sync: syncing va %p len %lu "
- "BUS_DMASYNC_POSTREAD\n", (void *)(u_long)va, (u_long)len));
+ if ((op & (BUS_DMASYNC_POSTREAD | BUS_DMASYNC_PREWRITE)) != 0) {
/* if we have a streaming buffer, flush it here first */
- if (is->is_sb[0] != 0 || is->is_sb[1] != 0) {
- while (len > 0) {
- DPRINTF(IDB_BUSDMA,
- ("iommu_dvmamap_sync: flushing va %p, %lu "
- "bytes left\n", (void *)(u_long)va,
- (u_long)len));
- iommu_strbuf_flush(is, va);
- if (len <= IO_PAGE_SIZE) {
- iommu_strbuf_flush_done(is);
- len = 0;
- } else
- len -= IO_PAGE_SIZE;
- va += IO_PAGE_SIZE;
- }
+ while (len > 0) {
+ iommu_strbuf_flush(is, va,
+ len <= IO_PAGE_SIZE);
+ len -= ulmin(len, IO_PAGE_SIZE);
+ va += IO_PAGE_SIZE;
}
}
- if ((op & BUS_DMASYNC_PREWRITE) != 0) {
- DPRINTF(IDB_SYNC,
- ("iommu_dvmamap_sync: syncing va %p len %lu "
- "BUS_DMASYNC_PREWRITE\n", (void *)(u_long)va, (u_long)len));
- /* if we have a streaming buffer, flush it here first */
- if (is->is_sb[0] != 0 || is->is_sb[1] != 0) {
- while (len > 0) {
- DPRINTF(IDB_BUSDMA,
- ("iommu_dvmamap_sync: flushing va %p, %lu "
- "bytes left\n", (void *)(u_long)va,
- (u_long)len));
- iommu_strbuf_flush(is, va);
- if (len <= IO_PAGE_SIZE) {
- iommu_strbuf_flush_done(is);
- len = 0;
- } else
- len -= IO_PAGE_SIZE;
- va += IO_PAGE_SIZE;
- }
- }
+ if ((op & BUS_DMASYNC_PREWRITE) != 0)
membar(Sync);
- }
- if ((op & BUS_DMASYNC_POSTWRITE) != 0) {
- DPRINTF(IDB_SYNC,
- ("iommu_dvmamap_sync: syncing va %p len %lu "
- "BUS_DMASYNC_POSTWRITE\n", (void *)(u_long)va,
- (u_long)len));
- /* Nothing to do */
- }
+ /* BUS_DMASYNC_POSTWRITE does not require any handling. */
}
#ifdef IOMMU_DIAG
@@ -843,8 +789,7 @@ iommu_diag(struct iommu_state *is, vm_offset_t va)
IOMMU_WRITE8(is, is_dva, 0, trunc_io_page(va));
membar(StoreStore | StoreLoad);
- printf("iommu_diag: tte entry %#lx",
- is->is_tsb[IOTSBSLOT(va)]);
+ printf("iommu_diag: tte entry %#lx", iommu_tsb[IOTSBSLOT(va)]);
if (is->is_dtcmp != 0) {
printf(", tag compare register is %#lx\n"
IOMMU_READ8(is, is_dtcmp, 0));
OpenPOWER on IntegriCloud