TianoCore EDK2 master
Loading...
Searching...
No Matches
TimerWrapper.c
Go to the documentation of this file.
1
10#include <Uefi.h>
11#include <CrtLibSupport.h>
14
15//
16// -- Time Management Routines --
17//
18
19#define SECSPERMIN (60)
20#define SECSPERHOUR (60 * 60)
21#define SECSPERDAY (24 * SECSPERHOUR)
22
23long timezone;
24
25//
26// The arrays give the cumulative number of days up to the first of the
27// month number used as the index (1 -> 12) for regular and leap years.
28// The value at index 13 is for the whole year.
29//
30UINTN CumulativeDays[2][14] = {
31 {
32 0,
33 0,
34 31,
35 31 + 28,
36 31 + 28 + 31,
37 31 + 28 + 31 + 30,
38 31 + 28 + 31 + 30 + 31,
39 31 + 28 + 31 + 30 + 31 + 30,
40 31 + 28 + 31 + 30 + 31 + 30 + 31,
41 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
42 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
43 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
44 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
45 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
46 },
47 {
48 0,
49 0,
50 31,
51 31 + 29,
52 31 + 29 + 31,
53 31 + 29 + 31 + 30,
54 31 + 29 + 31 + 30 + 31,
55 31 + 29 + 31 + 30 + 31 + 30,
56 31 + 29 + 31 + 30 + 31 + 30 + 31,
57 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
58 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
59 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
60 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
61 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
62 }
63};
64
65/* Check the year is leap or not. */
66// BOOLEAN IsLeap(
67// INTN timer
68// )
69BOOLEAN
70IsLeap (
71 time_t timer
72 )
73{
74 INT64 Remainder1;
75 INT64 Remainder2;
76 INT64 Remainder3;
77
78 DivS64x64Remainder (timer, 4, &Remainder1);
79 DivS64x64Remainder (timer, 100, &Remainder2);
80 DivS64x64Remainder (timer, 400, &Remainder3);
81
82 return (Remainder1 == 0 && (Remainder2 != 0 || Remainder3 == 0));
83}
84
86time_t
87CalculateTimeT (
88 EFI_TIME *Time
89 )
90{
91 time_t CalTime;
92 UINTN Year;
93
94 //
95 // Years Handling
96 // UTime should now be set to 00:00:00 on Jan 1 of the current year.
97 //
98 for (Year = 1970, CalTime = 0; Year != Time->Year; Year++) {
99 CalTime = CalTime + (time_t)(CumulativeDays[IsLeap (Year)][13] * SECSPERDAY);
100 }
101
102 //
103 // Add in number of seconds for current Month, Day, Hour, Minute, Seconds, and TimeZone adjustment
104 //
105 CalTime = CalTime +
106 (time_t)((Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) ? (Time->TimeZone * 60) : 0) +
107 (time_t)(CumulativeDays[IsLeap (Time->Year)][Time->Month] * SECSPERDAY) +
108 (time_t)(((Time->Day > 0) ? Time->Day - 1 : 0) * SECSPERDAY) +
109 (time_t)(Time->Hour * SECSPERHOUR) +
110 (time_t)(Time->Minute * 60) +
111 (time_t)Time->Second;
112
113 return CalTime;
114}
115
116/* Get the system time as seconds elapsed since midnight, January 1, 1970. */
117// INTN time(
118// INTN *timer
119// )
120time_t
121time (
122 time_t *timer
123 )
124{
125 EFI_STATUS Status;
126 EFI_TIME Time;
127 time_t CalTime;
128
129 //
130 // Get the current time and date information
131 //
132 Status = gRT->GetTime (&Time, NULL);
133 if (EFI_ERROR (Status) || (Time.Year < 1970)) {
134 return 0;
135 }
136
137 CalTime = CalculateTimeT (&Time);
138
139 if (timer != NULL) {
140 *timer = CalTime;
141 }
142
143 return CalTime;
144}
145
146time_t
147mktime (
148 struct tm *t
149 )
150{
151 EFI_TIME Time = {
152 .Year = (UINT16)t->tm_year,
153 .Month = (UINT8)t->tm_mon,
154 .Day = (UINT8)t->tm_mday,
155 .Hour = (UINT8)t->tm_hour,
156 .Minute = (UINT8)t->tm_min,
157 .Second = (UINT8)t->tm_sec,
158 .TimeZone = EFI_UNSPECIFIED_TIMEZONE,
159 };
160
161 return CalculateTimeT (&Time);
162}
163
164//
165// Convert a time value from type time_t to struct tm.
166//
167struct tm *
168gmtime (
169 const time_t *timer
170 )
171{
172 struct tm *GmTime;
173 UINT64 DayNo;
174 UINT64 DayRemainder;
175 time_t Year;
176 time_t YearNo;
177 UINT32 TotalDays;
178 UINT32 MonthNo;
179 INT64 Remainder;
180
181 if (timer == NULL) {
182 return NULL;
183 }
184
185 GmTime = malloc (sizeof (struct tm));
186 if (GmTime == NULL) {
187 return NULL;
188 }
189
190 ZeroMem ((VOID *)GmTime, (UINTN)sizeof (struct tm));
191
192 DayNo = (UINT64)DivS64x64Remainder (*timer, SECSPERDAY, &Remainder);
193 DayRemainder = (UINT64)Remainder;
194
195 DivS64x64Remainder (DayRemainder, SECSPERMIN, &Remainder);
196 GmTime->tm_sec = (int)Remainder;
197 DivS64x64Remainder (DayRemainder, SECSPERHOUR, &Remainder);
198 GmTime->tm_min = (int)DivS64x64Remainder (Remainder, SECSPERMIN, NULL);
199 GmTime->tm_hour = (int)DivS64x64Remainder (DayRemainder, SECSPERHOUR, NULL);
200 DivS64x64Remainder ((DayNo + 4), 7, &Remainder);
201 GmTime->tm_wday = (int)Remainder;
202
203 for (Year = 1970, YearNo = 0; DayNo > 0; Year++) {
204 TotalDays = (UINT32)(IsLeap (Year) ? 366 : 365);
205 if (DayNo >= TotalDays) {
206 DayNo = (UINT64)(DayNo - TotalDays);
207 YearNo++;
208 } else {
209 break;
210 }
211 }
212
213 GmTime->tm_year = (int)(YearNo + (1970 - 1900));
214 GmTime->tm_yday = (int)DayNo;
215
216 for (MonthNo = 12; MonthNo > 1; MonthNo--) {
217 if (DayNo >= CumulativeDays[IsLeap (Year)][MonthNo]) {
218 DayNo = (UINT64)(DayNo - (UINT32)(CumulativeDays[IsLeap (Year)][MonthNo]));
219 break;
220 }
221 }
222
223 GmTime->tm_mon = (int)MonthNo - 1;
224 GmTime->tm_mday = (int)DayNo + 1;
225
226 GmTime->tm_isdst = 0;
227 GmTime->tm_gmtoff = 0;
228 GmTime->tm_zone = NULL;
229
230 return GmTime;
231}
232
233unsigned int
234sleep (
235 unsigned int seconds
236 )
237{
238 gBS->Stall (seconds * 1000 * 1000);
239 return 0;
240}
241
242int
243gettimeofday (
244 struct timeval *tv,
245 struct timezone *tz
246 )
247{
248 tv->tv_sec = (long)time (NULL);
249 tv->tv_usec = 0;
250 return 0;
251}
UINT64 UINTN
INT64 EFIAPI DivS64x64Remainder(IN INT64 Dividend, IN INT64 Divisor, OUT INT64 *Remainder OPTIONAL)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
time_t time(time_t *)
struct tm * gmtime(const time_t *)
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
EFI_BOOT_SERVICES * gBS
#define EFI_UNSPECIFIED_TIMEZONE
Definition: UefiSpec.h:58