1139738Simp/*- 277943Sdfr * Copyright (c) 1999, 2000 377943Sdfr * Intel Corporation. 477943Sdfr * All rights reserved. 577943Sdfr * 677943Sdfr * Redistribution and use in source and binary forms, with or without 777943Sdfr * modification, are permitted provided that the following conditions 877943Sdfr * are met: 977943Sdfr * 1077943Sdfr * 1. Redistributions of source code must retain the above copyright 1177943Sdfr * notice, this list of conditions and the following disclaimer. 1277943Sdfr * 1377943Sdfr * 2. Redistributions in binary form must reproduce the above copyright 1477943Sdfr * notice, this list of conditions and the following disclaimer in the 1577943Sdfr * documentation and/or other materials provided with the distribution. 1677943Sdfr * 1777943Sdfr * 3. All advertising materials mentioning features or use of this software 1877943Sdfr * must display the following acknowledgement: 1977943Sdfr * 2077943Sdfr * This product includes software developed by Intel Corporation and 2177943Sdfr * its contributors. 2277943Sdfr * 2377943Sdfr * 4. Neither the name of Intel Corporation or its contributors may be 2477943Sdfr * used to endorse or promote products derived from this software 2577943Sdfr * without specific prior written permission. 2677943Sdfr * 2777943Sdfr * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' 2877943Sdfr * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2977943Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3077943Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE 3177943Sdfr * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3277943Sdfr * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3377943Sdfr * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3477943Sdfr * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3577943Sdfr * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3677943Sdfr * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 3777943Sdfr * THE POSSIBILITY OF SUCH DAMAGE. 3877943Sdfr * 3977943Sdfr */ 4077943Sdfr 41113038Sobrien#include <sys/cdefs.h> 42113038Sobrien__FBSDID("$FreeBSD: releng/10.3/sys/boot/efi/libefi/time.c 164010 2006-11-05 22:03:04Z marcel $"); 4378328Sobrien 4477943Sdfr#include <efi.h> 4577943Sdfr#include <efilib.h> 4677943Sdfr 4777943Sdfr#include <time.h> 4877943Sdfr#include <sys/time.h> 4977943Sdfr 5078328Sobrien/* 5177943Sdfr// Accurate only for the past couple of centuries; 5277943Sdfr// that will probably do. 5377943Sdfr// 5477943Sdfr// (#defines From FreeBSD 3.2 lib/libc/stdtime/tzfile.h) 5578328Sobrien*/ 5677943Sdfr 5777943Sdfr#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) 5877943Sdfr#define SECSPERHOUR ( 60*60 ) 5977943Sdfr#define SECSPERDAY (24 * SECSPERHOUR) 6077943Sdfr 6177943Sdfrtime_t 62164010Smarcelefi_time(EFI_TIME *ETime) 6377943Sdfr{ 6478328Sobrien /* 6577943Sdfr // These arrays give the cumulative number of days up to the first of the 6677943Sdfr // month number used as the index (1 -> 12) for regular and leap years. 6777943Sdfr // The value at index 13 is for the whole year. 6878328Sobrien */ 6977943Sdfr static time_t CumulativeDays[2][14] = { 7077943Sdfr {0, 7177943Sdfr 0, 7277943Sdfr 31, 7377943Sdfr 31 + 28, 7477943Sdfr 31 + 28 + 31, 7577943Sdfr 31 + 28 + 31 + 30, 7677943Sdfr 31 + 28 + 31 + 30 + 31, 7777943Sdfr 31 + 28 + 31 + 30 + 31 + 30, 7877943Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31, 7977943Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, 8077943Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, 8177943Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 8277943Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 8377943Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }, 8477943Sdfr {0, 8577943Sdfr 0, 8677943Sdfr 31, 8777943Sdfr 31 + 29, 8877943Sdfr 31 + 29 + 31, 8977943Sdfr 31 + 29 + 31 + 30, 9077943Sdfr 31 + 29 + 31 + 30 + 31, 9177943Sdfr 31 + 29 + 31 + 30 + 31 + 30, 9277943Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31, 9377943Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31, 9477943Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30, 9577943Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 9677943Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 9777943Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }}; 9877943Sdfr 9977943Sdfr time_t UTime; 10077943Sdfr int Year; 10177943Sdfr 10278328Sobrien /* 10377943Sdfr // Do a santity check 10478328Sobrien */ 10577943Sdfr if ( ETime->Year < 1998 || ETime->Year > 2099 || 10677943Sdfr ETime->Month == 0 || ETime->Month > 12 || 10777943Sdfr ETime->Day == 0 || ETime->Month > 31 || 10877943Sdfr ETime->Hour > 23 || 10977943Sdfr ETime->Minute > 59 || 11077943Sdfr ETime->Second > 59 || 11177943Sdfr ETime->TimeZone < -1440 || 11277943Sdfr (ETime->TimeZone > 1440 && ETime->TimeZone != 2047) ) { 11377943Sdfr return (0); 11477943Sdfr } 11577943Sdfr 11678328Sobrien /* 11777943Sdfr // Years 11878328Sobrien */ 11977943Sdfr UTime = 0; 12077943Sdfr for (Year = 1970; Year != ETime->Year; ++Year) { 12177943Sdfr UTime += (CumulativeDays[isleap(Year)][13] * SECSPERDAY); 12277943Sdfr } 12377943Sdfr 12478328Sobrien /* 12578328Sobrien // UTime should now be set to 00:00:00 on Jan 1 of the file's year. 12677943Sdfr // 12777943Sdfr // Months 12878328Sobrien */ 12977943Sdfr UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * SECSPERDAY); 13077943Sdfr 13178328Sobrien /* 13277943Sdfr // UTime should now be set to 00:00:00 on the first of the file's month and year 13377943Sdfr // 13477943Sdfr // Days -- Don't count the file's day 13578328Sobrien */ 13677943Sdfr UTime += (((ETime->Day > 0) ? ETime->Day-1:0) * SECSPERDAY); 13777943Sdfr 13878328Sobrien /* 13977943Sdfr // Hours 14078328Sobrien */ 14177943Sdfr UTime += (ETime->Hour * SECSPERHOUR); 14277943Sdfr 14378328Sobrien /* 14477943Sdfr // Minutes 14578328Sobrien */ 14677943Sdfr UTime += (ETime->Minute * 60); 14777943Sdfr 14878328Sobrien /* 14977943Sdfr // Seconds 15078328Sobrien */ 15177943Sdfr UTime += ETime->Second; 15277943Sdfr 15378328Sobrien /* 15477943Sdfr // EFI time is repored in local time. Adjust for any time zone offset to 15577943Sdfr // get true UT 15678328Sobrien */ 15777943Sdfr if ( ETime->TimeZone != EFI_UNSPECIFIED_TIMEZONE ) { 15878328Sobrien /* 15977943Sdfr // TimeZone is kept in minues... 16078328Sobrien */ 16177943Sdfr UTime += (ETime->TimeZone * 60); 16277943Sdfr } 16377943Sdfr 16477943Sdfr return UTime; 16577943Sdfr} 16677943Sdfr 16777943Sdfrint 16877943SdfrEFI_GetTimeOfDay( 16977943Sdfr OUT struct timeval *tp, 17077943Sdfr OUT struct timezone *tzp 17177943Sdfr ) 17277943Sdfr{ 173164010Smarcel EFI_TIME EfiTime; 17477943Sdfr EFI_TIME_CAPABILITIES Capabilities; 175164010Smarcel EFI_STATUS Status; 17677943Sdfr 17778328Sobrien /* 17877943Sdfr // Get time from EFI 17978328Sobrien */ 18077943Sdfr 181164010Smarcel Status = RS->GetTime(&EfiTime, &Capabilities); 18277943Sdfr if (EFI_ERROR(Status)) 18377943Sdfr return (-1); 18477943Sdfr 18578328Sobrien /* 18677943Sdfr // Convert to UNIX time (ie seconds since the epoch 18778328Sobrien */ 18877943Sdfr 189164010Smarcel tp->tv_sec = efi_time( &EfiTime ); 19078328Sobrien tp->tv_usec = 0; /* EfiTime.Nanosecond * 1000; */ 19177943Sdfr 19278328Sobrien /* 19377943Sdfr // Do something with the timezone if needed 19478328Sobrien */ 19577943Sdfr 19677943Sdfr if (tzp) { 19777943Sdfr tzp->tz_minuteswest = 19877943Sdfr EfiTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE ? 0 : EfiTime.TimeZone; 19978328Sobrien /* 20077943Sdfr // This isn't quit right since it doesn't deal with EFI_TIME_IN_DAYLIGHT 20178328Sobrien */ 20277943Sdfr tzp->tz_dsttime = 20377943Sdfr EfiTime.Daylight & EFI_TIME_ADJUST_DAYLIGHT ? 1 : 0; 20477943Sdfr } 20577943Sdfr 20677943Sdfr return (0); 20777943Sdfr} 20877943Sdfr 20977943Sdfrtime_t 21077943Sdfrtime(time_t *tloc) 21177943Sdfr{ 21277943Sdfr struct timeval tv; 21377943Sdfr EFI_GetTimeOfDay(&tv, 0); 21477943Sdfr 21577943Sdfr if (tloc) 21677943Sdfr *tloc = tv.tv_sec; 21777943Sdfr return tv.tv_sec; 21877943Sdfr} 21983825Sdfr 22083825Sdfrtime_t 22183825Sdfrgetsecs() 22283825Sdfr{ 22383825Sdfr return time(0); 22483825Sdfr} 225