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 use common IOMMU routines.
details: https://anonhg.NetBSD.org/src/rev/1d9ff4e4871b
branches: trunk
changeset: 473466:1d9ff4e4871b
user: mrg <mrg%NetBSD.org@localhost>
date: Sat Jun 05 05:30:43 1999 +0000
description:
use common IOMMU routines.
diffstat:
sys/arch/sparc64/dev/sbus.c | 145 +++++++++++++---------------------------
sys/arch/sparc64/dev/sbusvar.h | 39 ++++------
2 files changed, 62 insertions(+), 122 deletions(-)
diffs (truncated from 377 to 300 lines):
diff -r 798362a772f0 -r 1d9ff4e4871b sys/arch/sparc64/dev/sbus.c
--- a/sys/arch/sparc64/dev/sbus.c Sat Jun 05 05:29:50 1999 +0000
+++ b/sys/arch/sparc64/dev/sbus.c Sat Jun 05 05:30:43 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sbus.c,v 1.16 1999/05/31 00:14:00 eeh Exp $ */
+/* $NetBSD: sbus.c,v 1.17 1999/06/05 05:30:43 mrg Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -95,6 +95,7 @@
#include <machine/bus.h>
#include <sparc64/sparc64/vaddrs.h>
#include <sparc64/dev/iommureg.h>
+#include <sparc64/dev/iommuvar.h>
#include <sparc64/dev/sbusreg.h>
#include <dev/sbus/sbusvar.h>
@@ -291,69 +292,21 @@
if (error)
panic("%s: error getting ranges property", sc->sc_dev.dv_xname);
- /*
- * Setup the iommu.
- *
- * The sun4u iommu is part of the SBUS controller so we will
- * deal with it here. We could try to fake a device node so
- * we can eventually share it with the PCI bus run by psycho,
- * but I don't want to get into that sort of cruft.
- *
- * First we need to allocate a IOTSB. Problem is that the IOMMU
- * can only access the IOTSB by physical address, so all the
- * pages must be contiguous. Luckily, the smallest IOTSB size
- * is one 8K page.
- */
- sc->sc_tsbsize = 0;
- sc->sc_tsb = malloc(NBPG, M_DMAMAP, M_WAITOK);
- sc->sc_ptsb = pmap_extract(pmap_kernel(), (vaddr_t)sc->sc_tsb);
+ /* initailise the IOMMU */
- /* Need to do 64-bit stores */
- bus_space_write_8(sc->sc_bustag, &sc->sc_sysio->sys_iommu.iommu_cr,
- 0, (IOMMUCR_TSB1K|IOMMUCR_8KPG|IOMMUCR_EN));
- bus_space_write_8(sc->sc_bustag, &sc->sc_sysio->sys_iommu.iommu_tsb,
- 0, sc->sc_ptsb);
+ /* punch in our copies */
+ sc->sc_is.is_bustag = sc->sc_bustag;
+ sc->sc_is.is_iommu = &sc->sc_sysio->sys_iommu;
+ sc->sc_is.is_sb = &sc->sc_sysio->sys_strbuf;
#ifdef DEBUG
if (sbusdebug & SDB_DVMA)
- {
- /* Probe the iommu */
- int64_t cr, tsb;
-
- printf("iommu regs at: cr=%lx tsb=%lx flush=%lx\n", &sc->sc_sysio->sys_iommu.iommu_cr,
- &sc->sc_sysio->sys_iommu.iommu_tsb, &sc->sc_sysio->sys_iommu.iommu_flush);
- cr = sc->sc_sysio->sys_iommu.iommu_cr;
- tsb = sc->sc_sysio->sys_iommu.iommu_tsb;
- printf("iommu cr=%lx tsb=%lx\n", (long)cr, (long)tsb);
- printf("sysio base %p phys %p TSB base %p phys %p",
- (long)sc->sc_sysio, (long)pmap_extract(pmap_kernel(), (vaddr_t)sc->sc_sysio),
- (long)sc->sc_tsb, (long)sc->sc_ptsb);
- delay(1000000); /* 1 s */
- }
+ printf("sysio base %p phys %p\n",
+ (long)sc->sc_sysio, (long)pmap_extract(pmap_kernel(), (vaddr_t)sc->sc_sysio));
#endif
- /*
- * Initialize streaming buffer.
- */
- sc->sc_flushpa = pmap_extract(pmap_kernel(), (vaddr_t)&sc->sc_flush);
- bus_space_write_8(sc->sc_bustag, &sc->sc_sysio->sys_strbuf.strbuf_ctl,
- 0, STRBUF_EN); /* Enable diagnostics mode? */
-
- /*
- * Now all the hardware's working we need to allocate a dvma map.
- *
- * The IOMMU address space always ends at 0xffffe000, but the starting
- * address depends on the size of the map. The map size is 1024 * 2 ^
- * sc->sc_tsbsize entries, where each entry is 8 bytes. The start of
- * the map can be calculated by (0xffffe000 << (8 + sc->sc_tsbsize)).
- *
- * Note: the stupid IOMMU ignores the high bits of an address, so a
- * NULL DMA pointer will be translated by the first page of the IOTSB.
- * To trap bugs we'll skip the first entry in the IOTSB.
- */
- sc->sc_dvmamap = extent_create("SBus dvma", /* XXXX should have instance number */
- IOTSB_VSTART(sc->sc_tsbsize) + NBPG, IOTSB_VEND,
- M_DEVBUF, 0, 0, EX_NOWAIT);
+ /* XXX should have instance number */
+ iommu_init("SBus dvma", &sc->sc_is, 0);
/*
* Loop through ROM children, fixing any relative addresses
@@ -569,12 +522,7 @@
}
}
/* Reload iommu regs */
- bus_space_write_8(sc->sc_bustag, &sc->sc_sysio->sys_iommu.iommu_cr,
- 0, (IOMMUCR_TSB1K|IOMMUCR_8KPG|IOMMUCR_EN));
- bus_space_write_8(sc->sc_bustag, &sc->sc_sysio->sys_iommu.iommu_tsb,
- 0, sc->sc_ptsb);
- bus_space_write_8(sc->sc_bustag, &sc->sc_sysio->sys_strbuf.strbuf_ctl,
- 0, STRBUF_EN); /* Enable diagnostics mode? */
+ iommu_reset(&sc->sc_is);
}
/*
@@ -590,7 +538,7 @@
int64_t tte;
#ifdef DIAGNOSTIC
- if (va < sc->sc_dvmabase)
+ if (va < sc->sc_is.is_dvmabase)
panic("sbus_enter: va 0x%lx not in DVMA space",va);
#endif
@@ -598,21 +546,21 @@
!(flags&BUS_DMA_COHERENT));
/* Is the streamcache flush really needed? */
- bus_space_write_8(sc->sc_bustag, &sc->sc_sysio->sys_strbuf.strbuf_pgflush,
+ bus_space_write_8(sc->sc_bustag, &sc->sc_is.is_sb->strbuf_pgflush,
0, va);
sbus_flush(sc);
#ifdef DEBUG
if (sbusdebug & SDB_DVMA)
- printf("Clearing TSB slot %d for va %p\n", (int)IOTSBSLOT(va,sc->sc_tsbsize), va);
+ printf("Clearing TSB slot %d for va %p\n", (int)IOTSBSLOT(va,sc->sc_is.is_tsbsize), va);
#endif
- sc->sc_tsb[IOTSBSLOT(va,sc->sc_tsbsize)] = tte;
+ sc->sc_is.is_tsb[IOTSBSLOT(va,sc->sc_is.is_tsbsize)] = tte;
bus_space_write_8(sc->sc_bustag, &sc->sc_sysio->sys_iommu.iommu_flush,
0, va);
#ifdef DEBUG
if (sbusdebug & SDB_DVMA)
printf("sbus_enter: va %lx pa %lx TSB[%lx]@%p=%lx\n",
- va, (long)pa, IOTSBSLOT(va,sc->sc_tsbsize),
- &sc->sc_tsb[IOTSBSLOT(va,sc->sc_tsbsize)],
+ va, (long)pa, IOTSBSLOT(va,sc->sc_is.is_tsbsize),
+ &sc->sc_is.is_tsb[IOTSBSLOT(va,sc->sc_is.is_tsbsize)],
(long)tte);
#endif
}
@@ -630,7 +578,7 @@
{
#ifdef DIAGNOSTIC
- if (va < sc->sc_dvmabase)
+ if (va < sc->sc_is.is_dvmabase)
panic("sbus_remove: va 0x%lx not in DVMA space", (long)va);
if ((long)(va + len) < (long)va)
panic("sbus_remove: va 0x%lx + len 0x%lx wraps",
@@ -656,12 +604,12 @@
#ifdef DEBUG
if (sbusdebug & SDB_DVMA)
printf("sbus_remove: flushing va %p TSB[%lx]@%p=%lx, %lu bytes left\n",
- (long)va, (long)IOTSBSLOT(va,sc->sc_tsbsize),
- (long)&sc->sc_tsb[IOTSBSLOT(va,sc->sc_tsbsize)],
- (long)(sc->sc_tsb[IOTSBSLOT(va,sc->sc_tsbsize)]),
+ (long)va, (long)IOTSBSLOT(va,sc->sc_is.is_tsbsize),
+ (long)&sc->sc_is.is_tsb[IOTSBSLOT(va,sc->sc_is.is_tsbsize)],
+ (long)(sc->sc_is.is_tsb[IOTSBSLOT(va,sc->sc_is.is_tsbsize)]),
(u_long)len);
#endif
- bus_space_write_8(sc->sc_bustag, &sc->sc_sysio->sys_strbuf.strbuf_pgflush, 0, va);
+ bus_space_write_8(sc->sc_bustag, &sc->sc_is.is_sb->strbuf_pgflush, 0, va);
if (len <= NBPG) {
sbus_flush(sc);
len = 0;
@@ -669,12 +617,12 @@
#ifdef DEBUG
if (sbusdebug & SDB_DVMA)
printf("sbus_remove: flushed va %p TSB[%lx]@%p=%lx, %lu bytes left\n",
- (long)va, (long)IOTSBSLOT(va,sc->sc_tsbsize),
- (long)&sc->sc_tsb[IOTSBSLOT(va,sc->sc_tsbsize)],
- (long)(sc->sc_tsb[IOTSBSLOT(va,sc->sc_tsbsize)]),
+ (long)va, (long)IOTSBSLOT(va,sc->sc_is.is_tsbsize),
+ (long)&sc->sc_is.is_tsb[IOTSBSLOT(va,sc->sc_is.is_tsbsize)],
+ (long)(sc->sc_is.is_tsb[IOTSBSLOT(va,sc->sc_is.is_tsbsize)]),
(u_long)len);
#endif
- sc->sc_tsb[IOTSBSLOT(va,sc->sc_tsbsize)] = 0;
+ sc->sc_is.is_tsb[IOTSBSLOT(va,sc->sc_is.is_tsbsize)] = 0;
bus_space_write_8(sc->sc_bustag, &sc->sc_sysio->sys_iommu.iommu_flush, 0, va);
va += NBPG;
}
@@ -685,6 +633,8 @@
struct sbus_softc *sc;
{
struct timeval cur, flushtimeout;
+ struct iommu_state *is = &sc->sc_is;
+
#define BUMPTIME(t, usec) { \
register volatile struct timeval *tp = (t); \
register long us; \
@@ -696,9 +646,9 @@
} \
}
- sc->sc_flush = 0;
+ is->is_flush = 0;
membar_sync();
- bus_space_write_8(sc->sc_bustag, &sc->sc_sysio->sys_strbuf.strbuf_flushsync, 0, sc->sc_flushpa);
+ bus_space_write_8(sc->sc_bustag, &is->is_sb->strbuf_flushsync, 0, is->is_flushpa);
membar_sync();
microtime(&flushtimeout);
@@ -706,23 +656,22 @@
BUMPTIME(&flushtimeout, 500000); /* 1/2 sec */
#ifdef DEBUG
- if (sbusdebug & SDB_DVMA) {
- printf("sbus_flush: flush = %lx at va = %lx pa = %lx now=%lx until = %lx:%lx\n",
- (long)sc->sc_flush, (long)&sc->sc_flush,
- (long)sc->sc_flushpa, cur.tv_sec, cur.tv_usec,
+ if (sbusdebug & SDB_DVMA)
+ printf("sbus_flush: flush = %lx at va = %lx pa = %lx now=%lx:%lx until = %lx:%lx\n",
+ (long)is->is_flush, (long)&is->is_flush,
+ (long)is->is_flushpa, cur.tv_sec, cur.tv_usec,
flushtimeout.tv_sec, flushtimeout.tv_usec);
- }
#endif
/* Bypass non-coherent D$ */
- while( !ldxa(sc->sc_flushpa, ASI_PHYS_CACHED) &&
+ while (!ldxa(is->is_flushpa, ASI_PHYS_CACHED) &&
((cur.tv_sec <= flushtimeout.tv_sec) &&
(cur.tv_usec <= flushtimeout.tv_usec)))
microtime(&cur);
#ifdef DIAGNOSTIC
- if( !sc->sc_flush ) {
- printf("sbus_flush: flush timeout %p at %p\n", (long)sc->sc_flush,
- (long)sc->sc_flushpa); /* panic? */
+ if (!is->is_flush) {
+ printf("sbus_flush: flush timeout %p at %p\n", (long)is->is_flush,
+ (long)is->is_flushpa); /* panic? */
#ifdef DDB
Debugger();
#endif
@@ -732,7 +681,7 @@
if (sbusdebug & SDB_DVMA)
printf("sbus_flush: flushed\n");
#endif
- return (sc->sc_flush);
+ return (is->is_flush);
}
/*
@@ -1022,7 +971,7 @@
*/
s = splhigh();
- err = extent_alloc(sc->sc_dvmamap, sgsize, NBPG,
+ err = extent_alloc(sc->sc_is.is_dvmamap, sgsize, NBPG,
map->_dm_boundary, EX_NOWAIT, (u_long *)&dvmaddr);
splx(s);
@@ -1121,7 +1070,7 @@
/* Unmapping is bus dependent */
s = splhigh();
- error = extent_free(sc->sc_dvmamap, dvmaddr, sgsize, EX_NOWAIT);
+ error = extent_free(sc->sc_is.is_dvmamap, dvmaddr, sgsize, EX_NOWAIT);
splx(s);
if (error != 0)
printf("warning: %ld of DVMA space lost\n", (long)sgsize);
@@ -1185,7 +1134,7 @@
printf("sbus_dmamap_sync: flushing va %p, %lu bytes left\n",
(long)va, (u_long)len);
#endif
- bus_space_write_8(sc->sc_bustag, &sc->sc_sysio->sys_strbuf.strbuf_pgflush, 0, va);
+ bus_space_write_8(sc->sc_bustag, &sc->sc_is.is_sb->strbuf_pgflush, 0, va);
if (len <= NBPG) {
sbus_flush(sc);
len = 0;
@@ -1241,10 +1190,10 @@
/*
* Allocate a DVMA mapping for our new memory.
*/
- for (n=0; n<*rsegs; n++) {
+ for (n = 0; n < *rsegs; n++) {
#if 1
s = splhigh();
- if (extent_alloc(sc->sc_dvmamap, segs[0].ds_len, alignment,
+ if (extent_alloc(sc->sc_is.is_dvmamap, segs[0].ds_len, alignment,
boundary, EX_NOWAIT, (u_long *)&dvmaddr)) {
splx(s);
/* Free what we got and exit */
@@ -1297,7 +1246,7 @@
sbus_remove(sc, addr, len);
#if 1
s = splhigh();
- error = extent_free(sc->sc_dvmamap, addr, len, EX_NOWAIT);
+ error = extent_free(sc->sc_is.is_dvmamap, addr, len, EX_NOWAIT);
splx(s);
if (error != 0)
printf("warning: %ld of DVMA space lost\n", (long)len);
Home |
Main Index |
Thread Index |
Old Index