Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/sparc64 support UltraSPARC-IIe STICK counter as tim...



details:   https://anonhg.NetBSD.org/src/rev/ca12beaa0af3
branches:  trunk
changeset: 789496:ca12beaa0af3
user:      macallan <macallan%NetBSD.org@localhost>
date:      Tue Aug 20 19:19:23 2013 +0000

description:
support UltraSPARC-IIe STICK counter as time base

diffstat:

 sys/arch/sparc64/dev/psycho.c    |  77 +++++++++++++++++++++++++++++++++++-
 sys/arch/sparc64/dev/psychoreg.h |  23 ++++++----
 sys/arch/sparc64/dev/psychovar.h |   7 ++-
 sys/arch/sparc64/include/cpu.h   |   5 +-
 sys/arch/sparc64/sparc64/clock.c |  83 +++++++++++++++++++++++++++++++++++++++-
 sys/arch/sparc64/sparc64/cpu.c   |   9 +--
 6 files changed, 183 insertions(+), 21 deletions(-)

diffs (truncated from 422 to 300 lines):

diff -r d8f153e20a70 -r ca12beaa0af3 sys/arch/sparc64/dev/psycho.c
--- a/sys/arch/sparc64/dev/psycho.c     Tue Aug 20 18:06:03 2013 +0000
+++ b/sys/arch/sparc64/dev/psycho.c     Tue Aug 20 19:19:23 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: psycho.c,v 1.113 2013/06/21 20:09:58 nakayama Exp $    */
+/*     $NetBSD: psycho.c,v 1.114 2013/08/20 19:19:23 macallan Exp $    */
 
 /*
  * Copyright (c) 1999, 2000 Matthew R. Green
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: psycho.c,v 1.113 2013/06/21 20:09:58 nakayama Exp $");
+__KERNEL_RCSID(0, "$NetBSD: psycho.c,v 1.114 2013/08/20 19:19:23 macallan Exp $");
 
 #include "opt_ddb.h"
 
@@ -70,6 +70,7 @@
 #define PDB_INTR       0x04
 #define PDB_INTMAP     0x08
 #define PDB_CONF       0x10
+#define PDB_STICK      0x20
 int psycho_debug = 0x0;
 #define DPRINTF(l, s)   do { if (psycho_debug & l) printf s; } while (0)
 #else
@@ -220,6 +221,8 @@
        { NULL, 0 }
 };
 
+struct psycho_softc *psycho0 = NULL;
+
 static int
 psycho_match(device_t parent, cfdata_t match, void *aux)
 {
@@ -307,7 +310,11 @@
        sc->sc_node = ma->ma_node;
        sc->sc_bustag = ma->ma_bustag;
        sc->sc_dmatag = ma->ma_dmatag;
+       sc->sc_last_stick = 0;
 
+       if (psycho0 == NULL)
+               psycho0 = sc;
+       DPRINTF(PDB_STICK, ("init psycho0 %lx\n", (long)sc));
        /*
         * Identify the device.
         */
@@ -375,6 +382,7 @@
                                ma->ma_address[0], &sc->sc_bh);
                        sc->sc_regs = (struct psychoreg *)
                                bus_space_vaddr(sc->sc_bustag, sc->sc_bh);
+
                        bus_space_subregion(sc->sc_bustag, sc->sc_bh,
                                offsetof(struct psychoreg,  psy_pcictl),
                                sizeof(struct pci_ctl), &pci_ctl);
@@ -397,7 +405,6 @@
                                ma->ma_nreg);
        }
 
-
        csr = bus_space_read_8(sc->sc_bustag, sc->sc_bh,
                offsetof(struct psychoreg, psy_csr));
        sc->sc_ign = 0x7c0; /* APB IGN is always 0x7c */
@@ -1510,3 +1517,67 @@
        }
        bus_dmamap_sync(t->_parent, map, offset, len, ops);
 }
