Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/sparc64 use system tick timer instead of %tick on U...



details:   https://anonhg.NetBSD.org/src/rev/7d40ec171f80
branches:  trunk
changeset: 782585:7d40ec171f80
user:      macallan <macallan%NetBSD.org@localhost>
date:      Thu Nov 08 00:34:37 2012 +0000

description:
use system tick timer instead of %tick on UltraSPARC-III-ish CPUs
review & fixes by Takeshi Nakayama

diffstat:

 sys/arch/sparc64/include/cpu.h    |  11 +++-
 sys/arch/sparc64/include/ctlreg.h |   5 +-
 sys/arch/sparc64/include/psl.h    |   3 +-
 sys/arch/sparc64/sparc64/clock.c  |  96 ++++++++++++++++++++++++++++++++++----
 sys/arch/sparc64/sparc64/cpu.c    |  27 ++++++++--
 sys/arch/sparc64/sparc64/locore.s |  82 +++++++++++++++++++++++++++++++-
 6 files changed, 199 insertions(+), 25 deletions(-)

diffs (truncated from 449 to 300 lines):

diff -r 18964251c403 -r 7d40ec171f80 sys/arch/sparc64/include/cpu.h
--- a/sys/arch/sparc64/include/cpu.h    Wed Nov 07 17:14:02 2012 +0000
+++ b/sys/arch/sparc64/include/cpu.h    Thu Nov 08 00:34:37 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.h,v 1.98 2011/07/30 19:29:12 martin Exp $ */
+/*     $NetBSD: cpu.h,v 1.99 2012/11/08 00:34:37 macallan Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -128,7 +128,8 @@
 
        /* %tick and cpu frequency information */
        u_long                  ci_tick_increment;
-       uint64_t                ci_cpu_clockrate[2];
+       uint64_t                ci_cpu_clockrate[2];    /* %tick */
+       uint64_t                ci_system_clockrate[2]; /* %stick */
 
        /* Interrupts */
        struct intrhand         *ci_intrpending[16];
@@ -351,10 +352,12 @@
 /* clock.c */
 struct timeval;
 int    tickintr(void *);       /* level 10/14 (tick) interrupt code */
+int    stickintr(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 *));
 /* locore.s */
 struct fpstate64;
 void   savefpstate(struct fpstate64 *);
@@ -372,6 +375,10 @@
 void   switchtoctx_us(int);
 void   switchtoctx_usiii(int);
 void   next_tick(long);
+void   next_stick(long);
+void   setstick(long);
+long   getstick(void);
+
 /* trap.c */
 void   cpu_vmspace_exec(struct lwp *, vaddr_t, vaddr_t);
 int    rwindow_save(struct lwp *);
diff -r 18964251c403 -r 7d40ec171f80 sys/arch/sparc64/include/ctlreg.h
--- a/sys/arch/sparc64/include/ctlreg.h Wed Nov 07 17:14:02 2012 +0000
+++ b/sys/arch/sparc64/include/ctlreg.h Thu Nov 08 00:34:37 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ctlreg.h,v 1.56 2011/10/08 08:49:07 nakayama Exp $ */
+/*     $NetBSD: ctlreg.h,v 1.57 2012/11/08 00:34:37 macallan Exp $ */
 
 /*
  * Copyright (c) 1996-2002 Eduardo Horvath
@@ -415,6 +415,8 @@
 #define        CLEAR_SOFTINT   %asr21  /* Clears these bits */
 #define        SOFTINT         %asr22  /* Reads the register */
 #define        TICK_CMPR       %asr23
+#define        STICK           %asr24
+#define        STICK_CMPR      %asr25
 
 #define        TICK_INT        0x01    /* level-14 clock tick */
 #define        SOFTINT1        (0x1<<1)
@@ -432,6 +434,7 @@
 #define        SOFTINT13       (0x1<<13)
 #define        SOFTINT14       (0x1<<14)
 #define        SOFTINT15       (0x1<<15)
+#define        STICK_INTR      (0x1<<16)       /* system tick */
 
 /* Interrupt Dispatch -- usually reserved for cross-calls */
 #define        ASR_IDSR        0x48 /* Interrupt dispatch status reg */
