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