Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc64 Add code to support using %tick as the syst...
details: https://anonhg.NetBSD.org/src/rev/5a372ef10cc8
branches: trunk
changeset: 473354:5a372ef10cc8
user: eeh <eeh%NetBSD.org@localhost>
date: Sun May 30 19:13:33 1999 +0000
description:
Add code to support using %tick as the system clock if no "counter-timer" node
is found.
diffstat:
sys/arch/sparc64/dev/sbus.c | 3 +-
sys/arch/sparc64/include/cpu.h | 29 +--
sys/arch/sparc64/sparc64/autoconf.c | 3 +-
sys/arch/sparc64/sparc64/clock.c | 157 +++++++++-----
sys/arch/sparc64/sparc64/cpu.c | 7 +-
sys/arch/sparc64/sparc64/locore.s | 371 +++++++++++++++++++++++++----------
6 files changed, 374 insertions(+), 196 deletions(-)
diffs (truncated from 1002 to 300 lines):
diff -r 838062c5e285 -r 5a372ef10cc8 sys/arch/sparc64/dev/sbus.c
--- a/sys/arch/sparc64/dev/sbus.c Sun May 30 19:11:33 1999 +0000
+++ b/sys/arch/sparc64/dev/sbus.c Sun May 30 19:13:33 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sbus.c,v 1.14 1999/05/25 23:14:08 thorpej Exp $ */
+/* $NetBSD: sbus.c,v 1.15 1999/05/30 19:13:33 eeh Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -756,6 +756,7 @@
stxa(&sc->sc_sysio->sys_strbuf.strbuf_flushsync, ASI_NUCLEUS, sc->sc_flushpa);
#endif
membar_sync();
+/* XXXXXX this may never time out if %tick is the clock!!!! */
flushtimeout = tick() + cpu_clockrate/2; /* .5 sec after *now* */
#ifdef DEBUG
if (sbusdebug & SDB_DVMA)
diff -r 838062c5e285 -r 5a372ef10cc8 sys/arch/sparc64/include/cpu.h
--- a/sys/arch/sparc64/include/cpu.h Sun May 30 19:11:33 1999 +0000
+++ b/sys/arch/sparc64/include/cpu.h Sun May 30 19:13:33 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.6 1999/05/30 02:37:10 mrg Exp $ */
+/* $NetBSD: cpu.h,v 1.7 1999/05/30 19:13:33 eeh Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -80,29 +80,6 @@
* as well for strayintr (see locore.s:interrupt and intr.c:strayintr).
* Note that CLKF_INTR is valid only if CLKF_USERMODE is false.
*/
-/*
- * Note: we have to do something to make sure this matches the definition
- * of trapframe in reg.h.
- */
-#if 0
-struct clockframe {
- u_int64_t tstate; /* pstate before interrupt, excluding PSR_ET */
- u_int64_t pc; /* pc at interrupt */
- u_int64_t npc; /* npc at interrupt */
- u_int64_t faultaddr; /* faulting addr -- not used */
- u_int64_t oldfp; /* location of prev trapframe */
- u_int pil; /* actual interrupt priority level */
- u_int oldpil; /* priority before interrupt */
- u_int64_t fp; /* %fp at interrupt */
-};
-typedef const struct clockframe clockframe;
-extern int eintstack[];
-
-#define CLKF_USERMODE(framep) (((framep)->tstate & TSTATE_PRIV) == 0)
-#define CLKF_BASEPRI(framep) (((framep)->oldpil) == 0)
-#define CLKF_PC(framep) ((framep)->pc)
-#define CLKF_INTR(framep) (((framep)->fp < (u_int)eintstack)&&((framep)->fp > (u_int)KERNBASE))
-#else
extern int eintstack[];
struct clockframe {
struct trapframe t;
@@ -112,7 +89,6 @@
#define CLKF_BASEPRI(framep) (((framep)->t.tf_oldpil) == 0)
#define CLKF_PC(framep) ((framep)->t.tf_pc)
#define CLKF_INTR(framep) (((framep)->t.tf_kstack < (u_int)eintstack)&&((framep)->t.tf_kstack > (u_int)KERNBASE))
-#endif
/*
* Software interrupt request `register'.
@@ -197,8 +173,7 @@
caddr_t reserve_dumppages __P((caddr_t));
/* clock.c */
struct timeval;
-void lo_microtime __P((struct timeval *));
-int statintr __P((void *));
+int tickintr __P((void *)); /* level 10 (tick) interrupt code */
int clockintr __P((void *));/* level 10 (clock) interrupt code */
int statintr __P((void *)); /* level 14 (statclock) interrupt code */
/* locore.s */
diff -r 838062c5e285 -r 5a372ef10cc8 sys/arch/sparc64/sparc64/autoconf.c
--- a/sys/arch/sparc64/sparc64/autoconf.c Sun May 30 19:11:33 1999 +0000
+++ b/sys/arch/sparc64/sparc64/autoconf.c Sun May 30 19:13:33 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.c,v 1.16 1999/05/23 02:45:20 eeh Exp $ */
+/* $NetBSD: autoconf.c,v 1.17 1999/05/30 19:13:34 eeh Exp $ */
/*
* Copyright (c) 1996
@@ -626,7 +626,6 @@
static const char *const openboot_special[] = {
/* find these first */
- "counter-timer",
"",
/* ignore these (end with NULL) */
diff -r 838062c5e285 -r 5a372ef10cc8 sys/arch/sparc64/sparc64/clock.c
--- a/sys/arch/sparc64/sparc64/clock.c Sun May 30 19:11:33 1999 +0000
+++ b/sys/arch/sparc64/sparc64/clock.c Sun May 30 19:13:33 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: clock.c,v 1.9 1998/11/22 23:56:49 mrg Exp $ */
+/* $NetBSD: clock.c,v 1.10 1999/05/30 19:13:34 eeh Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -85,6 +85,7 @@
#include <sparc64/sparc64/clockreg.h>
#include <sparc64/sparc64/intreg.h>
#include <sparc64/sparc64/timerreg.h>
+#include <sparc64/dev/iommureg.h>
#include <sparc64/dev/sbusreg.h>
#include <dev/sbus/sbusvar.h>
#include "kbd.h"
@@ -120,8 +121,10 @@
#define intersil_clear(CLOCK) CLOCK->clk_intr_reg
+static long tick_increment;
static struct intrhand level10 = { clockintr };
+static struct intrhand level0 = { tickintr };
static struct intrhand level14 = { statintr };
static int clockmatch __P((struct device *, struct cfdata *, void *));
@@ -334,49 +337,6 @@
timerok = 1;
-#if 0
- /*
- * Calibrate delay() by tweaking the magic constant
- * until a delay(100) actually reads (at least) 100 us
- * on the clock. Since we're using the %tick register
- * which should be running at exactly the CPU clock rate, it
- * has a period of somewhere between 7ns and 3ns.
- */
-
-#ifdef DEBUG
- printf("Delay calibrarion....\n");
-#endif
- for (timerblurb = 1; timerblurb>0; timerblurb++) {
- volatile int discard;
- register int t0, t1;
-
- /* Reset counter register by writing some large limit value */
- discard = *lim;
- *lim = tmr_ustolim(TMR_MASK-1);
-
- t0 = *cnt;
- delay(100);
- t1 = *cnt;
-
- if (t1 & TMR_LIMIT)
- panic("delay calibration");
-
- t0 = (t0 >> TMR_SHIFT) & TMR_MASK;
- t1 = (t1 >> TMR_SHIFT) & TMR_MASK;
-
- if (t1 >= t0 + 100)
- break;
- }
-
- printf(" delay constant %d\n", timerblurb);
- timerok = 1;
-#endif
-
-#if 0 /* Done earlier */
- /* link interrupt handlers */
- intr_establish(10, &level10);
- intr_establish(14, &level14);
-#endif
}
/*
@@ -445,26 +405,83 @@
extern int intrdebug;
#endif
+#ifdef DEBUG
+ /* Set a 1s clock */
+ if (intrdebug) {
+ hz = 1;
+ printf("intrdebug set: 1Hz clock\n");
+ }
+#endif
+
if (1000000 % hz) {
printf("cannot get %d Hz clock; using 100 Hz\n", hz);
hz = 100;
tick = 1000000 / hz;
}
+ if (!timerreg_4u.t_timer || !timerreg_4u.t_clrintr) {
+ extern u_int64_t cpu_clockrate;
+ static u_int64_t start_time;
+
+ printf("No counter-timer -- using %%tick at %ldMHz as system clock.\n",
+ (long)(cpu_clockrate/1000000));
+ /* We don't have a counter-timer -- use %tick */
+ level0.ih_clr = 0;
+ /*
+ * Establish a level 10 interrupt handler
+ *
+ * We will have a conflict with the softint handler,
+ * so we set the ih_number to 1.
+ */
+ level0.ih_number = 1;
+ intr_establish(10, &level0);
+ /* We only have one timer so we have no statclock */
+ stathz = 0;
+ /* Make sure we have a sane cpu_clockrate -- we'll need it */
+ if (!cpu_clockrate)
+ /* Default to 200MHz clock XXXXX */
+ cpu_clockrate = 200000000;
+
+ /*
+ * Calculate the starting %tick value. We set that to the same
+ * as time, scaled for the CPU clockrate. This gets nasty, but
+ * we can handle it. time.tv_usec is in microseconds.
+ * cpu_clockrate is in MHz.
+ */
+ start_time = time.tv_sec * cpu_clockrate;
+ /* Now fine tune the usecs */
+ start_time += cpu_clockrate / 1000000 * time.tv_usec;
+
+ /* Initialize the %tick register */
+#ifdef __arch64__
+ __asm __volatile("wrpr %0, 0, %%tick" : : "r" (start_time));
+#else
+ {
+ int start_hi = (start_time>>32), start_lo = start_time;
+ __asm __volatile("sllx %0,32,%0; or %1,%0,%0; wrpr %0, 0, %%tick"
+ : "=&r" (start_hi) /* scratch register */
+ : "r" ((int)(start_hi)), "r" ((int)(start_lo)));
+ }
+#endif
+ /* set the next interrupt time */
+ tick_increment = cpu_clockrate / hz;
+#ifdef DEBUG
+ printf("Using %tick -- intr in %ld cycles...", tick_increment);
+#endif
+ next_tick(tick_increment);
+#ifdef DEBUG
+ printf("done.\n");
+#endif
+ return;
+ }
+
if (stathz == 0)
stathz = hz;
if (1000000 % stathz) {
printf("cannot get %d Hz statclock; using 100 Hz\n", stathz);
stathz = 100;
}
-#ifdef DEBUG
- /* Set a 1s clock */
- if (intrdebug) {
- hz = 1;
- tick = 1000000;
- printf("intrdebug set: 1Hz clock\n");
- }
-#endif
+
profhz = stathz; /* always */
statint = 1000000 / stathz;
@@ -472,8 +489,6 @@
while (statvar > minint)
statvar >>= 1;
- if (!timerreg_4u.t_timer || !timerreg_4u.t_clrintr)
- panic("cpu_initclocks(): Timer not attached!\n");
/*
* Enable timers
*
@@ -559,6 +574,39 @@
}
/*
+ * Level 10 (clock) interrupts. If we are using the FORTH PROM for
+ * console input, we need to check for that here as well, and generate
+ * a software interrupt to read it.
+ *
+ * %tick is really a level-14 interrupt. We need to remap this in
+ * locore.s to a level 10.
+ */
+int
+tickintr(cap)
+ void *cap;
+{
+ int s;
+
+#if NKBD > 0
+ extern int cnrom __P((void));
+ extern int rom_console_input;
+#endif
+
+ s = splhigh();
+ /* Reset the interrupt */
+ next_tick(tick_increment);
+ splx(s);
+
+ hardclock((struct clockframe *)cap);
+#if NKBD > 0
+ if (rom_console_input && cnrom())
Home |
Main Index |
Thread Index |
Old Index