Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sparc64 Move the DVMA mapin/mapout functions from t...



details:   https://anonhg.NetBSD.org/src/rev/49ea0d765e84
branches:  trunk
changeset: 473802:49ea0d765e84
user:      eeh <eeh%NetBSD.org@localhost>
date:      Sun Jun 20 00:51:29 1999 +0000

description:
Move the DVMA mapin/mapout functions from the SBus driver to the iommu driver.

diffstat:

 sys/arch/sparc64/dev/iommu.c    |  209 +++++++++++++++++++++++++++++++++------
 sys/arch/sparc64/dev/iommuvar.h |    5 +-
 sys/arch/sparc64/dev/sbus.c     |  184 +---------------------------------
 sys/arch/sparc64/include/cpu.h  |    5 +-
 4 files changed, 185 insertions(+), 218 deletions(-)

diffs (truncated from 541 to 300 lines):

diff -r 04db33fc4b6c -r 49ea0d765e84 sys/arch/sparc64/dev/iommu.c
--- a/sys/arch/sparc64/dev/iommu.c      Sun Jun 20 00:50:08 1999 +0000
+++ b/sys/arch/sparc64/dev/iommu.c      Sun Jun 20 00:51:29 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: iommu.c,v 1.1 1999/06/04 13:48:48 mrg Exp $    */
+/*     $NetBSD: iommu.c,v 1.2 1999/06/20 00:51:29 eeh Exp $    */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -136,31 +136,18 @@
        
        /* we want 8K pages */
        is->is_cr = IOMMUCR_8KPG | IOMMUCR_EN;
-
-       /* set the tsbsize and get the dvmabase */
-       switch (tsbsize) {
-       case 0:
-               is->is_dvmabase = 0x1fffffff;
-               is->is_cr |= IOMMUCR_TSB1K;
-               break;
-
-#if 0
-       /* XXX are these right? got the values from the linux driver */
-       case 1:
-               is->is_dvmabase = 0x3fffffff;
-               is->is_cr |= IOMMUCR_TSB2K;
-               break;
-
-       case 2:
-               is->is_dvmabase = 0x7fffffff;
-               is->is_cr |= IOMMUCR_TSB4K;
-               break;
-#endif
-
-       default:
-               panic("unknown tsbsize, fix me");
-       }
-
+       /*
+        *
+        * 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 ^
+        * is->is_tsbsize entries, where each entry is 8 bytes.  The start of
+        * the map can be calculated by (0xffffe000 << (8 + is->is_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.
+        */
+       is->is_dvmabase = IOTSB_VSTART(is->is_tsbsize) + NBPG;
        is->is_tsbsize = tsbsize;
        is->is_tsb = malloc(NBPG, M_DMAMAP, M_WAITOK);  /* XXX */
        is->is_ptsb = pmap_extract(pmap_kernel(), (vaddr_t)is->is_tsb);
@@ -194,18 +181,9 @@
 
        /*
         * 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 ^
-        * is->is_tsbsize entries, where each entry is 8 bytes.  The start of
-        * the map can be calculated by (0xffffe000 << (8 + is->is_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.
         */
        is->is_dvmamap = extent_create(name,
-                                      IOTSB_VSTART(is->is_tsbsize) + NBPG, IOTSB_VEND,
+                                      is->is_dvmabase, IOTSB_VEND,
                                       M_DEVBUF, 0, 0, EX_NOWAIT);
 }
 
@@ -220,3 +198,162 @@
        /* Enable diagnostics mode? */
        bus_space_write_8(is->is_bustag, &is->is_sb->strbuf_ctl, 0, STRBUF_EN);
 }
