OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [i960/] [kernel/] [time.c] - Diff between revs 1765 and 1782

Only display areas with differences | Details | Blame | View Log

Rev 1765 Rev 1782
/*
/*
 *  linux/arch/i960/kernel/time.c
 *  linux/arch/i960/kernel/time.c
 *
 *
 *  Copyright (C) 1999  Keith Adams     <kma@cse.ogi.edu>
 *  Copyright (C) 1999  Keith Adams     <kma@cse.ogi.edu>
 *                      Oregon Graduate Institute
 *                      Oregon Graduate Institute
 *
 *
 *  Based on:
 *  Based on:
 *
 *
 *  linux/arch/m68knommu/kernel/time.c
 *  linux/arch/m68knommu/kernel/time.c
 *
 *
 *  Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
 *  Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
 *                      Kenneth Albanowski <kjahds@kjahds.com>,
 *                      Kenneth Albanowski <kjahds@kjahds.com>,
 *                      The Silver Hammer Group, Ltd.
 *                      The Silver Hammer Group, Ltd.
 *
 *
 *  Copied/hacked from:
 *  Copied/hacked from:
 *
 *
 *  linux/arch/m68k/kernel/time.c
 *  linux/arch/m68k/kernel/time.c
 *
 *
 *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
 *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
 *
 *
 * This file contains the i960-specific time handling details.
 * This file contains the i960-specific time handling details.
 */
 */
 
 
#include <linux/config.h>
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/mm.h>
 
 
#include <asm/machdep.h>
#include <asm/machdep.h>
#include <asm/segment.h>
#include <asm/segment.h>
#include <asm/io.h>
#include <asm/io.h>
 
 
#include <linux/timex.h>
#include <linux/timex.h>
 
 
 
 
/*
/*
 * XXX: bloody hell. We need to have figured out our machine's MHZ, and
 * XXX: bloody hell. We need to have figured out our machine's MHZ, and
 * programmed its clock accordingly.
 * programmed its clock accordingly.
 */
 */
static inline int set_rtc_mmss(unsigned long nowtime)
static inline int set_rtc_mmss(unsigned long nowtime)
{
{
        return -1;
        return -1;
}
}
 
 
int do_reboot = 0;
int do_reboot = 0;
 
 
/*
/*
 * timer_interrupt() needs to keep up the real-time clock,
 * timer_interrupt() needs to keep up the real-time clock,
 * as well as call the "do_timer()" routine every clocktick
 * as well as call the "do_timer()" routine every clocktick
 */
 */
void timer_interrupt(struct pt_regs * regs)
void timer_interrupt(struct pt_regs * regs)
{
{
        /* last time the cmos clock got updated */
        /* last time the cmos clock got updated */
        static long last_rtc_update=0;
        static long last_rtc_update=0;
 
 
        do_timer(regs);
        do_timer(regs);
 
 
        /*
        /*
         * If we have an externally synchronized Linux clock, then update
         * If we have an externally synchronized Linux clock, then update
         * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
         * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
         * called as close as possible to 500 ms before the new second starts.
         * called as close as possible to 500 ms before the new second starts.
         */
         */
        if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
        if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
            xtime.tv_usec > 500000 - (tick >> 1) &&
            xtime.tv_usec > 500000 - (tick >> 1) &&
            xtime.tv_usec < 500000 + (tick >> 1))
            xtime.tv_usec < 500000 + (tick >> 1))
                if (set_rtc_mmss(xtime.tv_sec) == 0)
                if (set_rtc_mmss(xtime.tv_sec) == 0)
                        last_rtc_update = xtime.tv_sec;
                        last_rtc_update = xtime.tv_sec;
                else
                else
                        last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
                        last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
 
 
}
}
 
 
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
 *
 *
 * [For the Julian calendar (which was used in Russia before 1917,
 * [For the Julian calendar (which was used in Russia before 1917,
 * Britain & colonies before 1752, anywhere else before 1582,
 * Britain & colonies before 1752, anywhere else before 1582,
 * and is still in use by some communities) leave out the
 * and is still in use by some communities) leave out the
 * -year/100+year/400 terms, and add 10.]
 * -year/100+year/400 terms, and add 10.]
 *
 *
 * This algorithm was first published by Gauss (I think).
 * This algorithm was first published by Gauss (I think).
 *
 *
 * WARNING: this function will overflow on 2106-02-07 06:28:16 on
 * WARNING: this function will overflow on 2106-02-07 06:28:16 on
 * machines were long is 32-bit! (However, as time_t is signed, we
 * machines were long is 32-bit! (However, as time_t is signed, we
 * will already get problems at other places on 2038-01-19 03:14:08)
 * will already get problems at other places on 2038-01-19 03:14:08)
 */
 */
