BSD 4_4_Lite1 release
[unix-history] / usr / src / sys / hp300 / hp300 / clock.c
index 9eb7180..1247837 100644 (file)
@@ -1,17 +1,51 @@
 /*
  * Copyright (c) 1988 University of Utah.
 /*
  * Copyright (c) 1988 University of Utah.
- * Copyright (c) 1982, 1990 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1982, 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * the Systems Programming Group of the University of Utah Computer
  * Science Department.
  *
  *
  * This code is derived from software contributed to Berkeley by
  * the Systems Programming Group of the University of Utah Computer
  * Science Department.
  *
- * %sccs.include.redist.c%
+ * 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 University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
  *
  * from: Utah $Hdr: clock.c 1.18 91/01/21$
  *
  *
  * from: Utah $Hdr: clock.c 1.18 91/01/21$
  *
- *     @(#)clock.c     7.17 (Berkeley) %G%
+ *     @(#)clock.c     8.2 (Berkeley) 1/12/94
+ */
+
+/*
+ * HPs use the MC6840 PTM with the following arrangement:
+ *     Timers 1 and 3 are externally driver from a 25Mhz source.
+ *     Output from timer 3 is tied to the input of timer 2.
+ * The latter makes it possible to use timers 3 and 2 together to get
+ * a 32-bit countdown timer.
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -41,6 +75,7 @@ static int statvar = 1024 / 4;        /* {stat,prof}clock variance */
 static int statmin;            /* statclock interval - variance/2 */
 static int profmin;            /* profclock interval - variance/2 */
 static int timer3min;          /* current, from above choices */
 static int statmin;            /* statclock interval - variance/2 */
 static int profmin;            /* profclock interval - variance/2 */
 static int timer3min;          /* current, from above choices */
+static int statprev;           /* previous value in stat timer */
 
 static int month_days[12] = {
        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
 
 static int month_days[12] = {
        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
@@ -117,16 +152,14 @@ cpu_initclocks()
        statmin = statint - (statvar >> 1);
        profmin = profint - (statvar >> 1);
        timer3min = statmin;
        statmin = statint - (statvar >> 1);
        profmin = profint - (statvar >> 1);
        timer3min = statmin;
+       statprev = statint;
 
        /* finally, load hardware */
        clk->clk_cr2 = CLK_CR1;
        clk->clk_cr1 = CLK_RESET;
 
        /* finally, load hardware */
        clk->clk_cr2 = CLK_CR1;
        clk->clk_cr1 = CLK_RESET;
-       clk->clk_msb1 = intvl >> 8;
-       clk->clk_lsb1 = intvl;
-       clk->clk_msb2 = 0;
-       clk->clk_lsb2 = 0;
-       clk->clk_msb3 = statint >> 8;
-       clk->clk_lsb3 = statint;
+       asm volatile(" movpw %0,%1@(5)" : : "d" (intvl), "a" (clk));
+       asm volatile(" movpw %0,%1@(9)" : : "d" (0), "a" (clk));
+       asm volatile(" movpw %0,%1@(13)" : : "d" (statint), "a" (clk));
        clk->clk_cr2 = CLK_CR1;
        clk->clk_cr1 = CLK_IENAB;
        clk->clk_cr2 = CLK_CR3;
        clk->clk_cr2 = CLK_CR1;
        clk->clk_cr1 = CLK_IENAB;
        clk->clk_cr2 = CLK_CR3;
@@ -168,8 +201,19 @@ statintr(fp)
                r = random() & (var - 1);
        } while (r == 0);
        newint = timer3min + r;
                r = random() & (var - 1);
        } while (r == 0);
        newint = timer3min + r;
-       clk->clk_msb3 = newint >> 8;
-       clk->clk_lsb3 = newint;
+
+       /*
+        * The timer was automatically reloaded with the previous latch
+        * value at the time of the interrupt.  Compensate now for the
+        * amount of time that has run off since then (minimum of 2-12
+        * timer ticks depending on CPU type) plus one tick roundoff.
+        * This should keep us closer to the mean.
+        */
+       asm volatile(" clrl %0; movpw %1@(13),%0" : "=d" (r) : "a" (clk));
+       newint -= (statprev - r + 1);
+
+       asm volatile(" movpw %0,%1@(13)" : : "d" (newint), "a" (clk));
+       statprev = newint;
        statclock(fp);
 }
 
        statclock(fp);
 }
 
@@ -180,7 +224,7 @@ microtime(tvp)
        register struct timeval *tvp;
 {
        register volatile struct clkreg *clk;
        register struct timeval *tvp;
 {
        register volatile struct clkreg *clk;
-       register int s, u, h, l, sr, l2, h2, u2, s2;
+       register int s, u, t, u2, s2;
 
        /*
         * Read registers from slowest-changing to fastest-changing,
 
        /*
         * Read registers from slowest-changing to fastest-changing,
@@ -196,25 +240,13 @@ microtime(tvp)
        do {
                s = time.tv_sec;
                u = time.tv_usec;
        do {
                s = time.tv_sec;
                u = time.tv_usec;
-               h = clk->clk_msb1;
-               l = clk->clk_lsb1;
-               sr = clk->clk_sr;
-               l2 = clk->clk_lsb1;
-               h2 = clk->clk_msb1;
+               asm volatile (" clrl %0; movpw %1@(5),%0"
+                             : "=d" (t) : "a" (clk));
                u2 = time.tv_usec;
                s2 = time.tv_sec;
                u2 = time.tv_usec;
                s2 = time.tv_sec;
-       } while (l != l2 || h != h2 || u != u2 || s != s2);
+       } while (u != u2 || s != s2);
 
 
-       /*
-        * Pending interrupt means that the counter wrapped and we did not
-        * take the interrupt yet (can only happen if clock interrupts are
-        * blocked).  If so, add one tick.  Then in any case, add remaining
-        * count.  This should leave u < 2 seconds, since we can add at most
-        * two clock intervals (assuming hz > 2!).
-        */
-       if (sr & CLK_INT1)
-               u += tick;
-       u += clkint - ((h << 8) | l);
+       u += (clkint - t) * CLK_RESOLUTION;
        if (u >= 1000000) {             /* normalize */
                s++;
                u -= 1000000;
        if (u >= 1000000) {             /* normalize */
                s++;
                u -= 1000000;
@@ -398,6 +430,7 @@ read_bbc_reg(reg)
 
 u_char
 write_bbc_reg(reg, data)
 
 u_char
 write_bbc_reg(reg, data)
+       int reg;
        u_int data;
 {
        u_char tmp;
        u_int data;
 {
        u_char tmp;