+
+/* US-IIe STICK support */
+
+long
+psycho_getstick(void)
+{
+       long foo;
+
+       foo = bus_space_read_8(psycho0->sc_bustag, psycho0->sc_bh,
+           STICK_CNT_LOW) |
+           (bus_space_read_8(psycho0->sc_bustag, psycho0->sc_bh,
+           STICK_CNT_HIGH) & 0x7fffffff) << 32;
+       return foo;
+}
+
+void
+psycho_setstick(long cnt)
+{
+
+       /*
+        * looks like we can't actually write the STICK counter, so instead we
+        * prepare sc_last_stick for the coming interrupt setup
+        */
+#if 0
+       bus_space_write_8(psycho0->sc_bustag, psycho0->sc_bh,
+           STICK_CNT_HIGH, (cnt >> 32));
+       bus_space_write_8(psycho0->sc_bustag, psycho0->sc_bh,
+           STICK_CNT_LOW, (uint32_t)(cnt & 0xffffffff));
+#endif
+
+       if (cnt == 0) {
+               bus_space_write_8(psycho0->sc_bustag, psycho0->sc_bh,
+                   STICK_CMP_HIGH, 0);
+               bus_space_write_8(psycho0->sc_bustag, psycho0->sc_bh,
+                   STICK_CMP_LOW, 0);
+               psycho0->sc_last_stick = 0;
+       }
+
+       psycho0->sc_last_stick = psycho_getstick();
+       DPRINTF(PDB_STICK, ("stick: %ld\n", psycho0->sc_last_stick));
+}
+
+void
+psycho_nextstick(long diff)
+{
+       uint64_t cmp, now;
+
+       /*
+        * there is no way we'll ever overflow
+        * the counter is 63 bits wide, at 12MHz that's >24000 years
+        */
+       now = psycho_getstick() + 1000;
+       cmp = psycho0->sc_last_stick;
+       
+       while (cmp < now)
+               cmp += diff;
+       
+       bus_space_write_8(psycho0->sc_bustag, psycho0->sc_bh,
+           STICK_CMP_HIGH, (cmp >> 32) & 0x7fffffff);
+       bus_space_write_8(psycho0->sc_bustag, psycho0->sc_bh,
+           STICK_CMP_LOW, (cmp & 0xffffffff));
+       
+       psycho0->sc_last_stick = cmp;
+}
diff -r d8f153e20a70 -r ca12beaa0af3 sys/arch/sparc64/dev/psychoreg.h
--- a/sys/arch/sparc64/dev/psychoreg.h  Tue Aug 20 18:06:03 2013 +0000
+++ b/sys/arch/sparc64/dev/psychoreg.h  Tue Aug 20 19:19:23 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: psychoreg.h,v 1.18 2013/08/20 10:33:03 macallan Exp $ */
+/*     $NetBSD: psychoreg.h,v 1.19 2013/08/20 19:19:23 macallan Exp $ */
 
 /*
  * Copyright (c) 1999 Matthew R. Green
@@ -249,11 +249,11 @@
        /* 1fe.0000.d000-f058 */
        uint64_t        pad20[1036];
        /* US-IIe and II'i' only */
-       uint64_t        stick_cmp_low;
-       uint64_t        stick_cmp_high;
-       uint64_t        stick_count_low;
-       uint64_t        stick_count_high;
-       uint64_t        estar_mode;
+       uint64_t        stick_cmp_low;
+       uint64_t        stick_cmp_high;
+       uint64_t        stick_count_low;
+       uint64_t        stick_count_high;
+       uint64_t        estar_mode;
 
        /* 
         * Here is the rest of the map, which we're not specifying:
@@ -297,6 +297,12 @@
         */
 };
 
+#define STICK_CMP_LOW  0xf060
+#define STICK_CMP_HIGH 0xf068
+#define STICK_CNT_LOW  0xf070
+#define STICK_CNT_HIGH 0xf078
+#define ESTAR_MODE     0xf080
+
 /* what the bits mean! */
 
 /* PCI [a|b] control/status register */
@@ -313,9 +319,8 @@
 
 /* the following registers only exist on US-IIe and US-II'i' */
 
-/* STICK_COMPARE */
-#define STICK_ENABLE   0x8000000000000000LL    /* enable STICK interrupt */
-#define STICK_MASK     0x7fffffffffffffffLL    /* counter is 63bit wide */
+/* STICK_CMP_HIGH */
+#define STICK_DISABLE  0x80000000      /* disable STICK interrupt */
 
 /*
  * ESTAR_MODE
diff -r d8f153e20a70 -r ca12beaa0af3 sys/arch/sparc64/dev/psychovar.h
--- a/sys/arch/sparc64/dev/psychovar.h  Tue Aug 20 18:06:03 2013 +0000
+++ b/sys/arch/sparc64/dev/psychovar.h  Tue Aug 20 19:19:23 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: psychovar.h,v 1.18 2011/06/02 00:24:23 christos Exp $  */
+/*     $NetBSD: psychovar.h,v 1.19 2013/08/20 19:19:23 macallan Exp $  */
 
 /*
  * Copyright (c) 1999, 2000 Matthew R. Green
@@ -124,6 +124,7 @@
 
        struct sysmon_pswitch           *sc_smcontext;  /* power switch definition */
        int                             sc_powerpressed;/* already signaled */
