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 Manage both streaming caches on psycho/...



details:   https://anonhg.NetBSD.org/src/rev/432c32547c8e
branches:  trunk
changeset: 515896:432c32547c8e
user:      eeh <eeh%NetBSD.org@localhost>
date:      Sun Oct 07 20:30:40 2001 +0000

description:
Manage both streaming caches on psycho/psycho+.

diffstat:

 sys/arch/sparc64/dev/iommu.c    |  123 ++++++++++++++++++++++++++-------------
 sys/arch/sparc64/dev/iommuvar.h |    6 +-
 sys/arch/sparc64/dev/psycho.c   |   30 +++++----
 sys/arch/sparc64/dev/sbus.c     |    5 +-
 4 files changed, 103 insertions(+), 61 deletions(-)

diffs (truncated from 322 to 300 lines):

diff -r 3fcf4b37f3e6 -r 432c32547c8e sys/arch/sparc64/dev/iommu.c
--- a/sys/arch/sparc64/dev/iommu.c      Sun Oct 07 16:28:39 2001 +0000
+++ b/sys/arch/sparc64/dev/iommu.c      Sun Oct 07 20:30:40 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: iommu.c,v 1.41 2001/09/28 11:59:53 chs Exp $   */
+/*     $NetBSD: iommu.c,v 1.42 2001/10/07 20:30:40 eeh Exp $   */
 
 /*
  * Copyright (c) 1999, 2000 Matthew R. Green
@@ -142,8 +142,19 @@
 #define DPRINTF(l, s)
 #endif
 
-#define iommu_strbuf_flush(i,v) bus_space_write_8((i)->is_bustag, \
-       (bus_space_handle_t)(u_long)&(i)->is_sb->strbuf_pgflush, 0, (v))
+#define iommu_strbuf_flush(i,v) do {                           \
+       if ((i)->is_sb[0])                                      \
+               bus_space_write_8((i)->is_bustag,               \
+                       (bus_space_handle_t)(u_long)            \
+                       &(i)->is_sb[0]->strbuf_pgflush,         \
+                       0, (v));                                \
+       if ((i)->is_sb[1])                                      \
+               bus_space_write_8((i)->is_bustag,               \
+                       (bus_space_handle_t)(u_long)            \
+                       &(i)->is_sb[1]->strbuf_pgflush,         \
+                       0, (v));                                \
+       } while (0)
+
 static int iommu_strbuf_flush_done __P((struct iommu_state *));
 
 /*
@@ -231,8 +242,8 @@
        /*
         * Initialize streaming buffer, if it is there.
         */
-       if (is->is_sb)
-               (void)pmap_extract(pmap_kernel(), (vaddr_t)&is->is_flush,
+       if (is->is_sb[0] || is->is_sb[1])
+               (void)pmap_extract(pmap_kernel(), (vaddr_t)&is->is_flush[0],
                    (paddr_t *)&is->is_flushpa);
 
        /*
@@ -263,27 +274,40 @@
 
        /* Need to do 64-bit stores */
        bus_space_write_8(is->is_bustag, 
-                         (bus_space_handle_t)(u_long)&is->is_iommu->iommu_tsb, 
-                         0, is->is_ptsb);
+               (bus_space_handle_t)(u_long)&is->is_iommu->iommu_tsb,
+               0, is->is_ptsb);
        /* Enable IOMMU in diagnostic mode */
        bus_space_write_8(is->is_bustag, 
-                         (bus_space_handle_t)(u_long)&is->is_iommu->iommu_cr, 0, 
-                         is->is_cr|IOMMUCR_DE);
+               (bus_space_handle_t)(u_long)&is->is_iommu->iommu_cr,
+               0, is->is_cr|IOMMUCR_DE);
+
+       if (is->is_sb[0]) {
 
-
-       if (!is->is_sb)
-               return;
+               /* Enable diagnostics mode? */
+               bus_space_write_8(is->is_bustag,
+                       (bus_space_handle_t)(u_long)&is->is_sb[0]->strbuf_ctl,
+                       0, STRBUF_EN);
 
-       /* Enable diagnostics mode? */
-       bus_space_write_8(is->is_bustag, 
-                         (bus_space_handle_t)(u_long)&is->is_sb->strbuf_ctl,
-                         0, STRBUF_EN);
+               /* No streaming buffers? Disable them */
+               if (bus_space_read_8(is->is_bustag,
+                       (bus_space_handle_t)(u_long)&is->is_sb[0]->strbuf_ctl,
+                       0) == 0)
+               is->is_sb[0] = 0;
+       }
+
+       if (is->is_sb[1]) {
 
-       /* No streaming buffers? Disable them */
-       if (bus_space_read_8(is->is_bustag,
-                            (bus_space_handle_t)(u_long)&is->is_sb->strbuf_ctl, 
-                            0) == 0)
-               is->is_sb = 0;
+               /* Enable diagnostics mode? */
+               bus_space_write_8(is->is_bustag,
+                       (bus_space_handle_t)(u_long)&is->is_sb[1]->strbuf_ctl,
+                       0, STRBUF_EN);
+
+               /* No streaming buffers? Disable them */
+               if (bus_space_read_8(is->is_bustag,
+                       (bus_space_handle_t)(u_long)&is->is_sb[1]->strbuf_ctl,
+                       0) == 0)
+               is->is_sb[1] = 0;
+       }
 }
 
 /*
@@ -307,7 +331,7 @@
                        (flags&BUS_DMA_STREAMING));
        
        /* Is the streamcache flush really needed? */