diff -r 18964251c403 -r 7d40ec171f80 sys/arch/sparc64/include/psl.h
--- a/sys/arch/sparc64/include/psl.h    Wed Nov 07 17:14:02 2012 +0000
+++ b/sys/arch/sparc64/include/psl.h    Thu Nov 08 00:34:37 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: psl.h,v 1.49 2011/07/12 07:51:34 mrg Exp $ */
+/*     $NetBSD: psl.h,v 1.50 2012/11/08 00:34:37 macallan Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -330,6 +330,7 @@
 #define GETVER_CPU_IMPL()      ((getver() & VER_IMPL) >> VER_IMPL_SHIFT)
 #define GETVER_CPU_MANUF()     ((getver() & VER_MANUF) >> VER_MANUF_SHIFT)
 #define CPU_IS_SPITFIRE()      (GETVER_CPU_IMPL() == IMPL_SPITFIRE)
+#define CPU_IS_HUMMINGBIRD()   (GETVER_CPU_IMPL() == IMPL_HUMMINGBIRD)
 #define CPU_IS_USIIIi()                ((GETVER_CPU_IMPL() == IMPL_JALAPENO) || \
                                 (GETVER_CPU_IMPL() == IMPL_SERRANO))
 #define CPU_IS_USIII_UP()      (GETVER_CPU_IMPL() >= IMPL_CHEETAH)
diff -r 18964251c403 -r 7d40ec171f80 sys/arch/sparc64/sparc64/clock.c
--- a/sys/arch/sparc64/sparc64/clock.c  Wed Nov 07 17:14:02 2012 +0000
+++ b/sys/arch/sparc64/sparc64/clock.c  Thu Nov 08 00:34:37 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: clock.c,v 1.106 2011/09/04 12:17:46 nakayama Exp $ */
+/*     $NetBSD: clock.c,v 1.107 2012/11/08 00:34:38 macallan Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.106 2011/09/04 12:17:46 nakayama Exp $");
+__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.107 2012/11/08 00:34:38 macallan Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -99,6 +99,7 @@
  *  counter-timer       timer#0         timer#1         %tick
  *  counter-timer + SMP         timer#0/%tick   -               timer#1 or %tick
  *  no counter-timer    %tick           -               %tick
+ *  US-IIIi             %stick          -               %stick
  */
 
 /*
@@ -137,6 +138,7 @@
 int timerblurb = 10; /* Guess a value; used before clock is attached */
 
 static u_int tick_get_timecount(struct timecounter *);
+static u_int stick_get_timecount(struct timecounter *);
 
 /*
  * define timecounter "tick-counter"
@@ -153,6 +155,17 @@
        NULL                    /* next timecounter */
 };
 
+static struct timecounter stick_timecounter = {
+       stick_get_timecount,    /* get_timecount */
+       0,                      /* no poll_pps */
+       ~0u,                    /* counter_mask */
+       0,                      /* frequency - set at initialisation */
+       "stick-counter",        /* name */
+       100,                    /* quality */
+       0,                      /* private reference - UNUSED */
+       NULL                    /* next timecounter */
+};
+
 /*
  * tick_get_timecount provide current tick counter value
  */
@@ -162,6 +175,12 @@
        return cpu_counter();
 }
 
+static u_int
+stick_get_timecount(struct timecounter *tc)
+{
+       return getstick();
+}
+
 #ifdef MULTIPROCESSOR
 static u_int counter_get_timecount(struct timecounter *);
 
@@ -329,6 +348,27 @@
        intr_restore(s);
 }
 
+void
+stickintr_establish(int pil, int (*fun)(void *))
+{
+       int s;
+       struct intrhand *ih;
+       struct cpu_info *ci = curcpu();
+
+       ih = sparc_softintr_establish(pil, fun, NULL);
+       ih->ih_number = 1;
+       if (CPU_IS_PRIMARY(ci))
+               intr_establish(pil, true, ih);
+       ci->ci_tick_ih = ih;
+
+       /* set the next interrupt time */
+       ci->ci_tick_increment = ci->ci_system_clockrate[0] / hz;
+
+       s = intr_disable();
+       next_stick(ci->ci_tick_increment);
+       intr_restore(s);
+}
+
 /*
  * Set up the real-time and statistics clocks.  Leave stathz 0 only if
  * no alternative timer is available.
@@ -338,6 +378,7 @@
 void
 cpu_initclocks(void)
 {
+       struct cpu_info *ci = curcpu();
 #ifndef MULTIPROCESSOR
        int statint, minint;
 #endif
@@ -361,17 +402,24 @@
        }
 
        /* Make sure we have a sane cpu_clockrate -- we'll need it */
