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