]> git.proxmox.com Git - mirror_edk2.git/blob - UnixPkg/Sec/UnixThunk.c
Roll back the changes in revision 14294 since it will cause iSCSI security authentica...
[mirror_edk2.git] / UnixPkg / Sec / UnixThunk.c
1 /*++
2
3 Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>
4 Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 Module Name:
14
15 UnixThunk.c
16
17 Abstract:
18
19 Since the SEC is the only program in our emulation we
20 must use a Tiano mechanism to export APIs to other modules.
21 This is the role of the EFI_UNIX_THUNK_PROTOCOL.
22
23 The mUnixThunkTable exists so that a change to EFI_UNIX_THUNK_PROTOCOL
24 will cause an error in initializing the array if all the member functions
25 are not added. It looks like adding a element to end and not initializing
26 it may cause the table to be initaliized with the members at the end being
27 set to zero. This is bad as jumping to zero will crash.
28
29
30 gUnix is a a public exported global that contains the initialized
31 data.
32
33 --*/
34
35 #include "SecMain.h"
36 #include "Uefi.h"
37 #include "Library/UnixLib.h"
38
39 #if defined(__APPLE__) || defined(MDE_CPU_X64)
40 #include "Gasket.h"
41 #endif
42
43 int settimer_initialized;
44 struct timeval settimer_timeval;
45 void (*settimer_callback)(UINT64 delta);
46
47 BOOLEAN gEmulatorInterruptEnabled = FALSE;
48
49
50 void
51 settimer_handler (int sig)
52 {
53 struct timeval timeval;
54 UINT64 delta;
55
56 gettimeofday (&timeval, NULL);
57 delta = ((UINT64)timeval.tv_sec * 1000) + (timeval.tv_usec / 1000)
58 - ((UINT64)settimer_timeval.tv_sec * 1000)
59 - (settimer_timeval.tv_usec / 1000);
60 settimer_timeval = timeval;
61
62 if (settimer_callback) {
63 #if defined(__APPLE__) || defined(MDE_CPU_X64)
64 ReverseGasketUint64 (settimer_callback, delta);
65 #else
66 (*settimer_callback)(delta);
67 #endif
68 }
69 }
70
71 VOID
72 SetTimer (UINT64 PeriodMs, VOID (*CallBack)(UINT64 DeltaMs))
73 {
74 struct itimerval timerval;
75 UINT32 remainder;
76
77 if (!settimer_initialized) {
78 struct sigaction act;
79
80 settimer_initialized = 1;
81 act.sa_handler = settimer_handler;
82 act.sa_flags = 0;
83 sigemptyset (&act.sa_mask);
84 gEmulatorInterruptEnabled = TRUE;
85 if (sigaction (SIGALRM, &act, NULL) != 0) {
86 printf ("SetTimer: sigaction error %s\n", strerror (errno));
87 }
88 if (gettimeofday (&settimer_timeval, NULL) != 0) {
89 printf ("SetTimer: gettimeofday error %s\n", strerror (errno));
90 }
91 }
92 timerval.it_value.tv_sec = DivU64x32(PeriodMs, 1000);
93 DivU64x32Remainder(PeriodMs, 1000, &remainder);
94 timerval.it_value.tv_usec = remainder * 1000;
95 timerval.it_value.tv_sec = DivU64x32(PeriodMs, 1000);
96 timerval.it_interval = timerval.it_value;
97
98 if (setitimer (ITIMER_REAL, &timerval, NULL) != 0) {
99 printf ("SetTimer: setitimer error %s\n", strerror (errno));
100 }
101 settimer_callback = CallBack;
102 }
103
104
105 void
106 UnixEnableInterrupt (void)
107 {
108 sigset_t sigset;
109
110 gEmulatorInterruptEnabled = TRUE;
111 // Since SetTimer() uses SIGALRM we emulate turning on and off interrupts
112 // by enabling/disabling SIGALRM.
113 sigemptyset (&sigset);
114 sigaddset (&sigset, SIGALRM);
115 sigprocmask (SIG_UNBLOCK, &sigset, NULL);
116 }
117
118
119 void
120 UnixDisableInterrupt (void)
121 {
122 sigset_t sigset;
123
124 // Since SetTimer() uses SIGALRM we emulate turning on and off interrupts
125 // by enabling/disabling SIGALRM.
126 sigemptyset (&sigset);
127 sigaddset (&sigset, SIGALRM);
128 sigprocmask (SIG_BLOCK, &sigset, NULL);
129 gEmulatorInterruptEnabled = FALSE;
130 }
131
132
133 BOOLEAN
134 UnixInterruptEanbled (void)
135 {
136 return gEmulatorInterruptEnabled;
137 }
138
139
140
141 void
142 msSleep (unsigned long Milliseconds)
143 {
144 struct timespec rq, rm;
145 struct timeval start, end;
146 unsigned long MicroSec;
147
148 rq.tv_sec = Milliseconds / 1000;
149 rq.tv_nsec = (Milliseconds % 1000) * 1000000;
150
151 //
152 // nanosleep gets interrupted by our timer tic.
153 // we need to track wall clock time or we will stall for way too long
154 //
155 gettimeofday (&start, NULL);
156 end.tv_sec = start.tv_sec + rq.tv_sec;
157 MicroSec = (start.tv_usec + rq.tv_nsec/1000);
158 end.tv_usec = MicroSec % 1000000;
159 if (MicroSec > 1000000) {
160 end.tv_sec++;
161 }
162
163 while (nanosleep (&rq, &rm) == -1) {
164 if (errno != EINTR) {
165 break;
166 }
167 gettimeofday (&start, NULL);
168 if (start.tv_sec > end.tv_sec) {
169 break;
170 } if ((start.tv_sec == end.tv_sec) && (start.tv_usec > end.tv_usec)) {
171 break;
172 }
173 rq = rm;
174 }
175 }
176
177 void
178 GetLocalTime (EFI_TIME *Time)
179 {
180 struct tm *tm;
181 time_t t;
182
183 t = time (NULL);
184 tm = localtime (&t);
185
186 Time->Year = 1900 + tm->tm_year;
187 Time->Month = tm->tm_mon + 1;
188 Time->Day = tm->tm_mday;
189 Time->Hour = tm->tm_hour;
190 Time->Minute = tm->tm_min;
191 Time->Second = tm->tm_sec;
192 Time->Nanosecond = 0;
193 Time->TimeZone = GetTimeZone ();
194 Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0)
195 | (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0);
196 }
197
198 void
199 TzSet (void)
200 {
201 STATIC int done = 0;
202 if (!done) {
203 tzset ();
204 done = 1;
205 }
206 }
207
208 long
209 GetTimeZone(void)
210 {
211 TzSet ();
212 return timezone;
213 }
214
215 int
216 GetDayLight(void)
217 {
218 TzSet ();
219 return daylight;
220 }
221
222 int
223 GetErrno(void)
224 {
225 return errno;
226 }
227
228
229 extern EFI_STATUS
230 UgaCreate(struct _EFI_UNIX_UGA_IO_PROTOCOL **UgaIo, CONST CHAR16 *Title);
231
232 EFI_UNIX_THUNK_PROTOCOL mUnixThunkTable = {
233 EFI_UNIX_THUNK_PROTOCOL_SIGNATURE,
234 #if defined(__APPLE__) || defined(MDE_CPU_X64)
235 //
236 // Mac OS X requires the stack to be 16-byte aligned for IA-32. So on an OS X build
237 // we add an assembly wrapper that makes sure the stack ges aligned.
238 // This has the nice benfit of being able to run EFI ABI code, like the EFI shell
239 // that is checked in to source control in the OS X version of the emulator
240 //
241 GasketmsSleep, /* Sleep */
242 Gasketexit, /* Exit */
243 GasketSetTimer,
244 GasketGetLocalTime,
245 Gasketgmtime,
246 GasketGetTimeZone,
247 GasketGetDayLight,
248 Gasketpoll,
249 Gasketread,
250 Gasketwrite,
251 Gasketgetenv,
252 Gasketopen,
253 Gasketlseek,
254 Gasketftruncate,
255 Gasketclose,
256 Gasketmkdir,
257 Gasketrmdir,
258 Gasketunlink,
259 GasketGetErrno,
260 Gasketopendir,
261 Gasketrewinddir,
262 Gasketreaddir,
263 Gasketclosedir,
264 Gasketstat,
265 Gasketstatfs,
266 Gasketrename,
267 Gasketmktime,
268 Gasketfsync,
269 Gasketchmod,
270 Gasketutime,
271 Gaskettcflush,
272 GasketUgaCreate,
273 Gasketperror,
274 Gasketioctl,
275 Gasketfcntl,
276 Gasketcfsetispeed,
277 Gasketcfsetospeed,
278 Gaskettcgetattr,
279 Gaskettcsetattr,
280 GasketUnixPeCoffGetEntryPoint,
281 GasketUnixPeCoffRelocateImageExtraAction,
282 GasketUnixPeCoffUnloadImageExtraAction,
283
284 GasketUnixEnableInterrupt,
285 GasketUnixDisableInterrupt,
286
287 Gasketgetifaddrs,
288 Gasketfreeifaddrs,
289 Gasketsocket,
290
291 #else
292 msSleep, /* Sleep */
293 exit, /* Exit */
294 SetTimer,
295 GetLocalTime,
296 gmtime,
297 GetTimeZone,
298 GetDayLight,
299 (UnixPoll)poll,
300 (UnixRead)read,
301 (UnixWrite)write,
302 getenv,
303 (UnixOpen)open,
304 (UnixSeek)lseek,
305 (UnixFtruncate)ftruncate,
306 close,
307 mkdir,
308 rmdir,
309 unlink,
310 GetErrno,
311 opendir,
312 rewinddir,
313 readdir,
314 closedir,
315 (UnixStat)stat,
316 statfs,
317 rename,
318 mktime,
319 fsync,
320 chmod,
321 utime,
322 tcflush,
323 UgaCreate,
324 perror,
325 ioctl,
326 fcntl,
327 cfsetispeed,
328 cfsetospeed,
329 tcgetattr,
330 tcsetattr,
331 SecPeCoffGetEntryPoint,
332 SecPeCoffRelocateImageExtraAction,
333 SecPeCoffLoaderUnloadImageExtraAction,
334 UnixEnableInterrupt,
335 UnixDisableInterrupt,
336 getifaddrs,
337 freeifaddrs,
338 socket
339 #endif
340 };
341
342
343 EFI_UNIX_THUNK_PROTOCOL *gUnix = &mUnixThunkTable;