Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc64/dev - add a note about streaming buffers an...
details: https://anonhg.NetBSD.org/src/rev/8d72bb1dd85a
branches: trunk
changeset: 485347:8d72bb1dd85a
user: mrg <mrg%NetBSD.org@localhost>
date: Tue Apr 25 14:59:38 2000 +0000
description:
- add a note about streaming buffers and US IIi not having them.
- make some debugging messages in iommu_remove() saner and add some more.
- decrement 'len' in the no streaming buffer case, also.
- in iommu_dvmamem_map(), do not enter these mappings into the IOMMU,
only into the CPU (the former is done at _load time).
- make a panic that shouldn't happen a DIAGNOSTIC.
diffstat:
sys/arch/sparc64/dev/iommu.c | 83 +++++++++++++++++++++----------------------
1 files changed, 41 insertions(+), 42 deletions(-)
diffs (180 lines):
diff -r 1d782b26eabb -r 8d72bb1dd85a sys/arch/sparc64/dev/iommu.c
--- a/sys/arch/sparc64/dev/iommu.c Tue Apr 25 14:39:00 2000 +0000
+++ b/sys/arch/sparc64/dev/iommu.c Tue Apr 25 14:59:38 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: iommu.c,v 1.7 2000/04/22 17:06:03 mrg Exp $ */
+/* $NetBSD: iommu.c,v 1.8 2000/04/25 14:59:38 mrg Exp $ */
/*
* Copyright (c) 1999, 2000 Matthew R. Green
@@ -121,6 +121,7 @@
#include <sys/systm.h>
#include <sys/device.h>
#include <vm/vm.h>
+#include <vm/vm_kern.h>
#include <machine/bus.h>
#include <sparc64/sparc64/cache.h>
@@ -206,10 +207,11 @@
#endif
/*
- * Initialize streaming buffer.
+ * Initialize streaming buffer, if it is there.
*/
- (void) pmap_extract(pmap_kernel(), (vaddr_t)&is->is_flush,
- (paddr_t *)&is->is_flushpa);
+ if (is->is_sb)
+ (void)pmap_extract(pmap_kernel(), (vaddr_t)&is->is_flush,
+ (paddr_t *)&is->is_flushpa);
/*
* now actually start up the IOMMU
@@ -224,6 +226,11 @@
M_DEVBUF, 0, 0, EX_NOWAIT);
}
+/*
+ * Streaming buffers don't exist on the UltraSPARC IIi; we should have
+ * detected that already and disabled them. If not, we will notice that
+ * they aren't there when the STRBUF_EN bit does not remain.
+ */
void
iommu_reset(is)
struct iommu_state *is;
@@ -286,6 +293,8 @@
* 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(is, va, len)
@@ -305,7 +314,12 @@
#endif
va = trunc_page(va);
+ DPRINTF(IDB_DVMA, ("iommu_remove: va %lx TSB[%lx]@%p\n",
+ va, IOTSBSLOT(va,is->is_tsbsize),
+ &is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)]));
while (len > 0) {
+ DPRINTF(IDB_DVMA, ("iommu_remove: clearing TSB slot %d for va %p size %lx\n",
+ (int)IOTSBSLOT(va,is->is_tsbsize), va, (u_long)len));
if (is->is_sb) {
DPRINTF(IDB_DVMA, ("iommu_remove: flushing va %p TSB[%lx]@%p=%lx, %lu bytes left\n",
(long)va, (long)IOTSBSLOT(va,is->is_tsbsize),
@@ -323,7 +337,11 @@
(long)&is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)],
(long)(is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)]),
(u_long)len));
+ } else {
+ len -= NBPG;
+ membar_sync(); /* XXX */
}
+
is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)] = 0;
bus_space_write_8(is->is_bustag, &is->is_iommu->iommu_flush, 0, va);
va += NBPG;
@@ -534,7 +552,6 @@
map->dm_mapsize = 0;
map->dm_nsegs = 0;
- /* Unmapping is bus dependent */
s = splhigh();
error = extent_free(is->is_dvmamap, dvmaddr, sgsize, EX_NOWAIT);
splx(s);
@@ -612,7 +629,7 @@
{
DPRINTF(IDB_DVMA, ("iommu_dvmamem_alloc: sz %qx align %qx bound %qx "
- "segp %p flags %d", size, alignment, boundary, segs, flags));
+ "segp %p flags %d\n", size, alignment, boundary, segs, flags));
return (bus_dmamem_alloc(t->_parent, size, alignment, boundary,
segs, nsegs, rsegs, flags));
}
@@ -648,38 +665,21 @@
vaddr_t va;
bus_addr_t addr;
struct pglist *mlist;
- paddr_t curaddr;
- u_long dvmaddr;
- int cbit, s, err;
+ int cbit;
DPRINTF(IDB_DVMA, ("iommu_dvmamem_map: segp %p nsegs %d size %lx\n",
segs, nsegs, size));
/*
- * OK, now map this into the IOMMU
+ * Allocate some space in the kernel map, and then map these pages
+ * into this space.
*/
-
- s = splhigh();
- err = extent_alloc(is->is_dvmamap, segs[0].ds_len, NBPG,
- segs[0]._ds_boundary, EX_NOWAIT, (u_long *)&dvmaddr);
- splx(s);
-
- if (err)
- return (err); /* XXX: cleanup here? */
+ size = round_page(size);
+ va = uvm_km_valloc(kernel_map, size);
+ if (va == 0)
+ return (ENOMEM);
- segs[0].ds_addr = dvmaddr;
- size = segs[0].ds_len;
- mlist = segs[0]._ds_mlist;
-
- /* Map memory into DVMA space */
- for (m = mlist->tqh_first; m != NULL; m = m->pageq.tqe_next) {
- curaddr = VM_PAGE_TO_PHYS(m);
- DPRINTF(IDB_DVMA,
- ("iommu_dvmamem_map: map %p loading va %lx at pa %lx\n",
- (long)m, (long)dvmaddr, (long)(curaddr & ~(NBPG-1))));
- iommu_enter(is, dvmaddr, curaddr, flags);
- dvmaddr += PAGE_SIZE;
- }
+ *kvap = (caddr_t)va;
/*
* digest flags:
@@ -691,22 +691,14 @@
cbit |= PMAP_NC;
/*
- * Now take this and map it into the CPU since it should already
- * be in the IOMMU.
+ * Now take this and map it into the CPU.
*/
-#ifdef DIAGNOSTIC
- if (!segs[0].ds_addr) {
- printf("iommu_dvmamem_map: NULL ds_addr\n");
- Debugger();
- }
-#endif
- *kvap = (caddr_t)va = segs[0].ds_addr;
mlist = segs[0]._ds_mlist;
for (m = mlist->tqh_first; m != NULL; m = m->pageq.tqe_next) {
-
+#ifdef DIAGNOSTIC
if (size == 0)
panic("iommu_dvmamem_map: size botch");
-
+#endif
addr = VM_PAGE_TO_PHYS(m);
DPRINTF(IDB_DVMA, ("iommu_dvmamem_map: "
"mapping va %lx at %qx\n", va, addr | cbit));
@@ -740,4 +732,11 @@
size = round_page(size);
pmap_remove(pmap_kernel(), (vaddr_t)kva, size);
+#if 0
+ /*
+ * XXX ? is this necessary? i think so and i think other
+ * implementations are missing it.
+ */
+ uvm_km_free(kernel_map, (vaddr_t)kva, size);
+#endif
}
Home |
Main Index |
Thread Index |
Old Index