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