]> git.proxmox.com Git - mirror_edk2.git/blame - UnixPkg/Sec/UnixThunk.c
Use PCD for PMM size and EndOpromShadowAddress to remove hard code value in CSM module.
[mirror_edk2.git] / UnixPkg / Sec / UnixThunk.c
CommitLineData
804405e7 1/*++
2
f9b8ab56 3Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>
2ff79f2e 4Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
5This program and the accompanying materials
6are licensed and made available under the terms and conditions of the BSD License
7which accompanies this distribution. The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
804405e7 12
13Module Name:
14
15 UnixThunk.c
16
17Abstract:
18
2ff79f2e 19 Since the SEC is the only program in our emulation we
804405e7 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.
2ff79f2e 28
804405e7 29
30 gUnix is a a public exported global that contains the initialized
31 data.
32
33--*/
34
35#include "SecMain.h"
b67f2798 36#include "Uefi.h"
804405e7 37#include "Library/UnixLib.h"
38
3ff2e324 39#if defined(__APPLE__) || defined(MDE_CPU_X64)
7ee3b613
A
40#include "Gasket.h"
41#endif
42
7492c63d 43int settimer_initialized;
44struct timeval settimer_timeval;
45void (*settimer_callback)(UINT64 delta);
804405e7 46
2ff79f2e 47BOOLEAN gEmulatorInterruptEnabled = FALSE;
48
49
7492c63d 50void
804405e7 51settimer_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)
2ff79f2e 58 - ((UINT64)settimer_timeval.tv_sec * 1000)
804405e7 59 - (settimer_timeval.tv_usec / 1000);
60 settimer_timeval = timeval;
2ff79f2e 61
b9c8e50e 62 if (settimer_callback) {
3ff2e324 63#if defined(__APPLE__) || defined(MDE_CPU_X64)
2ec364f9 64 ReverseGasketUint64 (settimer_callback, delta);
b9c8e50e 65#else
2ff79f2e 66 (*settimer_callback)(delta);
b9c8e50e 67#endif
68 }
804405e7 69}
70
804405e7 71VOID
72SetTimer (UINT64 PeriodMs, VOID (*CallBack)(UINT64 DeltaMs))
73{
74 struct itimerval timerval;
73aa7f04 75 UINT32 remainder;
804405e7 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);
2ff79f2e 84 gEmulatorInterruptEnabled = TRUE;
804405e7 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 }
73aa7f04 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);
804405e7 96 timerval.it_interval = timerval.it_value;
2ff79f2e 97
804405e7 98 if (setitimer (ITIMER_REAL, &timerval, NULL) != 0) {
99 printf ("SetTimer: setitimer error %s\n", strerror (errno));
100 }
101 settimer_callback = CallBack;
102}
103
2ff79f2e 104
105void
106UnixEnableInterrupt (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
119void
120UnixDisableInterrupt (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
133BOOLEAN
134UnixInterruptEanbled (void)
135{
136 return gEmulatorInterruptEnabled;
137}
138
139
140
804405e7 141void
142msSleep (unsigned long Milliseconds)
143{
b9c8e50e 144 struct timespec rq, rm;
b5b1aca9 145 struct timeval start, end;
146 unsigned long MicroSec;
147
b9c8e50e 148 rq.tv_sec = Milliseconds / 1000;
149 rq.tv_nsec = (Milliseconds % 1000) * 1000000;
804405e7 150
b5b1aca9 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) {
b9c8e50e 164 if (errno != EINTR) {
165 break;
166 }
b5b1aca9 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 }
b9c8e50e 173 rq = rm;
2ff79f2e 174 }
804405e7 175}
176
177void
178GetLocalTime (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;
be5d189f 187 Time->Month = tm->tm_mon + 1;
804405e7 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;
bb111c23 193 Time->TimeZone = GetTimeZone ();
804405e7 194 Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0)
195 | (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0);
196}
197
7492c63d 198void
804405e7 199TzSet (void)
200{
7492c63d 201 STATIC int done = 0;
804405e7 202 if (!done) {
203 tzset ();
204 done = 1;
205 }
206}
207
208long
209GetTimeZone(void)
210{
211 TzSet ();
212 return timezone;
213}
214
215int
216GetDayLight(void)
217{
218 TzSet ();
219 return daylight;
220}
221
222int
223GetErrno(void)
224{
225 return errno;
226}
227
ccd55824 228
804405e7 229extern EFI_STATUS
230UgaCreate(struct _EFI_UNIX_UGA_IO_PROTOCOL **UgaIo, CONST CHAR16 *Title);
231
232EFI_UNIX_THUNK_PROTOCOL mUnixThunkTable = {
233 EFI_UNIX_THUNK_PROTOCOL_SIGNATURE,
3ff2e324 234#if defined(__APPLE__) || defined(MDE_CPU_X64)
ccd55824 235//
236// Mac OS X requires the stack to be 16-byte aligned for IA-32. So on an OS X build
2ff79f2e 237// we add an assembly wrapper that makes sure the stack ges aligned.
ccd55824 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,
b9c8e50e 248 Gasketpoll,
249 Gasketread,
250 Gasketwrite,
ccd55824 251 Gasketgetenv,
b9c8e50e 252 Gasketopen,
253 Gasketlseek,
254 Gasketftruncate,
ccd55824 255 Gasketclose,
256 Gasketmkdir,
257 Gasketrmdir,
258 Gasketunlink,
259 GasketGetErrno,
260 Gasketopendir,
b9c8e50e 261 Gasketrewinddir,
ccd55824 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,
2ff79f2e 280 GasketUnixPeCoffGetEntryPoint,
281 GasketUnixPeCoffRelocateImageExtraAction,
282 GasketUnixPeCoffUnloadImageExtraAction,
283
284 GasketUnixEnableInterrupt,
285 GasketUnixDisableInterrupt,
286
287 Gasketgetifaddrs,
288 Gasketfreeifaddrs,
289 Gasketsocket,
ccd55824 290
291#else
804405e7 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,
ccd55824 304 (UnixSeek)lseek,
305 (UnixFtruncate)ftruncate,
804405e7 306 close,
307 mkdir,
308 rmdir,
309 unlink,
310 GetErrno,
311 opendir,
312 rewinddir,
313 readdir,
314 closedir,
7ee3b613 315 (UnixStat)stat,
804405e7 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,
398b646f 330 tcsetattr,
ccd55824 331 SecPeCoffGetEntryPoint,
332 SecPeCoffRelocateImageExtraAction,
2ff79f2e 333 SecPeCoffLoaderUnloadImageExtraAction,
334 UnixEnableInterrupt,
335 UnixDisableInterrupt,
336 getifaddrs,
337 freeifaddrs,
338 socket
ccd55824 339#endif
804405e7 340};
341
342
343EFI_UNIX_THUNK_PROTOCOL *gUnix = &mUnixThunkTable;