Source-Changes-HG archive

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

[src/trunk]: src/sys Switch to use cycle counter (%tick) based microtime().



details:   https://anonhg.NetBSD.org/src/rev/6a148e009c99
branches:  trunk
changeset: 542735:6a148e009c99
user:      nakayama <nakayama%NetBSD.org@localhost>
date:      Wed Feb 05 12:06:51 2003 +0000

description:
Switch to use cycle counter (%tick) based microtime().

This is derived from alpha/microtime.c and i386/tsc_microtime.c,
and will share with both ports.

This should fix PR port-sparc64/18452.
(approved by martin)

diffstat:

 sys/arch/sparc64/conf/files.sparc64    |    3 +-
 sys/arch/sparc64/include/cpu.h         |   20 ++-
 sys/arch/sparc64/include/cpu_counter.h |   76 +++++++++++
 sys/arch/sparc64/sparc64/clock.c       |   61 +++++++-
 sys/arch/sparc64/sparc64/cpu.c         |    3 +-
 sys/arch/sparc64/sparc64/locore.s      |    4 +-
 sys/kern/kern_microtime.c              |  215 +++++++++++++++++++++++++++++++++
 7 files changed, 366 insertions(+), 16 deletions(-)

diffs (truncated from 562 to 300 lines):

diff -r fa528f99cac2 -r 6a148e009c99 sys/arch/sparc64/conf/files.sparc64
--- a/sys/arch/sparc64/conf/files.sparc64       Wed Feb 05 12:03:54 2003 +0000
+++ b/sys/arch/sparc64/conf/files.sparc64       Wed Feb 05 12:06:51 2003 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.sparc64,v 1.73 2003/01/06 13:26:26 wiz Exp $
+#      $NetBSD: files.sparc64,v 1.74 2003/02/05 12:06:52 nakayama Exp $
 
 # @(#)files.sparc64    8.1 (Berkeley) 7/19/93
 # sparc64-specific configuration info
@@ -163,6 +163,7 @@
 
 file   dev/cons.c
 file   arch/sparc64/dev/consinit.c
+file   kern/kern_microtime.c
 
 file   arch/sparc/fpu/fpu.c
 file   arch/sparc/fpu/fpu_add.c
diff -r fa528f99cac2 -r 6a148e009c99 sys/arch/sparc64/include/cpu.h
--- a/sys/arch/sparc64/include/cpu.h    Wed Feb 05 12:03:54 2003 +0000
+++ b/sys/arch/sparc64/include/cpu.h    Wed Feb 05 12:06:51 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.h,v 1.34 2003/01/18 06:55:21 thorpej Exp $ */
+/*     $NetBSD: cpu.h,v 1.35 2003/02/05 12:06:52 nakayama Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -107,6 +107,14 @@
        int                     ci_upaid;
        struct schedstate_percpu ci_schedstate;
 
+       /*
+        * Variables used by cc_microtime().
+        */
+       struct timeval ci_cc_time;
+       int64_t ci_cc_cc;
+       int64_t ci_cc_ms_delta;
+       int64_t ci_cc_denom;
+
        /* DEBUG/DIAGNOSTIC stuff */
        u_long                  ci_spin_locks;
        u_long                  ci_simple_locks;
@@ -143,6 +151,16 @@
 #define        cpu_proc_fork(p1, p2)   /* nothing */
 
 /*
+ * definitions for MI microtime().
+ */
+extern struct timeval cc_microset_time;
+#define microtime(tv)  cc_microtime(tv)
+void   cc_microtime __P((struct timeval *));
+void   cc_microset __P((struct cpu_info *));
+
+extern uint64_t cpu_clockrate[];
+
+/*
  * Arguments to hardclock, softclock and gatherstats encapsulate the
  * previous machine state in an opaque clockframe.  The ipl is here
  * as well for strayintr (see locore.s:interrupt and intr.c:strayintr).
diff -r fa528f99cac2 -r 6a148e009c99 sys/arch/sparc64/include/cpu_counter.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/sparc64/include/cpu_counter.h    Wed Feb 05 12:06:51 2003 +0000
@@ -0,0 +1,76 @@
+/*     $NetBSD: cpu_counter.h,v 1.1 2003/02/05 12:06:52 nakayama Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Martin Husemann.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SPARC64_CPU_COUNTER_H_
+#define _SPARC64_CPU_COUNTER_H_
+
+/*
+ * Machine-specific support for CPU counter.
+ */
+
+#ifdef _KERNEL
+
+#include <machine/cpu.h>
+#include <machine/ctlreg.h>
+
+#define        cpu_hascounter()        (1)
+
+static __inline uint64_t
+cpu_counter(void)
+{
+
+       return (tick());
+}
+
+static __inline uint32_t
+cpu_counter32(void)
+{
+
+       return (tick() & 0xffffffffUL);
+}
+
+static __inline uint64_t
+cpu_frequency(struct cpu_info *ci)
+{
+
+       return (cpu_clockrate[0]);
+}
+
+#endif /* _KERNEL */
+
+#endif /* !_SPARC64_CPU_COUNTER_H_ */
diff -r fa528f99cac2 -r 6a148e009c99 sys/arch/sparc64/sparc64/clock.c
--- a/sys/arch/sparc64/sparc64/clock.c  Wed Feb 05 12:03:54 2003 +0000
+++ b/sys/arch/sparc64/sparc64/clock.c  Wed Feb 05 12:06:51 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: clock.c,v 1.54 2003/01/18 06:55:22 thorpej Exp $ */
+/*     $NetBSD: clock.c,v 1.55 2003/02/05 12:06:52 nakayama Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -93,8 +93,6 @@
 #include <dev/ebus/ebusreg.h>
 #include <dev/ebus/ebusvar.h>
 
-extern u_int64_t cpu_clockrate;
-
 struct rtc_info {
        bus_space_tag_t rtc_bt;         /* bus tag & handle */
        bus_space_handle_t rtc_bh;      /* */