+       uint64_t                        sc_last_stick;
 };
 
 /* get a PCI offset address from bus_space_handle_t */
@@ -137,4 +138,8 @@
 #define psycho_alloc_mem_tag(pp) psycho_alloc_bus_tag((pp), PCI_MEMORY_BUS_SPACE)
 #define psycho_alloc_io_tag(pp) psycho_alloc_bus_tag((pp), PCI_IO_BUS_SPACE)
 
+long psycho_getstick(void);
+void psycho_setstick(long);
+void psycho_nextstick(long);
+
 #endif /* _SPARC64_DEV_PSYCHOVAR_H_ */
diff -r d8f153e20a70 -r ca12beaa0af3 sys/arch/sparc64/include/cpu.h
--- a/sys/arch/sparc64/include/cpu.h    Tue Aug 20 18:06:03 2013 +0000
+++ b/sys/arch/sparc64/include/cpu.h    Tue Aug 20 19:19:23 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.h,v 1.102 2013/06/21 20:09:59 nakayama Exp $ */
+/*     $NetBSD: cpu.h,v 1.103 2013/08/20 19:19:23 macallan Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -358,11 +358,14 @@
 struct timeval;
 int    tickintr(void *);       /* level 10/14 (tick) interrupt code */
 int    stickintr(void *);      /* system tick interrupt code */
+int    stick2eintr(void *);    /* system tick interrupt code */
 int    clockintr(void *);      /* level 10 (clock) interrupt code */
 int    statintr(void *);       /* level 14 (statclock) interrupt code */
 int    schedintr(void *);      /* level 10 (schedclock) interrupt code */
 void   tickintr_establish(int, int (*)(void *));
 void   stickintr_establish(int, int (*)(void *));
+void   stick2eintr_establish(int, int (*)(void *));
+
 /* locore.s */
 struct fpstate64;
 void   savefpstate(struct fpstate64 *);
diff -r d8f153e20a70 -r ca12beaa0af3 sys/arch/sparc64/sparc64/clock.c
--- a/sys/arch/sparc64/sparc64/clock.c  Tue Aug 20 18:06:03 2013 +0000
+++ b/sys/arch/sparc64/sparc64/clock.c  Tue Aug 20 19:19:23 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: clock.c,v 1.108 2013/05/24 23:02:08 nakayama Exp $ */
+/*     $NetBSD: clock.c,v 1.109 2013/08/20 19:19:23 macallan Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.108 2013/05/24 23:02:08 nakayama Exp $");
+__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.109 2013/08/20 19:19:23 macallan Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -90,6 +90,14 @@
 #include <sparc64/sparc64/timerreg.h>
 #include <sparc64/dev/iommureg.h>
 
+/* just because US-IIe STICK registers live in psycho space */
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <sparc64/dev/iommureg.h>
+#include <sparc64/dev/iommuvar.h>
+#include <sparc64/dev/psychoreg.h>
+#include <sparc64/dev/psychovar.h>
+
 
 /*
  * Clock assignments:
@@ -138,6 +146,7 @@
 
 static u_int tick_get_timecount(struct timecounter *);
 static u_int stick_get_timecount(struct timecounter *);
+static u_int stick2e_get_timecount(struct timecounter *);
 
 /*
  * define timecounter "tick-counter"
@@ -154,6 +163,8 @@
        NULL                    /* next timecounter */
 };
 
+/* US-III %stick */
+
 static struct timecounter stick_timecounter = {
        stick_get_timecount,    /* get_timecount */
        0,                      /* no poll_pps */
@@ -165,6 +176,20 @@
        NULL                    /* next timecounter */
 };
 
+/* US-IIe STICK counter */
+
+static struct timecounter stick2e_timecounter = {
+       stick2e_get_timecount,  /* get_timecount */
+       0,                      /* no poll_pps */
+       ~0u,                    /* counter_mask */
+       0,                      /* frequency - set at initialisation */
+       "stick-counter",        /* name */
+       200,                    /* quality */
+       0,                      /* private reference - UNUSED */
+       NULL                    /* next timecounter */
+};
+
+



Home | Main Index | Thread Index | Old Index