time.c revision 83666
183364Sdfr/* 283364Sdfr * Copyright (c) 1999, 2000 383364Sdfr * Intel Corporation. 483364Sdfr * All rights reserved. 583364Sdfr * 683364Sdfr * Redistribution and use in source and binary forms, with or without 783364Sdfr * modification, are permitted provided that the following conditions 883364Sdfr * are met: 983364Sdfr * 1083364Sdfr * 1. Redistributions of source code must retain the above copyright 1183364Sdfr * notice, this list of conditions and the following disclaimer. 1283364Sdfr * 1383364Sdfr * 2. Redistributions in binary form must reproduce the above copyright 1483364Sdfr * notice, this list of conditions and the following disclaimer in the 1583364Sdfr * documentation and/or other materials provided with the distribution. 1683364Sdfr * 1783364Sdfr * 3. All advertising materials mentioning features or use of this software 1883364Sdfr * must display the following acknowledgement: 1983364Sdfr * 2083364Sdfr * This product includes software developed by Intel Corporation and 2183364Sdfr * its contributors. 2283364Sdfr * 2383364Sdfr * 4. Neither the name of Intel Corporation or its contributors may be 2483364Sdfr * used to endorse or promote products derived from this software 2583364Sdfr * without specific prior written permission. 2683364Sdfr * 2783364Sdfr * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' 2883364Sdfr * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2983364Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3083364Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE 3183364Sdfr * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3283364Sdfr * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3383364Sdfr * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3483364Sdfr * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3583364Sdfr * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3683364Sdfr * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 3783364Sdfr * THE POSSIBILITY OF SUCH DAMAGE. 3883364Sdfr * 3983364Sdfr */ 4083364Sdfr 4183364Sdfr#ifndef lint 4283364Sdfrstatic const char rcsid[] = 4383364Sdfr "$FreeBSD: head/sys/boot/ia64/ski/time.c 83666 2001-09-19 12:12:12Z dfr $"; 4483364Sdfr#endif /* not lint */ 4583364Sdfr 4683364Sdfr#include <time.h> 4783364Sdfr#include <sys/time.h> 4883666Sdfr#include <stand.h> 4983364Sdfr 5083666Sdfr#include "libski.h" 5183666Sdfr 5283364Sdfr/* 5383364Sdfr// Accurate only for the past couple of centuries; 5483364Sdfr// that will probably do. 5583364Sdfr// 5683364Sdfr// (#defines From FreeBSD 3.2 lib/libc/stdtime/tzfile.h) 5783364Sdfr*/ 5883364Sdfr 5983364Sdfr#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) 6083364Sdfr#define SECSPERHOUR ( 60*60 ) 6183364Sdfr#define SECSPERDAY (24 * SECSPERHOUR) 6283364Sdfr 6383666Sdfrstruct ssc_time { 6483666Sdfr int Year; 6583666Sdfr int Month; 6683666Sdfr int Day; 6783666Sdfr int Hour; 6883666Sdfr int Minute; 6983666Sdfr int Second; 7083666Sdfr int Msec; 7183666Sdfr int Wday; 7283666Sdfr}; 7383364Sdfr 7483364Sdfrtime_t 7583666SdfrEfiTimeToUnixTime(struct ssc_time *ETime) 7683666Sdfr{ 7783666Sdfr /* 7883666Sdfr // These arrays give the cumulative number of days up to the first of the 7983666Sdfr // month number used as the index (1 -> 12) for regular and leap years. 8083666Sdfr // The value at index 13 is for the whole year. 8183666Sdfr */ 8283666Sdfr static time_t CumulativeDays[2][14] = { 8383666Sdfr {0, 8483666Sdfr 0, 8583666Sdfr 31, 8683666Sdfr 31 + 28, 8783666Sdfr 31 + 28 + 31, 8883666Sdfr 31 + 28 + 31 + 30, 8983666Sdfr 31 + 28 + 31 + 30 + 31, 9083666Sdfr 31 + 28 + 31 + 30 + 31 + 30, 9183666Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31, 9283666Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, 9383666Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, 9483666Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 9583666Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 9683666Sdfr 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }, 9783666Sdfr {0, 9883666Sdfr 0, 9983666Sdfr 31, 10083666Sdfr 31 + 29, 10183666Sdfr 31 + 29 + 31, 10283666Sdfr 31 + 29 + 31 + 30, 10383666Sdfr 31 + 29 + 31 + 30 + 31, 10483666Sdfr 31 + 29 + 31 + 30 + 31 + 30, 10583666Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31, 10683666Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31, 10783666Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30, 10883666Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 10983666Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 11083666Sdfr 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }}; 11183666Sdfr 11283666Sdfr time_t UTime; 11383666Sdfr int Year; 11483666Sdfr 11583666Sdfr ETime->Year += 1900; 11683666Sdfr 11783666Sdfr /* 11883666Sdfr // Do a santity check 11983666Sdfr */ 12083666Sdfr if ( ETime->Year < 1998 || ETime->Year > 2099 || 12183666Sdfr ETime->Month == 0 || ETime->Month > 12 || 12283666Sdfr ETime->Day == 0 || ETime->Month > 31 || 12383666Sdfr ETime->Hour > 23 || 12483666Sdfr ETime->Minute > 59 || 12583666Sdfr ETime->Second > 59 ) { 12683666Sdfr return (0); 12783666Sdfr } 12883666Sdfr 12983666Sdfr /* 13083666Sdfr // Years 13183666Sdfr */ 13283666Sdfr UTime = 0; 13383666Sdfr for (Year = 1970; Year != ETime->Year; ++Year) { 13483666Sdfr UTime += (CumulativeDays[isleap(Year)][13] * SECSPERDAY); 13583666Sdfr } 13683666Sdfr 13783666Sdfr /* 13883666Sdfr // UTime should now be set to 00:00:00 on Jan 1 of the file's year. 13983666Sdfr // 14083666Sdfr // Months 14183666Sdfr */ 14283666Sdfr UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * SECSPERDAY); 14383666Sdfr 14483666Sdfr /* 14583666Sdfr // UTime should now be set to 00:00:00 on the first of the file's month and year 14683666Sdfr // 14783666Sdfr // Days -- Don't count the file's day 14883666Sdfr */ 14983666Sdfr UTime += (((ETime->Day > 0) ? ETime->Day-1:0) * SECSPERDAY); 15083666Sdfr 15183666Sdfr /* 15283666Sdfr // Hours 15383666Sdfr */ 15483666Sdfr UTime += (ETime->Hour * SECSPERHOUR); 15583666Sdfr 15683666Sdfr /* 15783666Sdfr // Minutes 15883666Sdfr */ 15983666Sdfr UTime += (ETime->Minute * 60); 16083666Sdfr 16183666Sdfr /* 16283666Sdfr // Seconds 16383666Sdfr */ 16483666Sdfr UTime += ETime->Second; 16583666Sdfr 16683666Sdfr return UTime; 16783666Sdfr} 16883666Sdfr 16983666Sdfrtime_t 17083364Sdfrtime(time_t *tloc) 17183364Sdfr{ 17283666Sdfr struct ssc_time time; 17383666Sdfr 17483666Sdfr ssc((u_int64_t) &time, 0, 0, 0, SSC_GET_RTC); 17583666Sdfr 17683666Sdfr return *tloc = EfiTimeToUnixTime(&time); 17783364Sdfr} 178