1 1.4 scole /* $NetBSD: time.c,v 1.4 2016/08/04 18:07:43 scole Exp $ */ 2 1.1 cherry 3 1.1 cherry /*- 4 1.1 cherry * Copyright (c) 1999, 2000 5 1.1 cherry * Intel Corporation. 6 1.1 cherry * All rights reserved. 7 1.1 cherry * 8 1.1 cherry * Redistribution and use in source and binary forms, with or without 9 1.1 cherry * modification, are permitted provided that the following conditions 10 1.1 cherry * are met: 11 1.1 cherry * 12 1.1 cherry * 1. Redistributions of source code must retain the above copyright 13 1.1 cherry * notice, this list of conditions and the following disclaimer. 14 1.1 cherry * 15 1.1 cherry * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 cherry * notice, this list of conditions and the following disclaimer in the 17 1.1 cherry * documentation and/or other materials provided with the distribution. 18 1.1 cherry * 19 1.1 cherry * 3. All advertising materials mentioning features or use of this software 20 1.1 cherry * must display the following acknowledgement: 21 1.1 cherry * 22 1.1 cherry * This product includes software developed by Intel Corporation and 23 1.1 cherry * its contributors. 24 1.1 cherry * 25 1.1 cherry * 4. Neither the name of Intel Corporation or its contributors may be 26 1.1 cherry * used to endorse or promote products derived from this software 27 1.1 cherry * without specific prior written permission. 28 1.1 cherry * 29 1.1 cherry * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' 30 1.1 cherry * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 1.1 cherry * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 1.1 cherry * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE 33 1.1 cherry * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 34 1.1 cherry * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 35 1.1 cherry * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 36 1.1 cherry * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 37 1.1 cherry * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 1.1 cherry * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 39 1.1 cherry * THE POSSIBILITY OF SUCH DAMAGE. 40 1.1 cherry * 41 1.1 cherry */ 42 1.1 cherry 43 1.1 cherry #include <sys/cdefs.h> 44 1.2 cherry /* __FBSDID("$FreeBSD: src/sys/boot/efi/libefi/time.c,v 1.4 2003/04/03 21:36:29 obrien Exp $"); 45 1.2 cherry */ 46 1.1 cherry #include <efi.h> 47 1.1 cherry #include <efilib.h> 48 1.1 cherry 49 1.1 cherry #include <sys/time.h> 50 1.1 cherry 51 1.4 scole #include <machine/efilib.h> 52 1.4 scole 53 1.1 cherry /* 54 1.1 cherry // Accurate only for the past couple of centuries; 55 1.1 cherry // that will probably do. 56 1.1 cherry // 57 1.1 cherry // (#defines From FreeBSD 3.2 lib/libc/stdtime/tzfile.h) 58 1.1 cherry */ 59 1.1 cherry 60 1.1 cherry #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) 61 1.1 cherry #define SECSPERHOUR ( 60*60 ) 62 1.1 cherry #define SECSPERDAY (24 * SECSPERHOUR) 63 1.1 cherry 64 1.1 cherry time_t 65 1.1 cherry EfiTimeToUnixTime(EFI_TIME *ETime) 66 1.1 cherry { 67 1.1 cherry /* 68 1.1 cherry // These arrays give the cumulative number of days up to the first of the 69 1.1 cherry // month number used as the index (1 -> 12) for regular and leap years. 70 1.1 cherry // The value at index 13 is for the whole year. 71 1.1 cherry */ 72 1.1 cherry static time_t CumulativeDays[2][14] = { 73 1.1 cherry {0, 74 1.1 cherry 0, 75 1.1 cherry 31, 76 1.1 cherry 31 + 28, 77 1.1 cherry 31 + 28 + 31, 78 1.1 cherry 31 + 28 + 31 + 30, 79 1.1 cherry 31 + 28 + 31 + 30 + 31, 80 1.1 cherry 31 + 28 + 31 + 30 + 31 + 30, 81 1.1 cherry 31 + 28 + 31 + 30 + 31 + 30 + 31, 82 1.1 cherry 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, 83 1.1 cherry 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, 84 1.1 cherry 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 85 1.1 cherry 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 86 1.1 cherry 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }, 87 1.1 cherry {0, 88 1.1 cherry 0, 89 1.1 cherry 31, 90 1.1 cherry 31 + 29, 91 1.1 cherry 31 + 29 + 31, 92 1.1 cherry 31 + 29 + 31 + 30, 93 1.1 cherry 31 + 29 + 31 + 30 + 31, 94 1.1 cherry 31 + 29 + 31 + 30 + 31 + 30, 95 1.1 cherry 31 + 29 + 31 + 30 + 31 + 30 + 31, 96 1.1 cherry 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31, 97 1.1 cherry 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30, 98 1.1 cherry 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 99 1.1 cherry 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 100 1.1 cherry 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }}; 101 1.1 cherry 102 1.1 cherry time_t UTime; 103 1.1 cherry int Year; 104 1.1 cherry 105 1.1 cherry /* 106 1.1 cherry // Do a santity check 107 1.1 cherry */ 108 1.1 cherry if ( ETime->Year < 1998 || ETime->Year > 2099 || 109 1.1 cherry ETime->Month == 0 || ETime->Month > 12 || 110 1.1 cherry ETime->Day == 0 || ETime->Month > 31 || 111 1.1 cherry ETime->Hour > 23 || 112 1.1 cherry ETime->Minute > 59 || 113 1.1 cherry ETime->Second > 59 || 114 1.1 cherry ETime->TimeZone < -1440 || 115 1.1 cherry (ETime->TimeZone > 1440 && ETime->TimeZone != 2047) ) { 116 1.1 cherry return (0); 117 1.1 cherry } 118 1.1 cherry 119 1.1 cherry /* 120 1.1 cherry // Years 121 1.1 cherry */ 122 1.1 cherry UTime = 0; 123 1.1 cherry for (Year = 1970; Year != ETime->Year; ++Year) { 124 1.1 cherry UTime += (CumulativeDays[isleap(Year)][13] * SECSPERDAY); 125 1.1 cherry } 126 1.1 cherry 127 1.1 cherry /* 128 1.1 cherry // UTime should now be set to 00:00:00 on Jan 1 of the file's year. 129 1.1 cherry // 130 1.1 cherry // Months 131 1.1 cherry */ 132 1.1 cherry UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * SECSPERDAY); 133 1.1 cherry 134 1.1 cherry /* 135 1.1 cherry // UTime should now be set to 00:00:00 on the first of the file's month and year 136 1.1 cherry // 137 1.1 cherry // Days -- Don't count the file's day 138 1.1 cherry */ 139 1.1 cherry UTime += (((ETime->Day > 0) ? ETime->Day-1:0) * SECSPERDAY); 140 1.1 cherry 141 1.1 cherry /* 142 1.1 cherry // Hours 143 1.1 cherry */ 144 1.1 cherry UTime += (ETime->Hour * SECSPERHOUR); 145 1.1 cherry 146 1.1 cherry /* 147 1.1 cherry // Minutes 148 1.1 cherry */ 149 1.1 cherry UTime += (ETime->Minute * 60); 150 1.1 cherry 151 1.1 cherry /* 152 1.1 cherry // Seconds 153 1.1 cherry */ 154 1.1 cherry UTime += ETime->Second; 155 1.1 cherry 156 1.1 cherry /* 157 1.1 cherry // EFI time is repored in local time. Adjust for any time zone offset to 158 1.1 cherry // get true UT 159 1.1 cherry */ 160 1.1 cherry if ( ETime->TimeZone != EFI_UNSPECIFIED_TIMEZONE ) { 161 1.1 cherry /* 162 1.1 cherry // TimeZone is kept in minues... 163 1.1 cherry */ 164 1.1 cherry UTime += (ETime->TimeZone * 60); 165 1.1 cherry } 166 1.1 cherry 167 1.1 cherry return UTime; 168 1.1 cherry } 169 1.1 cherry 170 1.1 cherry int 171 1.1 cherry EFI_GetTimeOfDay( 172 1.1 cherry OUT struct timeval *tp, 173 1.1 cherry OUT struct timezone *tzp 174 1.1 cherry ) 175 1.1 cherry { 176 1.1 cherry EFI_TIME EfiTime; 177 1.1 cherry EFI_TIME_CAPABILITIES Capabilities; 178 1.1 cherry EFI_STATUS Status; 179 1.1 cherry 180 1.1 cherry /* 181 1.1 cherry // Get time from EFI 182 1.1 cherry */ 183 1.1 cherry 184 1.1 cherry Status = RS->GetTime( &EfiTime, &Capabilities ); 185 1.1 cherry if (EFI_ERROR(Status)) 186 1.1 cherry return (-1); 187 1.1 cherry 188 1.1 cherry /* 189 1.1 cherry // Convert to UNIX time (ie seconds since the epoch 190 1.1 cherry */ 191 1.1 cherry 192 1.1 cherry tp->tv_sec = EfiTimeToUnixTime( &EfiTime ); 193 1.1 cherry tp->tv_usec = 0; /* EfiTime.Nanosecond * 1000; */ 194 1.1 cherry 195 1.1 cherry /* 196 1.1 cherry // Do something with the timezone if needed 197 1.1 cherry */ 198 1.1 cherry 199 1.1 cherry if (tzp) { 200 1.1 cherry tzp->tz_minuteswest = 201 1.1 cherry EfiTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE ? 0 : EfiTime.TimeZone; 202 1.1 cherry /* 203 1.1 cherry // This isn't quit right since it doesn't deal with EFI_TIME_IN_DAYLIGHT 204 1.1 cherry */ 205 1.1 cherry tzp->tz_dsttime = 206 1.1 cherry EfiTime.Daylight & EFI_TIME_ADJUST_DAYLIGHT ? 1 : 0; 207 1.1 cherry } 208 1.1 cherry 209 1.1 cherry return (0); 210 1.1 cherry } 211 1.1 cherry 212 1.1 cherry time_t 213 1.1 cherry time(time_t *tloc) 214 1.1 cherry { 215 1.1 cherry struct timeval tv; 216 1.1 cherry EFI_GetTimeOfDay(&tv, 0); 217 1.1 cherry 218 1.1 cherry if (tloc) 219 1.1 cherry *tloc = tv.tv_sec; 220 1.1 cherry return tv.tv_sec; 221 1.1 cherry } 222 1.1 cherry 223 1.1 cherry time_t 224 1.3 cegger getsecs(void) 225 1.1 cherry { 226 1.1 cherry return time(0); 227 1.1 cherry } 228