@@ -631,9 +629,11 @@
        }
 
        /* Make sure we have a sane cpu_clockrate -- we'll need it */
-       if (!cpu_clockrate) 
+       if (!cpu_clockrate[0]) {
                /* Default to 200MHz clock XXXXX */
-               cpu_clockrate = 200000000;
+               cpu_clockrate[0] = 200000000;
+               cpu_clockrate[1] = 200000000 / 1000000;
+       }
        
        /*
         * Calculate the starting %tick value.  We set that to the same
@@ -641,9 +641,9 @@
         * we can handle it.  time.tv_usec is in microseconds.  
         * cpu_clockrate is in MHz.  
         */
-       start_time = time.tv_sec * cpu_clockrate;
+       start_time = time.tv_sec * cpu_clockrate[0];
        /* Now fine tune the usecs */
-       start_time += cpu_clockrate / 1000000 * time.tv_usec;
+       start_time += time.tv_usec * cpu_clockrate[1];
        
        /* Initialize the %tick register */
 #ifdef __arch64__
@@ -665,7 +665,7 @@
        if (!timerreg_4u.t_timer || !timerreg_4u.t_clrintr) {
 
                printf("No counter-timer -- using %%tick at %ldMHz as system clock.\n",
-                       (long)(cpu_clockrate/1000000));
+                       (long)cpu_clockrate[1]);
                /* We don't have a counter-timer -- use %tick */
                level0.ih_clr = 0;
                /* 
@@ -680,7 +680,7 @@
                stathz = 0;     
 
                /* set the next interrupt time */
-               tick_increment = cpu_clockrate / hz;
+               tick_increment = cpu_clockrate[0] / hz;
 #ifdef DEBUG
                printf("Using %%tick -- intr in %ld cycles...", tick_increment);
 #endif
@@ -764,19 +764,21 @@
 clockintr(cap)
        void *cap;
 {
+       static int microset_iter;       /* call cc_microset once/sec */
+       struct cpu_info *ci = curcpu();
 #ifdef DEBUG
        static int64_t tick_base = 0;
        int64_t t = (u_int64_t)tick();
 
        if (!tick_base) {
                tick_base = (time.tv_sec * 1000000LL + time.tv_usec) 
-                       * 1000000LL / cpu_clockrate;
+                       / cpu_clockrate[1];
                tick_base -= t;
        } else if (clockcheck) {
                int64_t tk = t;
                int64_t clk = (time.tv_sec * 1000000LL + time.tv_usec);
                t -= tick_base;
-               t = t * 1000000LL / cpu_clockrate;
+               t = t / cpu_clockrate[1];
                if (t - clk > hz) {
                        printf("Clock lost an interrupt!\n");
                        printf("Actual: %llx Expected: %llx tick %llx tick_base %llx\n",
@@ -786,6 +788,19 @@
                }
        }       
 #endif
+       if (
+#ifdef MULTIPROCESSOR
+           CPU_IS_PRIMARY(ci) &&
+#endif
+           (microset_iter--) == 0) {
+               microset_iter = hz - 1;
+               cc_microset_time = time;
+#ifdef MULTIPROCESSOR
+               /* XXX broadcast IPI_MICROSET code here */
+#endif
+               cc_microset(ci);
+       }
+
        /* Let locore.s clear the interrupt for us. */
        hardclock((struct clockframe *)cap);
        return (1);
@@ -805,6 +820,8 @@
 tickintr(cap)
        void *cap;
 {
+       static int microset_iter;       /* call cc_microset once/sec */
+       struct cpu_info *ci = curcpu();
        int s;
 
 #if    NKBD    > 0
@@ -812,6 +829,19 @@
        extern int rom_console_input;
 #endif
 
+       if (
+#ifdef MULTIPROCESSOR
+           CPU_IS_PRIMARY(ci) &&
+#endif
+           (microset_iter--) == 0) {
+               microset_iter = hz - 1;
+               cc_microset_time = time;
+#ifdef MULTIPROCESSOR
+               /* XXX broadcast IPI_MICROSET code here */
+#endif
+               cc_microset(ci);
+       }
+
        hardclock((struct clockframe *)cap);
        if (poll_console)
                setsoftint();
@@ -912,11 +942,15 @@
                 * anything better, resetting the clock.
                 */
                time.tv_sec = base;
+               cc_microset_time = time;
+               cc_microset(curcpu());
                if (!badbase)
                        resettodr();
        } else {
                int deltat = time.tv_sec - base;
 
+               cc_microset_time = time;
+               cc_microset(curcpu());
                sparc_clock_time_is_ok = 1;
 
                if (deltat < 0)
@@ -942,6 +976,11 @@
        if (time.tv_sec == 0)
                return;
 
+       cc_microset_time = time;
+#ifdef MULTIPROCESSOR
+       /* XXX broadcast IPI_MICROSET code here */
+#endif
+       cc_microset(curcpu());
        sparc_clock_time_is_ok = 1;
        if (todr_handle == 0 ||



Home | Main Index | Thread Index | Old Index