static inline unsigned long mktime(unsigned int year, unsigned int mon,
static inline unsigned long mktime(unsigned int year, unsigned int mon,
        unsigned int day, unsigned int hour,
        unsigned int day, unsigned int hour,
        unsigned int min, unsigned int sec)
        unsigned int min, unsigned int sec)
{
{
        if (0 >= (int) (mon -= 2)) {     /* 1..12 -> 11,12,1..10 */
        if (0 >= (int) (mon -= 2)) {     /* 1..12 -> 11,12,1..10 */
                mon += 12;      /* Puts Feb last since it has leap day */
                mon += 12;      /* Puts Feb last since it has leap day */
                year -= 1;
                year -= 1;
        }
        }
        return (((
        return (((
            (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
            (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
              year*365 - 719499
              year*365 - 719499
            )*24 + hour /* now have hours */
            )*24 + hour /* now have hours */
           )*60 + min /* now have minutes */
           )*60 + min /* now have minutes */
          )*60 + sec; /* finally seconds */
          )*60 + sec; /* finally seconds */
}
}
 
 
void time_init(void)
void time_init(void)
{
{
        unsigned int year, mon, day, hour, min, sec;
        unsigned int year, mon, day, hour, min, sec;
 
 
        extern void arch_gettod(int *year, int *mon, int *day, int *hour,
        extern void arch_gettod(int *year, int *mon, int *day, int *hour,
                                int *min, int *sec);
                                int *min, int *sec);
 
 
        arch_gettod (&year, &mon, &day, &hour, &min, &sec);
        arch_gettod (&year, &mon, &day, &hour, &min, &sec);
 
 
        if ((year += 1900) < 1970)
        if ((year += 1900) < 1970)
                year += 100;
                year += 100;
        xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
        xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
        xtime.tv_usec = 0;
        xtime.tv_usec = 0;
 
 
#ifdef CONFIG_M68328
#ifdef CONFIG_M68328
        (*((volatile unsigned short*)0xFFFFF610)) = /*0x1000;*/ 0xd7e4;
        (*((volatile unsigned short*)0xFFFFF610)) = /*0x1000;*/ 0xd7e4;
        (*((volatile unsigned short*)0xFFFFF60c)) = 0x33; /* Reset */
        (*((volatile unsigned short*)0xFFFFF60c)) = 0x33; /* Reset */
        (*((volatile unsigned short*)0xFFFFF60e)) = 0x2;  /* divider */
        (*((volatile unsigned short*)0xFFFFF60e)) = 0x2;  /* divider */
        (*((volatile unsigned long*)0xFFFFF304)) &= ~2;   /* Enable interrupt */
        (*((volatile unsigned long*)0xFFFFF304)) &= ~2;   /* Enable interrupt */
#endif
#endif
#ifdef CONFIG_M68332
#ifdef CONFIG_M68332
        *(volatile unsigned short *)0xfffa22 = 0x0140;  /* ipl 6, vec 0x40 */
        *(volatile unsigned short *)0xfffa22 = 0x0140;  /* ipl 6, vec 0x40 */
        *(volatile unsigned short *)0xfffa24 = 0x00a3;  /* 50 Hz */
        *(volatile unsigned short *)0xfffa24 = 0x00a3;  /* 50 Hz */
#endif
#endif
}
}
 
 
/*
/*
 * This version of gettimeofday has near microsecond resolution.
 * This version of gettimeofday has near microsecond resolution.
 */
 */
void do_gettimeofday(struct timeval *tv)
void do_gettimeofday(struct timeval *tv)
{
{
        unsigned long flags;
        unsigned long flags;
 
 
        save_flags(flags);
        save_flags(flags);
        cli();
        cli();
        *tv = xtime;
        *tv = xtime;
        restore_flags(flags);
        restore_flags(flags);
}
}
 
 
void do_settimeofday(struct timeval *tv)
void do_settimeofday(struct timeval *tv)
{
{
        cli();
        cli();
        /* This is revolting. We need to set the xtime.tv_usec
        /* This is revolting. We need to set the xtime.tv_usec
         * correctly. However, the value in this location is
         * correctly. However, the value in this location is
         * is value at the last tick.
         * is value at the last tick.
         * Discover what correction gettimeofday
         * Discover what correction gettimeofday
         * would have done, and then undo it!
         * would have done, and then undo it!
         */
         */
#if 0    
#if 0    
        tv->tv_usec -= mach_gettimeoffset();
        tv->tv_usec -= mach_gettimeoffset();
#endif
#endif
 
 
        if (tv->tv_usec < 0) {
        if (tv->tv_usec < 0) {
                tv->tv_usec += 1000000;
                tv->tv_usec += 1000000;
                tv->tv_sec--;
                tv->tv_sec--;
        }
        }
 
 
        xtime = *tv;
        xtime = *tv;
        time_state = TIME_BAD;
        time_state = TIME_BAD;
        time_maxerror = MAXPHASE;
        time_maxerror = MAXPHASE;
        time_esterror = MAXPHASE;
        time_esterror = MAXPHASE;
        sti();
        sti();
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.