time.c revision 139738
118334Speter/*- 2169689Skan * Copyright (c) 1999, 2000 390075Sobrien * Intel Corporation. 418334Speter * All rights reserved. 590075Sobrien * 618334Speter * Redistribution and use in source and binary forms, with or without 790075Sobrien * modification, are permitted provided that the following conditions 890075Sobrien * are met: 990075Sobrien * 1090075Sobrien * 1. Redistributions of source code must retain the above copyright 1118334Speter * notice, this list of conditions and the following disclaimer. 1290075Sobrien * 1390075Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1490075Sobrien * notice, this list of conditions and the following disclaimer in the 1590075Sobrien * documentation and/or other materials provided with the distribution. 1618334Speter * 1718334Speter * 3. All advertising materials mentioning features or use of this software 1890075Sobrien * must display the following acknowledgement: 19169689Skan * 20169689Skan * This product includes software developed by Intel Corporation and 2118334Speter * its contributors. 2290075Sobrien * 2390075Sobrien * 4. Neither the name of Intel Corporation or its contributors may be 2418334Speter * used to endorse or promote products derived from this software 2550397Sobrien * without specific prior written permission. 2652284Sobrien * 2752284Sobrien * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' 2890075Sobrien * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29117395Skan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30169689Skan * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE 31169689Skan * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32169689Skan * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3318334Speter * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3490075Sobrien * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3590075Sobrien * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36169689Skan * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 3790075Sobrien * THE POSSIBILITY OF SUCH DAMAGE. 3890075Sobrien */ 3918334Speter 40169689Skan#include <sys/cdefs.h> 41169689Skan__FBSDID("$FreeBSD: head/sys/boot/ia64/ski/time.c 139738 2005-01-05 22:16:58Z imp $"); 42169689Skan 43169689Skan#include <time.h> 44169689Skan#include <sys/time.h> 45169689Skan#include <stand.h> 4690075Sobrien 47169689Skan#include "libski.h" 4890075Sobrien 4950397Sobrien/* 5050397Sobrien// Accurate only for the past couple of centuries; 5118334Speter// that will probably do. 5250397Sobrien// 5350397Sobrien// (#defines From FreeBSD 3.2 lib/libc/stdtime/tzfile.h) 5418334Speter*/ 5590075Sobrien 5690075Sobrien#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) 5790075Sobrien#define SECSPERHOUR ( 60*60 ) 5850397Sobrien#define SECSPERDAY (24 * SECSPERHOUR) 59169689Skan 6018334Speterstruct ssc_time { 6150397Sobrien int Year; 62169689Skan int Month; 6318334Speter int Day; 6450397Sobrien int Hour; 65169689Skan int Minute; 6618334Speter int Second; 6790075Sobrien int Msec; 68169689Skan int Wday; 6990075Sobrien}; 7050397Sobrien 7150397Sobrientime_t 72169689SkanEfiTimeToUnixTime(struct ssc_time *ETime) 7318334Speter{ 7450397Sobrien /* 7550397Sobrien // These arrays give the cumulative number of days up to the first of the 7650397Sobrien // month number used as the index (1 -> 12) for regular and leap years. 7750397Sobrien // The value at index 13 is for the whole year. 7850397Sobrien */ 7950397Sobrien static time_t CumulativeDays[2][14] = { 8050397Sobrien {0, 8150397Sobrien 0, 8250397Sobrien 31, 8350397Sobrien 31 + 28, 84132718Skan 31 + 28 + 31, 8550397Sobrien 31 + 28 + 31 + 30, 8650397Sobrien 31 + 28 + 31 + 30 + 31, 8750397Sobrien 31 + 28 + 31 + 30 + 31 + 30, 8890075Sobrien 31 + 28 + 31 + 30 + 31 + 30 + 31, 8950397Sobrien 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, 9050397Sobrien 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, 91169689Skan 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 92169689Skan 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 9350397Sobrien 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }, 9490075Sobrien {0, 95169689Skan 0, 96169689Skan 31, 9750397Sobrien 31 + 29, 9850397Sobrien 31 + 29 + 31, 9950397Sobrien 31 + 29 + 31 + 30, 10090075Sobrien 31 + 29 + 31 + 30 + 31, 101169689Skan 31 + 29 + 31 + 30 + 31 + 30, 102169689Skan 31 + 29 + 31 + 30 + 31 + 30 + 31, 10350397Sobrien 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31, 10450397Sobrien 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30, 10550397Sobrien 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 10690075Sobrien 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 107169689Skan 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }}; 108169689Skan 10950397Sobrien time_t UTime; 110132718Skan int Year; 111132718Skan 112132718Skan ETime->Year += 1900; 113132718Skan 114132718Skan /* 11590075Sobrien // Do a santity check 11690075Sobrien */ 11752284Sobrien if ( ETime->Year < 1998 || ETime->Year > 2099 || 118169689Skan ETime->Month == 0 || ETime->Month > 12 || 119169689Skan ETime->Day == 0 || ETime->Month > 31 || 12052284Sobrien ETime->Hour > 23 || 121169689Skan ETime->Minute > 59 || 122169689Skan ETime->Second > 59 ) { 12318334Speter return (0); 12452284Sobrien } 125169689Skan 126169689Skan /* 127169689Skan // Years 128169689Skan */ 12918334Speter UTime = 0; 13052284Sobrien for (Year = 1970; Year != ETime->Year; ++Year) { 131169689Skan UTime += (CumulativeDays[isleap(Year)][13] * SECSPERDAY); 13218334Speter } 133169689Skan 134169689Skan /* 135169689Skan // UTime should now be set to 00:00:00 on Jan 1 of the file's year. 13652284Sobrien // 13752284Sobrien // Months 13890075Sobrien */ 13990075Sobrien UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * SECSPERDAY); 14018334Speter 141169689Skan /* 142169689Skan // UTime should now be set to 00:00:00 on the first of the file's month and year 143169689Skan // 144169689Skan // Days -- Don't count the file's day 145169689Skan */ 146169689Skan UTime += (((ETime->Day > 0) ? ETime->Day-1:0) * SECSPERDAY); 147169689Skan 148169689Skan /* 149169689Skan // Hours 150117395Skan */ 151117395Skan UTime += (ETime->Hour * SECSPERHOUR); 152117395Skan 153117395Skan /* 154117395Skan // Minutes 155117395Skan */ 156117395Skan UTime += (ETime->Minute * 60); 157117395Skan 158117395Skan /* 159117395Skan // Seconds 160132718Skan */ 161132718Skan UTime += ETime->Second; 162132718Skan 163169689Skan return UTime; 164169689Skan} 165169689Skan 166169689Skantime_t 167169689Skantime(time_t *tloc) 168169689Skan{ 169169689Skan struct ssc_time time; 170169689Skan 171169689Skan ssc((u_int64_t) &time, 0, 0, 0, SSC_GET_RTC); 172169689Skan 17318334Speter return *tloc = EfiTimeToUnixTime(&time); 17490075Sobrien} 17550397Sobrien