| File: | src/sys/arch/amd64/stand/fdboot/../libsa/time.c |
| Warning: | line 91, column 10 1st function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: time.c,v 1.5 2014/09/23 17:59:25 brad 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) ((((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 | return ((c & 0xf0) / 8) * 5 + (c & 0x0f); | |||
| 46 | } | |||
| 47 | ||||
| 48 | /* | |||
| 49 | * Quick compute of time in seconds since the Epoch | |||
| 50 | */ | |||
| 51 | const u_short monthcount[] = { | |||
| 52 | 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 | |||
| 53 | }; | |||
| 54 | ||||
| 55 | static __inline time_t | |||
| 56 | compute(int year, u_int8_t month, u_int8_t day, u_int8_t hour, | |||
| 57 | u_int8_t min, u_int8_t sec) | |||
| 58 | { | |||
| 59 | /* Number of days per month */ | |||
| 60 | register time_t tt; | |||
| 61 | ||||
| 62 | /* Compute days */ | |||
| 63 | tt = (year - 1970) * 365 + monthcount[month] + day - 1; | |||
| 64 | ||||
| 65 | /* Compute for leap year */ | |||
| 66 | for (month <= 2 ? year-- : 0; year >= 1970; year--) | |||
| 67 | if (isleap(year)((((year) % 4) == 0 && ((year) % 100) != 0) || ((year ) % 400) == 0)) | |||
| 68 | tt++; | |||
| 69 | ||||
| 70 | /* Plus the time */ | |||
| 71 | tt = sec + 60 * (min + 60 * (tt * 24 + hour)); | |||
| 72 | ||||
| 73 | return tt; | |||
| 74 | } | |||
| 75 | ||||
| 76 | static int | |||
| 77 | bios_time_date(int f, u_int8_t *b) | |||
| 78 | { | |||
| 79 | __asm volatile(DOINT(0x1a)"int $0x20+(" "0x1a" ")" "\n\t" | |||
| 80 | "setc %b0\n\t" | |||
| 81 | "movb %%ch, 0(%2)\n\t" | |||
| 82 | "movb %%cl, 1(%2)\n\t" | |||
| 83 | "movb %%dh, 2(%2)\n\t" | |||
| 84 | "movb %%dl, 3(%2)\n\t" | |||
| 85 | : "=a" (f) | |||
| 86 | : "0" (f), "r" (b) : "%ecx", "%edx", "cc"); | |||
| 87 | ||||
| 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], datebuf[2], | |||
| 128 | datebuf[3], timebuf[0], timebuf[1], timebuf[2]); | |||
| 129 | } else | |||
| 130 | errno = EIO5; | |||
| 131 | ||||
| 132 | return 1; | |||
| 133 | } | |||
| 134 | ||||
| 135 | u_int | |||
| 136 | sleep(u_int i) | |||
| 137 | { | |||
| 138 | register time_t t; | |||
| 139 | ||||
| 140 | /* | |||
| 141 | * Loop for the requested number of seconds, polling BIOS, | |||
| 142 | * so that it may handle interrupts. | |||
| 143 | */ | |||
| 144 | for (t = getsecs() + i; getsecs() < t; cnischar()) | |||
| ||||
| 145 | ; | |||
| 146 | ||||
| 147 | return 0; | |||
| 148 | } |