+
+/*
+ * Here are the iommu control routines. 
+ */
+void
+iommu_enter(is, va, pa, flags)
+       struct iommu_state *is;
+       vaddr_t va;
+       int64_t pa;
+       int flags;
+{
+       int64_t tte;
+
+#ifdef DIAGNOSTIC
+       if (va < is->is_dvmabase)
+               panic("sbus_enter: va 0x%lx not in DVMA space",va);
+#endif
+
+       tte = MAKEIOTTE(pa, !(flags&BUS_DMA_NOWRITE), !(flags&BUS_DMA_NOCACHE), 
+                       !(flags&BUS_DMA_COHERENT));
+       
+       /* Is the streamcache flush really needed? */
+       bus_space_write_8(is->is_bustag, &is->is_sb->strbuf_pgflush,
+                         0, va);
+       iommu_flush(is);
+#ifdef DEBUG
+       if (iommudebug & IDB_DVMA)
+               printf("Clearing TSB slot %d for va %p\n", 
+                      (int)IOTSBSLOT(va,is->is_tsbsize), va);
+#endif
+       is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)] = tte;
+       bus_space_write_8(is->is_bustag, &is->is_iommu->iommu_flush, 
+                         0, va);
+#ifdef DEBUG
+       if (iommudebug & IDB_DVMA)
+               printf("sbus_enter: va %lx pa %lx TSB[%lx]@%p=%lx\n",
+                      va, (long)pa, IOTSBSLOT(va,is->is_tsbsize), 
+                      &is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)],
+                      (long)tte);
+#endif
+}
+
+/*
+ * iommu_remove: removes mappings created by iommu_enter
+ *
+ * Only demap from IOMMU if flag is set.
+ */
+void
+iommu_remove(is, va, len)
+       struct iommu_state *is;
+       vaddr_t va;
+       size_t len;
+{
+
+#ifdef DIAGNOSTIC
+       if (va < 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", 
+                     (long) va, (long) len);
+       if (len & ~0xfffffff) 
+               panic("sbus_remove: rediculous len 0x%lx", (long)len);
+#endif
+
+       va = trunc_page(va);
+       while (len > 0) {
+
+               /*
+                * Streaming buffer flushes:
+                * 
+                *   1 Tell strbuf to flush by storing va to strbuf_pgflush
+                * If we're not on a cache line boundary (64-bits):
+                *   2 Store 0 in flag
+                *   3 Store pointer to flag in flushsync
+                *   4 wait till flushsync becomes 0x1
+                *
+                * If it takes more than .5 sec, something went wrong.
+                */
+#ifdef DEBUG
+               if (iommudebug & IDB_DVMA)
+                       printf("sbus_remove: flushing va %p TSB[%lx]@%p=%lx, %lu bytes left\n",                
+                              (long)va, (long)IOTSBSLOT(va,is->is_tsbsize), 
+                              (long)&is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)],
+                              (long)(is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)]), 
+                              (u_long)len);
+#endif
+               bus_space_write_8(is->is_bustag, &is->is_sb->strbuf_pgflush, 0, va);
+               if (len <= NBPG) {
+                       iommu_flush(is);
+                       len = 0;
+               } else len -= NBPG;
+#ifdef DEBUG
+               if (iommudebug & IDB_DVMA)
+                       printf("sbus_remove: flushed va %p TSB[%lx]@%p=%lx, %lu bytes left\n",         
+                              (long)va, (long)IOTSBSLOT(va,is->is_tsbsize), 
+                              (long)&is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)],
+                              (long)(is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)]), 
+                              (u_long)len);
+#endif
+               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;
+       }
+}
+
+int 
+iommu_flush(is)
+       struct iommu_state *is;
+{
+       struct timeval cur, flushtimeout;
+
+#define BUMPTIME(t, usec) { \
+       register volatile struct timeval *tp = (t); \
+       register long us; \
+ \
+       tp->tv_usec = us = tp->tv_usec + (usec); \
+       if (us >= 1000000) { \
+               tp->tv_usec = us - 1000000; \
+               tp->tv_sec++; \
+       } \
+}
+
+       is->is_flush = 0;
+       membar_sync();
+       bus_space_write_8(is->is_bustag, &is->is_sb->strbuf_flushsync, 0, is->is_flushpa);
+       membar_sync();
+
+       microtime(&flushtimeout); 
+       cur = flushtimeout;
+       BUMPTIME(&flushtimeout, 500000); /* 1/2 sec */
+       
+#ifdef DEBUG
+       if (iommudebug & IDB_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(is->is_flushpa, ASI_PHYS_CACHED) && 
+              ((cur.tv_sec <= flushtimeout.tv_sec) && 
+               (cur.tv_usec <= flushtimeout.tv_usec)))
+               microtime(&cur);
+
+#ifdef DIAGNOSTIC
+       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
+       }
+#endif
+#ifdef DEBUG
+       if (iommudebug & IDB_DVMA)
+               printf("sbus_flush: flushed\n");
+#endif
+       return (is->is_flush);
+}
diff -r 04db33fc4b6c -r 49ea0d765e84 sys/arch/sparc64/dev/iommuvar.h
--- a/sys/arch/sparc64/dev/iommuvar.h   Sun Jun 20 00:50:08 1999 +0000
+++ b/sys/arch/sparc64/dev/iommuvar.h   Sun Jun 20 00:51:29 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: iommuvar.h,v 1.1 1999/06/04 13:48:48 mrg Exp $ */
+/*     $NetBSD: iommuvar.h,v 1.2 1999/06/20 00:51:29 eeh Exp $ */
 
 /*
  * Copyright (c) 1999 Matthew R. Green
@@ -55,5 +55,8 @@
 /* interfaces for PCI/SBUS code */
 void   iommu_init __P((char *, struct iommu_state *, int));
 void   iommu_reset __P((struct iommu_state *));
+void    iommu_enter __P((struct iommu_state *, vaddr_t, int64_t, int));
+void    iommu_remove __P((struct iommu_state *, vaddr_t, size_t));
+int    iommu_flush __P((struct iommu_state *));
 
 #endif /* _SPARC64_DEV_IOMMUVAR_H_ */
diff -r 04db33fc4b6c -r 49ea0d765e84 sys/arch/sparc64/dev/sbus.c
--- a/sys/arch/sparc64/dev/sbus.c       Sun Jun 20 00:50:08 1999 +0000
+++ b/sys/arch/sparc64/dev/sbus.c       Sun Jun 20 00:51:29 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sbus.c,v 1.18 1999/06/07 05:28:03 eeh Exp $ */
+/*     $NetBSD: sbus.c,v 1.19 1999/06/20 00:51:30 eeh Exp $ */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -135,7 +135,6 @@
 #endif
 
 void sbusreset __P((int));
-int sbus_flush __P((struct sbus_softc *));
 
 static bus_space_tag_t sbus_alloc_bustag __P((struct sbus_softc *));
 static bus_dma_tag_t sbus_alloc_dmatag __P((struct sbus_softc *));
@@ -173,8 +172,6 @@
 /*
  * DVMA routines
  */
-void sbus_enter __P((struct sbus_softc *, vaddr_t, int64_t, int));
-void sbus_remove __P((struct sbus_softc *, vaddr_t, size_t));
 int sbus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
                          bus_size_t, struct proc *, int));
 void sbus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
@@ -550,165 +547,6 @@
 }
 
 /*
- * Here are the iommu control routines. 
- */
-void
-sbus_enter(sc, va, pa, flags)
-       struct sbus_softc *sc;
-       vaddr_t va;
-       int64_t pa;
-       int flags;
-{
-       int64_t tte;
-
-#ifdef DIAGNOSTIC
-       if (va < sc->sc_is.is_dvmabase)
-               panic("sbus_enter: va 0x%lx not in DVMA space",va);
-#endif
-



Home | Main Index | Thread Index | Old Index