patch-2.1.48 linux/arch/sparc64/kernel/time.c
Next file: linux/arch/sparc64/kernel/trampoline.S
Previous file: linux/arch/sparc64/kernel/smp.c
Back to the patch index
Back to the overall index
- Lines: 112
- Date:
Thu Jul 31 13:09:17 1997
- Orig file:
v2.1.47/linux/arch/sparc64/kernel/time.c
- Orig date:
Mon Jul 7 08:18:54 1997
diff -u --recursive --new-file v2.1.47/linux/arch/sparc64/kernel/time.c linux/arch/sparc64/kernel/time.c
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.3 1997/06/17 13:25:29 jj Exp $
+/* $Id: time.c,v 1.5 1997/07/23 11:32:06 davem Exp $
* time.c: UltraSparc timer and TOD clock support.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -20,6 +20,7 @@
#include <asm/oplib.h>
#include <asm/mostek.h>
+#include <asm/timer.h>
#include <asm/irq.h>
#include <asm/io.h>
@@ -35,11 +36,17 @@
* NOTE: On SUN5 systems the ticker interrupt comes in using 2
* interrupts, one at level14 and one with softint bit 0.
*/
-void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+extern struct sun5_timer *linux_timers;
+
+static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
/* last time the cmos clock got updated */
static long last_rtc_update=0;
+ __asm__ __volatile__("ldx [%0], %%g0"
+ : /* no outputs */
+ : "r" (&((linux_timers)->limit0)));
+
do_timer(regs);
/* Determine when to update the Mostek clock. */
@@ -239,14 +246,12 @@
__initfunc(void time_init(void))
{
- extern void init_timers(void (*func)(int, void *, struct pt_regs *));
unsigned int year, mon, day, hour, min, sec;
struct mostek48t02 *mregs;
do_get_fast_time = do_gettimeofday;
clock_probe();
- init_timers(timer_interrupt);
mregs = mstk48t02_regs;
if(!mregs) {
@@ -266,6 +271,13 @@
mregs->creg &= ~MSTK_CREG_READ;
}
+extern void init_timers(void (*func)(int, void *, struct pt_regs *));
+
+__initfunc(void sun4u_start_timers(void))
+{
+ init_timers(timer_interrupt);
+}
+
static __inline__ unsigned long do_gettimeoffset(void)
{
unsigned long offset = 0;
@@ -286,16 +298,39 @@
void do_gettimeofday(struct timeval *tv)
{
- unsigned long flags;
-
- save_and_cli(flags);
- *tv = xtime;
- tv->tv_usec += do_gettimeoffset();
- if(tv->tv_usec >= 1000000) {
- tv->tv_usec -= 1000000;
- tv->tv_sec++;
- }
- restore_flags(flags);
+ /* Load doubles must be used on xtime so that what we get
+ * is guarenteed to be atomic, this is why we can run this
+ * with interrupts on full blast. Don't touch this... -DaveM
+ */
+ __asm__ __volatile__("
+ sethi %hi(linux_timers), %o1
+ sethi %hi(xtime), %g2
+ ldx [%o1 + %lo(linux_timers)], %g3
+1: ldd [%g2 + %lo(xtime)], %o4
+ ldx [%g3], %o1
+ ldd [%g2 + %lo(xtime)], %o2
+ xor %o4, %o2, %o2
+ xor %o5, %o3, %o3
+ orcc %o2, %o3, %g0
+ bne,pn %icc, 1b
+ cmp %o1, 0
+ bge,pt %icc, 1f
+ sethi %hi(tick), %o3
+ ld [%o3 + %lo(tick)], %o3
+ sethi %hi(0x1fffff), %o2
+ or %o2, %lo(0x1fffff), %o2
+ add %o5, %o3, %o5
+ and %o1, %o2, %o1
+1: add %o5, %o1, %o5
+ sethi %hi(1000000), %o2
+ or %o2, %lo(1000000), %o2
+ cmp %o5, %o2
+ bl,a,pn %icc, 1f
+ st %o4, [%o0 + 0x0]
+ add %o4, 0x1, %o4
+ sub %o5, %o2, %o5
+ st %o4, [%o0 + 0x0]
+1: st %o5, [%o0 + 0x4]");
}
void do_settimeofday(struct timeval *tv)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov