Annotation of Net2/arch/i386/isa/clock.c, revision 1.1.1.2

1.1       root        1: /*-
                      2:  * Copyright (c) 1990 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * William Jolitz and Don Ahn.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by the University of
                     19:  *     California, Berkeley and its contributors.
                     20:  * 4. Neither the name of the University nor the names of its contributors
                     21:  *    may be used to endorse or promote products derived from this software
                     22:  *    without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     34:  * SUCH DAMAGE.
                     35:  *
                     36:  *     @(#)clock.c     7.2 (Berkeley) 5/12/91
1.1.1.2 ! root       37:  *
        !            38:  * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
        !            39:  * --------------------         -----   ----------------------
        !            40:  * CURRENT PATCH LEVEL:         3       00082
        !            41:  * --------------------         -----   ----------------------
        !            42:  *
        !            43:  * 14 Aug 92   Arne Henrik Juul        Added code in the kernel to
        !            44:  *                                     allow for DST in the BIOS.
        !            45:  * 17 Jan 93   Bruce Evans             Fixed leap year and second
        !            46:  *                                     calculations
        !            47:  * 01 Feb 93   Julian Elischer         Added code to for the cpu
        !            48:  *                                     speed independent spinwait()
        !            49:  *                                     function, (used by scsi and others)
1.1       root       50:  */
                     51: 
                     52: /*
                     53:  * Primitive clock interrupt routines.
                     54:  */
                     55: #include "param.h"
1.1.1.2 ! root       56: #include "systm.h"
1.1       root       57: #include "time.h"
                     58: #include "kernel.h"
                     59: #include "machine/segments.h"
                     60: #include "i386/isa/icu.h"
                     61: #include "i386/isa/isa.h"
                     62: #include "i386/isa/rtc.h"
1.1.1.2 ! root       63: #include "i386/isa/timerreg.h"
1.1       root       64: 
                     65: #define DAYST 119
                     66: #define DAYEN 303
1.1.1.2 ! root       67: #define XTALSPEED 1193182
1.1       root       68: 
                     69: startrtclock() {
                     70:        int s;
                     71: 
1.1.1.2 ! root       72:        findcpuspeed();         /* use the clock (while it's free)
        !            73:                                        to find the cpu speed */
1.1       root       74:        /* initialize 8253 clock */
1.1.1.2 ! root       75:        outb(TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
        !            76:        outb (IO_TIMER1, XTALSPEED/hz);
        !            77:        outb (IO_TIMER1, (XTALSPEED/hz)/256);
1.1       root       78: 
                     79:        /* initialize brain-dead battery powered clock */
                     80:        outb (IO_RTC, RTC_STATUSA);
                     81:        outb (IO_RTC+1, 0x26);
                     82:        outb (IO_RTC, RTC_STATUSB);
                     83:        outb (IO_RTC+1, 2);
                     84: 
                     85:        outb (IO_RTC, RTC_DIAG);
                     86:        if (s = inb (IO_RTC+1))
                     87:                printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS);
                     88:        outb (IO_RTC, RTC_DIAG);
                     89:        outb (IO_RTC+1, 0);
                     90: }
                     91: 
1.1.1.2 ! root       92: unsigned int delaycount;       /* calibrated loop variable (1 millisecond) */
        !            93: 
        !            94: #define FIRST_GUESS    0x2000
        !            95: findcpuspeed()
        !            96: {
        !            97:        unsigned char low;
        !            98:        unsigned int remainder;
        !            99: 
        !           100:        /* Put counter in count down mode */
        !           101:        outb(IO_TIMER1+3, 0x34);
        !           102:        outb(IO_TIMER1, 0xff);
        !           103:        outb(IO_TIMER1, 0xff);
        !           104:        delaycount = FIRST_GUESS;
        !           105:        spinwait(1);
        !           106:        /* Read the value left in the counter */
        !           107:        low     = inb(IO_TIMER1);       /* least siginifcant */
        !           108:        remainder = inb(IO_TIMER1);     /* most significant */
        !           109:        remainder = (remainder<<8) + low ;
        !           110:        /* Formula for delaycount is :
        !           111:         *  (loopcount * timer clock speed)/ (counter ticks * 1000)
        !           112:         */
        !           113:        delaycount = (FIRST_GUESS * (XTALSPEED/1000)) / (0xffff-remainder);
        !           114: }
        !           115: 
        !           116: 
        !           117: 
