Annotation of sys/arch/i386/stand/libsa/time.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: time.c,v 1.16 2004/08/17 15:11:31 tom Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 1997 Michael Shalayeff
! 5: * Copyright (c) 1997 Tobias Weingartner
! 6: * All rights reserved.
! 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: *
! 17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 18: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! 19: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 20: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 27: * SUCH DAMAGE.
! 28: *
! 29: */
! 30:
! 31: #include <sys/time.h>
! 32: #include <machine/biosvar.h>
! 33: #include <machine/pio.h>
! 34: #include "libsa.h"
! 35: #include "biosdev.h"
! 36:
! 37: #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
! 38:
! 39: /*
! 40: * Convert from bcd (packed) to int
! 41: */
! 42: static __inline u_int8_t
! 43: bcdtoint(u_int8_t c)
! 44: {
! 45:
! 46: return ((c & 0xf0) / 8) * 5 + (c & 0x0f);
! 47: }
! 48:
! 49: /*
! 50: * Quick compute of time in seconds since the Epoch
! 51: */
! 52: const u_short monthcount[] = {
! 53: 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
! 54: };
! 55:
! 56: static __inline time_t
! 57: compute(int year, u_int8_t month, u_int8_t day, u_int8_t hour,
! 58: u_int8_t min, u_int8_t sec)
! 59: {
! 60: /* Number of days per month */
! 61: register time_t tt;
! 62:
! 63: /* Compute days */
! 64: tt = (year - 1970) * 365 + monthcount[month] + day - 1;
! 65:
! 66: /* Compute for leap year */
! 67: for (month <= 2 ? year-- : 0; year >= 1970; year--)
! 68: if (isleap(year))
! 69: tt++;
! 70:
! 71: /* Plus the time */
! 72: tt = sec + 60 * (min + 60 * (tt * 24 + hour));
! 73:
! 74: return tt;
! 75: }
! 76:
! 77: static int
! 78: bios_time_date(int f, u_int8_t *b)
! 79: {
! 80: __asm __volatile(DOINT(0x1a) "\n\t"
! 81: "setc %b0\n\t"
! 82: "movb %%ch, 0(%2)\n\t"
! 83: "movb %%cl, 1(%2)\n\t"
! 84: "movb %%dh, 2(%2)\n\t"
! 85: "movb %%dl, 3(%2)\n\t"
! 86: : "=a" (f)
! 87: : "0" (f), "p" (b) : "%ecx", "%edx", "cc");
! 88: if (f & 0xff)
! 89: return -1;
! 90: else {
! 91: b[0] = bcdtoint(b[0]);
! 92: b[1] = bcdtoint(b[1]);
! 93: b[2] = bcdtoint(b[2]);
! 94: b[3] = bcdtoint(b[3]);
! 95: return 0;
! 96: }
! 97: }
! 98:
! 99: static __inline int
! 100: biosdate(u_int8_t *b)
! 101: {
! 102: return bios_time_date(4 << 8, b);
! 103: }
! 104:
! 105: static __inline int
! 106: biostime(u_int8_t *b)
! 107: {
! 108: return bios_time_date(2 << 8, b);
! 109: }
! 110:
! 111: /*
! 112: * Return time since epoch
! 113: */
! 114: time_t
! 115: getsecs(void)
! 116: {
! 117: u_int8_t timebuf[4], datebuf[4];
! 118:
! 119: /* Query BIOS for time & date */
! 120: if (!biostime(timebuf) && !biosdate(datebuf)) {
! 121: #ifdef notdef
! 122: int dst;
! 123:
! 124: dst = timebuf[3];
! 125: #endif
! 126: /* Convert to seconds since Epoch */
! 127: return (compute(datebuf[0] * 100 + datebuf[1],
! 128: datebuf[2], datebuf[3],
! 129: timebuf[0], timebuf[1], timebuf[2]));
! 130: } else
! 131: errno = EIO;
! 132:
! 133: return 1;
! 134: }
! 135:
! 136: u_int
! 137: sleep(u_int i)
! 138: {
! 139: register time_t t;
! 140:
! 141: /*
! 142: * Loop for the requested number of seconds, polling BIOS,
! 143: * so that it may handle interrupts.
! 144: */
! 145: for (t = getsecs() + i; getsecs() < t; cnischar());
! 146:
! 147: return 0;
! 148: }
CVSweb