]> git.proxmox.com Git - mirror_edk2.git/blob - UnixPkg/Sec/UnixThunk.c
Adding Simple Pointer, GOP, SimpleTextInEx, and Networking protocols to the emulator...
[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
146 rq.tv_sec = Milliseconds / 1000;
147 rq.tv_nsec = (Milliseconds % 1000) * 1000000;
148
149 while (nanosleep (&rq, &rm) != -1) {
150 if (errno != EINTR) {
151 break;
152 }
153 rq = rm;
154 }
155
156 }
157
158 void
159 GetLocalTime (EFI_TIME *Time)
160 {
161 struct tm *tm;
162 time_t t;
163
164 t = time (NULL);
165 tm = localtime (&t);
166
167 Time->Year = 1900 + tm->tm_year;
168 Time->Month = tm->tm_mon + 1;
169 Time->Day = tm->tm_mday;
170 Time->Hour = tm->tm_hour;
171 Time->Minute = tm->tm_min;
172 Time->Second = tm->tm_sec;
173 Time->Nanosecond = 0;
174 Time->TimeZone = GetTimeZone ();
175 Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0)
176 | (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0);
177 }
178
179 void
180 TzSet (void)
181 {
182 STATIC int done = 0;
183 if (!done) {
184 tzset ();
185 done = 1;
186 }
187 }
188
189 long
190 GetTimeZone(void)
191 {
192 TzSet ();
193 return timezone;
194 }
195
196 int
197 GetDayLight(void)
198 {
199 TzSet ();
200 return daylight;
201 }
202
203 int
204 GetErrno(void)
205 {
206 return errno;
207 }
208
209
210 extern EFI_STATUS
211 UgaCreate(struct _EFI_UNIX_UGA_IO_PROTOCOL **UgaIo, CONST CHAR16 *Title);
212
213 EFI_UNIX_THUNK_PROTOCOL mUnixThunkTable = {
214 EFI_UNIX_THUNK_PROTOCOL_SIGNATURE,
215 #if defined(__APPLE__) || defined(MDE_CPU_X64)
216 //
217 // Mac OS X requires the stack to be 16-byte aligned for IA-32. So on an OS X build
218 // we add an assembly wrapper that makes sure the stack ges aligned.
219 // This has the nice benfit of being able to run EFI ABI code, like the EFI shell
220 // that is checked in to source control in the OS X version of the emulator
221 //
222 GasketmsSleep, /* Sleep */
223 Gasketexit, /* Exit */
224 GasketSetTimer,
225 GasketGetLocalTime,
226 Gasketgmtime,
227 GasketGetTimeZone,
228 GasketGetDayLight,
229 Gasketpoll,
230 Gasketread,
231 Gasketwrite,
232 Gasketgetenv,
233 Gasketopen,
234 Gasketlseek,
235 Gasketftruncate,
236 Gasketclose,
237 Gasketmkdir,
238 Gasketrmdir,
239 Gasketunlink,
240 GasketGetErrno,
241 Gasketopendir,
242 Gasketrewinddir,
243 Gasketreaddir,
244 Gasketclosedir,
245 Gasketstat,
246 Gasketstatfs,
247 Gasketrename,
248 Gasketmktime,
249 Gasketfsync,
250 Gasketchmod,
251 Gasketutime,
252 Gaskettcflush,
253 GasketUgaCreate,
254 Gasketperror,
255 Gasketioctl,
256 Gasketfcntl,
257 Gasketcfsetispeed,
258 Gasketcfsetospeed,
259 Gaskettcgetattr,
260 Gaskettcsetattr,
261 GasketUnixPeCoffGetEntryPoint,
262 GasketUnixPeCoffRelocateImageExtraAction,
263 GasketUnixPeCoffUnloadImageExtraAction,
264
265 GasketUnixEnableInterrupt,
266 GasketUnixDisableInterrupt,
267
268 Gasketgetifaddrs,
269 Gasketfreeifaddrs,
270 Gasketsocket,
271
272 #else
273 msSleep, /* Sleep */
274 exit, /* Exit */
275 SetTimer,
276 GetLocalTime,
277 gmtime,
278 GetTimeZone,
279 GetDayLight,
280 (UnixPoll)poll,
281 (UnixRead)read,
282 (UnixWrite)write,
283 getenv,
284 (UnixOpen)open,
285 (UnixSeek)lseek,
286 (UnixFtruncate)ftruncate,
287 close,
288 mkdir,
289 rmdir,
290 unlink,
291 GetErrno,
292 opendir,
293 rewinddir,
294 readdir,
295 closedir,
296 (UnixStat)stat,
297 statfs,
298 rename,
299 mktime,
300 fsync,
301 chmod,
302 utime,
303 tcflush,
304 UgaCreate,
305 perror,
306 ioctl,
307 fcntl,
308 cfsetispeed,
309 cfsetospeed,
310 tcgetattr,
311 tcsetattr,
312 SecPeCoffGetEntryPoint,
313 SecPeCoffRelocateImageExtraAction,
314 SecPeCoffLoaderUnloadImageExtraAction,
315 UnixEnableInterrupt,
316 UnixDisableInterrupt,
317 getifaddrs,
318 freeifaddrs,
319 socket
320 #endif
321 };
322
323
324 EFI_UNIX_THUNK_PROTOCOL *gUnix = &mUnixThunkTable;