1.1       root      118: /* convert 2 digit BCD number */
                    119: bcd(i)
                    120: int i;
                    121: {
                    122:        return ((i/16)*10 + (i%16));
                    123: }
                    124: 
                    125: /* convert years to seconds (from 1970) */
                    126: unsigned long
                    127: ytos(y)
                    128: int y;
                    129: {
                    130:        int i;
                    131:        unsigned long ret;
                    132: 
1.1.1.2 ! root      133:        ret = 0;
        !           134:        for(i = 1970; i < y; i++) {
1.1       root      135:                if (i % 4) ret += 365*24*60*60;
                    136:                else ret += 366*24*60*60;
                    137:        }
                    138:        return ret;
                    139: }
                    140: 
                    141: /* convert months to seconds */
                    142: unsigned long
                    143: mtos(m,leap)
                    144: int m,leap;
                    145: {
                    146:        int i;
                    147:        unsigned long ret;
                    148: 
                    149:        ret = 0;
                    150:        for(i=1;i<m;i++) {
                    151:                switch(i){
                    152:                case 1: case 3: case 5: case 7: case 8: case 10: case 12:
                    153:                        ret += 31*24*60*60; break;
                    154:                case 4: case 6: case 9: case 11:
                    155:                        ret += 30*24*60*60; break;
                    156:                case 2:
                    157:                        if (leap) ret += 29*24*60*60;
                    158:                        else ret += 28*24*60*60;
                    159:                }
                    160:        }
                    161:        return ret;
                    162: }
                    163: 
                    164: 
                    165: /*
                    166:  * Initialize the time of day register, based on the time base which is, e.g.
                    167:  * from a filesystem.
                    168:  */
                    169: inittodr(base)
                    170:        time_t base;
                    171: {
                    172:        unsigned long sec;
                    173:        int leap,day_week,t,yd;
                    174:        int sa,s;
                    175: 
                    176:        /* do we have a realtime clock present? (otherwise we loop below) */
                    177:        sa = rtcin(RTC_STATUSA);
                    178:        if (sa == 0xff || sa == 0) return;
                    179: 
                    180:        /* ready for a read? */
                    181:        while ((sa&RTCSA_TUP) == RTCSA_TUP)
                    182:                sa = rtcin(RTC_STATUSA);
                    183: 
1.1.1.2 ! root      184:        sec = bcd(rtcin(RTC_YEAR)) + 1900;
        !           185:        if (sec < 1970)
        !           186:                sec += 100;
        !           187:        leap = !(sec % 4); sec = ytos(sec); /* year    */
1.1       root      188:        yd = mtos(bcd(rtcin(RTC_MONTH)),leap); sec += yd;       /* month   */
                    189:        t = (bcd(rtcin(RTC_DAY))-1) * 24*60*60; sec += t; yd += t; /* date    */
                    190:        day_week = rtcin(RTC_WDAY);                             /* day     */
                    191:        sec += bcd(rtcin(RTC_HRS)) * 60*60;                     /* hour    */
                    192:        sec += bcd(rtcin(RTC_MIN)) * 60;                        /* minutes */
                    193:        sec += bcd(rtcin(RTC_SEC));                             /* seconds */
                    194: 
                    195:        /* XXX off by one? Need to calculate DST on SUNDAY */
                    196:        /* Perhaps we should have the RTC hold GMT time to save */
                    197:        /* us the bother of converting. */
1.1.1.2 ! root      198:        yd = yd / (24*60*60);
1.1       root      199:        if ((yd >= DAYST) && ( yd <= DAYEN)) {
                    200:                sec -= 60*60;
                    201:        }
                    202:        sec += tz.tz_minuteswest * 60;
                    203: 
                    204:        time.tv_sec = sec;
                    205: }
                    206: 
                    207: #ifdef garbage
                    208: /*
                    209:  * Initialze the time of day register, based on the time base which is, e.g.
                    210:  * from a filesystem.
                    211:  */
                    212: test_inittodr(base)
                    213:        time_t base;
                    214: {
                    215: 
                    216:        outb(IO_RTC,9); /* year    */
                    217:        printf("%d ",bcd(inb(IO_RTC+1)));
                    218:        outb(IO_RTC,8); /* month   */
                    219:        printf("%d ",bcd(inb(IO_RTC+1)));
                    220:        outb(IO_RTC,7); /* day     */
                    221:        printf("%d ",bcd(inb(IO_RTC+1)));
                    222:        outb(IO_RTC,4); /* hour    */
                    223:        printf("%d ",bcd(inb(IO_RTC+1)));
                    224:        outb(IO_RTC,2); /* minutes */
                    225:        printf("%d ",bcd(inb(IO_RTC+1)));
                    226:        outb(IO_RTC,0); /* seconds */
                    227:        printf("%d\n",bcd(inb(IO_RTC+1)));
                    228: 
                    229:        time.tv_sec = base;
                    230: }
                    231: #endif
                    232: 
                    233: /*
                    234:  * Restart the clock.
                    235:  */
                    236: resettodr()
                    237: {
                    238: }
                    239: 
                    240: /*
                    241:  * Wire clock interrupt in.
                    242:  */
                    243: #define V(s)   __CONCAT(V, s)
                    244: extern V(clk)();
                    245: enablertclock() {
                    246:        INTREN(IRQ0);
                    247:        setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL);
                    248:        splnone();
                    249: }
1.1.1.2 ! root      250: 
        !           251: 
        !           252: 
        !           253: 
        !           254: spinwait(millisecs)
        !           255: int millisecs;         /* number of milliseconds to delay */
        !           256: {
        !           257:        int i, j;
        !           258: 
        !           259:        for (i=0;i<millisecs;i++)
        !           260:                for (j=0;j<delaycount;j++)
        !           261:                        ;
        !           262: }
        !           263: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.