-       if (!curcpu()->ci_cpu_clockrate[0]) {
+       if (!ci->ci_cpu_clockrate[0]) {
                /* Default to 200MHz clock XXXXX */
-               curcpu()->ci_cpu_clockrate[0] = 200000000;
-               curcpu()->ci_cpu_clockrate[1] = 200000000 / 1000000;
+               ci->ci_cpu_clockrate[0] = 200000000;
+               ci->ci_cpu_clockrate[1] = 200000000 / 1000000;
        }
 
        /* Initialize the %tick register */
        settick(0);
 
-       tick_timecounter.tc_frequency = curcpu()->ci_cpu_clockrate[0];
-       tc_init(&tick_timecounter);
+       if (ci->ci_system_clockrate[0] == 0) {
+               tick_timecounter.tc_frequency = ci->ci_cpu_clockrate[0];
+               tc_init(&tick_timecounter);
+       } else {
+               setstick(0);
+               stick_timecounter.tc_frequency = 
+                   ci->ci_system_clockrate[0];
+               tc_init(&stick_timecounter);
+       }
 
        /*
         * Now handle machines w/o counter-timers.
@@ -379,13 +427,21 @@
 
        if (!timerreg_4u.t_timer || !timerreg_4u.t_clrintr) {
 
-               aprint_normal("No counter-timer -- using %%tick at %luMHz as "
-                       "system clock.\n",
-                       (unsigned long)curcpu()->ci_cpu_clockrate[1]);
+               if (ci->ci_system_clockrate[0] == 0) {
+                       aprint_normal("No counter-timer -- using %%tick "
+                           "at %luMHz as system clock.\n",
+                           (unsigned long)ci->ci_cpu_clockrate[1]);
 
-               /* We don't have a counter-timer -- use %tick */
-               tickintr_establish(PIL_CLOCK, tickintr);
+                       /* We don't have a counter-timer -- use %tick */
+                       tickintr_establish(PIL_CLOCK, tickintr);
+               } else {
+                       aprint_normal("No counter-timer -- using %%stick "
+                           "at %luMHz as system clock.\n",
+                           (unsigned long)ci->ci_system_clockrate[1]);
 
+                       /* We don't have a counter-timer -- use %stick */
+                       stickintr_establish(PIL_CLOCK, stickintr);
+               }
                /* We only have one timer so we have no statclock */
                stathz = 0;
 
@@ -525,6 +581,22 @@
        return (1);
 }
 
+int
+stickintr(void *cap)
+{
+       int s;
+
+       hardclock((struct clockframe *)cap);
+
+       s = intr_disable();
+       /* Reset the interrupt */
+       next_stick(curcpu()->ci_tick_increment);
+       intr_restore(s);
+       curcpu()->ci_tick_evcnt.ev_count++;
+
+       return (1);
+}
+
 #ifndef MULTIPROCESSOR
 /*
  * Level 14 (stat clock) interrupt handler.
diff -r 18964251c403 -r 7d40ec171f80 sys/arch/sparc64/sparc64/cpu.c
--- a/sys/arch/sparc64/sparc64/cpu.c    Wed Nov 07 17:14:02 2012 +0000
+++ b/sys/arch/sparc64/sparc64/cpu.c    Thu Nov 08 00:34:37 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.c,v 1.102 2012/10/27 17:18:12 chs Exp $ */
+/*     $NetBSD: cpu.c,v 1.103 2012/11/08 00:34:38 macallan Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -52,7 +52,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.102 2012/10/27 17:18:12 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.103 2012/11/08 00:34:38 macallan Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -242,7 +242,7 @@
 cpu_attach(device_t parent, device_t dev, void *aux)
 {
        int node;
-       long clk;
+       long clk, sclk = 0;
        struct mainbus_attach_args *ma = aux;
        struct cpu_info *ci;
        const char *sep;
@@ -299,12 +299,23 @@
                ci->ci_cpu_clockrate[1] = clk / 1000000;
        }
 
+       if (!CPU_IS_HUMMINGBIRD()) {
+               sclk = prom_getpropint(findroot(), "stick-frequency", 0);



Home | Main Index | Thread Index | Old Index