-       if (is->is_sb) {
+       if (is->is_sb[0] || is->is_sb[1]) {
                iommu_strbuf_flush(is, va);
                iommu_strbuf_flush_done(is);
        }
@@ -372,7 +396,7 @@
        while (len > 0) {
                DPRINTF(IDB_IOMMU, ("iommu_remove: clearing TSB slot %d for va %p size %lx\n", 
                    (int)IOTSBSLOT(va,is->is_tsbsize), (void *)(u_long)va, (u_long)len));
-               if (is->is_sb) {
+               if (is->is_sb[0] || is->is_sb[0]) {
                        DPRINTF(IDB_IOMMU, ("iommu_remove: flushing va %p TSB[%lx]@%p=%lx, %lu bytes left\n",          
                               (void *)(u_long)va, (long)IOTSBSLOT(va,is->is_tsbsize), 
                               (void *)(u_long)&is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)],
@@ -417,7 +441,7 @@
        } \
 }
 
-       if (!is->is_sb)
+       if (!is->is_sb[0] && !is->is_sb[1])
                return (0);
                                
        /*
@@ -433,38 +457,51 @@
         * went wrong.
         */
 
-       is->is_flush = 0;
-       membar_sync();  /* #StoreStore is prolly enuf. */
-       bus_space_write_8(is->is_bustag, (bus_space_handle_t)(u_long)
-                         &is->is_sb->strbuf_flushsync, 0, is->is_flushpa);
-       membar_sync();  /* Prolly not needed at all. */
+       is->is_flush[0] = 1;
+       is->is_flush[1] = 1;
+       if (is->is_sb[0]) {
+               is->is_flush[0] = 0;
+               bus_space_write_8(is->is_bustag, (bus_space_handle_t)(u_long)
+                       &is->is_sb[0]->strbuf_flushsync, 0, is->is_flushpa);
+       }
+       if (is->is_sb[1]) {
+               is->is_flush[0] = 1;
+               bus_space_write_8(is->is_bustag, (bus_space_handle_t)(u_long)
+                       &is->is_sb[1]->strbuf_flushsync, 0, is->is_flushpa + 8);
+       }
 
        microtime(&flushtimeout); 
        cur = flushtimeout;
        BUMPTIME(&flushtimeout, 500000); /* 1/2 sec */
        
-       DPRINTF(IDB_IOMMU, ("iommu_strbuf_flush_done: 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));
+       DPRINTF(IDB_IOMMU, ("iommu_strbuf_flush_done: flush = %lx,%lx "
+               "at va = %lx pa = %lx now=%lx:%lx until = %lx:%lx\n",
+               (long)is->is_flush[0], (long)is->is_flush[1],
+               (long)&is->is_flush[0], (long)is->is_flushpa, 
+               cur.tv_sec, cur.tv_usec,
+               flushtimeout.tv_sec, flushtimeout.tv_usec));
+
        /* Bypass non-coherent D$ */
-       while (!ldxa(is->is_flushpa, ASI_PHYS_CACHED) && 
-              ((cur.tv_sec <= flushtimeout.tv_sec) && 
-               (cur.tv_usec <= flushtimeout.tv_usec)))
+       while ((!ldxa(is->is_flushpa, ASI_PHYS_CACHED) ||
+               !ldxa(is->is_flushpa + 8, ASI_PHYS_CACHED)) &&
+               ((cur.tv_sec <= flushtimeout.tv_sec) &&
+                       (cur.tv_usec <= flushtimeout.tv_usec)))
                microtime(&cur);
 
 #ifdef DIAGNOSTIC
-       if (!ldxa(is->is_flushpa, ASI_PHYS_CACHED)) {
-               printf("iommu_strbuf_flush_done: flush timeout %p at %p\n",
-                   (void *)(u_long)is->is_flush, 
-                   (void *)(u_long)is->is_flushpa); /* panic? */
+       if ((!ldxa(is->is_flushpa, ASI_PHYS_CACHED) ||
+               !ldxa(is->is_flushpa + 8, ASI_PHYS_CACHED)) {
+               printf("iommu_strbuf_flush_done: flush timeout %p,%p at %p\n",
+                       (void *)(u_long)is->is_flush[0],
+                       (void *)(u_long)is->is_flush[1],
+                       (void *)(u_long)is->is_flushpa); /* panic? */
 #ifdef DDB
                Debugger();
 #endif
        }
 #endif
        DPRINTF(IDB_IOMMU, ("iommu_strbuf_flush_done: flushed\n"));
-       return (is->is_flush);
+       return (is->is_flush[0] && is->is_flush[1]);
 }
 
 /*
@@ -938,7 +975,7 @@
                    ("iommu_dvmamap_sync: syncing va %p len %lu "
                     "BUS_DMASYNC_POSTREAD\n", (void *)(u_long)va, (u_long)len));
                /* if we have a streaming buffer, flush it here first */
-               if (is->is_sb)
+               if (is->is_sb[0] || is->is_sb[1])
                        while (len > 0) {
                                DPRINTF(IDB_BUSDMA,
                                    ("iommu_dvmamap_sync: flushing va %p, %lu "
@@ -957,7 +994,7 @@
                    ("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)
+               if (is->is_sb[0] || is->is_sb[1])
                        while (len > 0) {
                                DPRINTF(IDB_BUSDMA,
                                    ("iommu_dvmamap_sync: flushing va %p, %lu "
diff -r 3fcf4b37f3e6 -r 432c32547c8e sys/arch/sparc64/dev/iommuvar.h
--- a/sys/arch/sparc64/dev/iommuvar.h   Sun Oct 07 16:28:39 2001 +0000
+++ b/sys/arch/sparc64/dev/iommuvar.h   Sun Oct 07 20:30:40 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: iommuvar.h,v 1.8 2001/09/15 06:55:50 eeh Exp $ */
+/*     $NetBSD: iommuvar.h,v 1.9 2001/10/07 20:30:41 eeh Exp $ */
 
 /*
  * Copyright (c) 1999 Matthew R. Green
@@ -44,12 +44,12 @@
 
        paddr_t                 is_flushpa;     /* used to flush the SBUS */
        /* Needs to be volatile or egcs optimizes away loads */
-       volatile int64_t        is_flush;
+       volatile int64_t        is_flush[2];
 
        /* copies of our parents state, to allow us to be self contained */
        bus_space_tag_t         is_bustag;      /* our bus tag */
        struct iommureg         *is_iommu;      /* IOMMU registers */
-       struct iommu_strbuf     *is_sb;         /* streaming buffer */
+       struct iommu_strbuf     *is_sb[2];      /* streaming buffer(s) */
 };
 
 /* interfaces for PCI/SBUS code */
diff -r 3fcf4b37f3e6 -r 432c32547c8e sys/arch/sparc64/dev/psycho.c
--- a/sys/arch/sparc64/dev/psycho.c     Sun Oct 07 16:28:39 2001 +0000
+++ b/sys/arch/sparc64/dev/psycho.c     Sun Oct 07 20:30:40 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: psycho.c,v 1.38 2001/09/26 20:53:11 eeh Exp $  */
+/*     $NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp $  */
 
 /*
  * Copyright (c) 1999, 2000 Matthew R. Green
@@ -455,6 +455,17 @@
                 *
                 * For the moment, 32KB should be more than enough.
                 */
+               sc->sc_is = malloc(sizeof(struct iommu_state),
+                       M_DEVBUF, M_NOWAIT);
+               if (sc->sc_is == NULL)
+                       panic("psycho_attach: malloc iommu_state");
+
+
+               sc->sc_is->is_sb[0] = 0;
+               sc->sc_is->is_sb[1] = 0;
+               if (PROM_getproplen(sc->sc_node, "no-streaming-cache") >= 0)
+                       sc->sc_is->is_sb[0] = &pci_ctl->pci_strbuf;
+
                psycho_iommu_init(sc, 2);
 
                sc->sc_configtag = psycho_alloc_config_tag(sc->sc_psycho_this);
@@ -472,6 +483,10 @@
                sc->sc_is = osc->sc_is;
                sc->sc_configtag = osc->sc_configtag;
                sc->sc_configaddr = osc->sc_configaddr;
+
+               if (PROM_getproplen(sc->sc_node, "no-streaming-cache") >= 0)
+                       sc->sc_is->is_sb[1] = &pci_ctl->pci_strbuf;
+               iommu_reset(sc->sc_is);
        }
 
        /*
@@ -685,26 +700,15 @@
        int tsbsize;
 {
        char *name;
-       struct iommu_state *is;
+       struct iommu_state *is = sc->sc_is;
        u_int32_t iobase = -1;
        int *vdma = NULL;
        int nitem;
 
-       is = malloc(sizeof(struct iommu_state), M_DEVBUF, M_NOWAIT);
-       if (is == NULL)
-               panic("psycho_iommu_init: malloc is");
-
-       sc->sc_is = is;
-
        /* punch in our copies */
        is->is_bustag = sc->sc_bustag;
        is->is_iommu = &sc->sc_regs->psy_iommu;
 
-       if (PROM_getproplen(sc->sc_node, "no-streaming-cache") < 0)
-               is->is_sb = 0;
-       else
-               is->is_sb = &sc->sc_regs->psy_iommu_strbuf;
-



Home | Main Index | Thread Index | Old Index