]> git.proxmox.com Git - mirror_edk2.git/blob - UnixPkg/Sec/UnixThunk.c
874f26fa89ee3af872361417dc52461f9772ab93
[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 - 2009, 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 void
48 settimer_handler (int sig)
49 {
50 struct timeval timeval;
51 UINT64 delta;
52
53 gettimeofday (&timeval, NULL);
54 delta = ((UINT64)timeval.tv_sec * 1000) + (timeval.tv_usec / 1000)
55 - ((UINT64)settimer_timeval.tv_sec * 1000)
56 - (settimer_timeval.tv_usec / 1000);
57 settimer_timeval = timeval;
58
59 if (settimer_callback) {
60 #if defined(__APPLE__) || defined(MDE_CPU_X64)
61 ReverseGasketUint64 (settimer_callback, delta);
62 #else
63 (*settimer_callback)(delta);
64 #endif
65 }
66 }
67
68 VOID
69 SetTimer (UINT64 PeriodMs, VOID (*CallBack)(UINT64 DeltaMs))
70 {
71 struct itimerval timerval;
72 UINT32 remainder;
73
74 if (!settimer_initialized) {
75 struct sigaction act;
76
77 settimer_initialized = 1;
78 act.sa_handler = settimer_handler;
79 act.sa_flags = 0;
80 sigemptyset (&act.sa_mask);
81 if (sigaction (SIGALRM, &act, NULL) != 0) {
82 printf ("SetTimer: sigaction error %s\n", strerror (errno));
83 }
84 if (gettimeofday (&settimer_timeval, NULL) != 0) {
85 printf ("SetTimer: gettimeofday error %s\n", strerror (errno));
86 }
87 }
88 timerval.it_value.tv_sec = DivU64x32(PeriodMs, 1000);
89 DivU64x32Remainder(PeriodMs, 1000, &remainder);
90 timerval.it_value.tv_usec = remainder * 1000;
91 timerval.it_value.tv_sec = DivU64x32(PeriodMs, 1000);
92 timerval.it_interval = timerval.it_value;
93
94 if (setitimer (ITIMER_REAL, &timerval, NULL) != 0) {
95 printf ("SetTimer: setitimer error %s\n", strerror (errno));
96 }
97 settimer_callback = CallBack;
98 }
99
100 void
101 msSleep (unsigned long Milliseconds)
102 {
103 struct timespec rq, rm;
104
105 rq.tv_sec = Milliseconds / 1000;
106 rq.tv_nsec = (Milliseconds % 1000) * 1000000;
107
108 while (nanosleep (&rq, &rm) != -1) {
109 if (errno != EINTR) {
110 break;
111 }
112 rq = rm;
113 }
114
115 }
116
117 void
118 GetLocalTime (EFI_TIME *Time)
119 {
120 struct tm *tm;
121 time_t t;
122
123 t = time (NULL);
124 tm = localtime (&t);
125
126 Time->Year = 1900 + tm->tm_year;
127 Time->Month = tm->tm_mon + 1;
128 Time->Day = tm->tm_mday;
129 Time->Hour = tm->tm_hour;
130 Time->Minute = tm->tm_min;
131 Time->Second = tm->tm_sec;
132 Time->Nanosecond = 0;
133 Time->TimeZone = GetTimeZone ();
134 Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0)
135 | (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0);
136 }
137
138 void
139 TzSet (void)
140 {
141 STATIC int done = 0;
142 if (!done) {
143 tzset ();
144 done = 1;
145 }
146 }
147
148 long
149 GetTimeZone(void)
150 {
151 TzSet ();
152 return timezone;
153 }
154
155 int
156 GetDayLight(void)
157 {
158 TzSet ();
159 return daylight;
160 }
161
162 int
163 GetErrno(void)
164 {
165 return errno;
166 }
167
168
169 extern EFI_STATUS
170 UgaCreate(struct _EFI_UNIX_UGA_IO_PROTOCOL **UgaIo, CONST CHAR16 *Title);
171
172 EFI_UNIX_THUNK_PROTOCOL mUnixThunkTable = {
173 EFI_UNIX_THUNK_PROTOCOL_SIGNATURE,
174 #if defined(__APPLE__) || defined(MDE_CPU_X64)
175 //
176 // Mac OS X requires the stack to be 16-byte aligned for IA-32. So on an OS X build
177 // we add an assembly wrapper that makes sure the stack ges aligned.
178 // This has the nice benfit of being able to run EFI ABI code, like the EFI shell
179 // that is checked in to source control in the OS X version of the emulator
180 //
181 GasketmsSleep, /* Sleep */
182 Gasketexit, /* Exit */
183 GasketSetTimer,
184 GasketGetLocalTime,
185 Gasketgmtime,
186 GasketGetTimeZone,
187 GasketGetDayLight,
188 Gasketpoll,
189 Gasketread,
190 Gasketwrite,
191 Gasketgetenv,
192 Gasketopen,
193 Gasketlseek,
194 Gasketftruncate,
195 Gasketclose,
196 Gasketmkdir,
197 Gasketrmdir,
198 Gasketunlink,
199 GasketGetErrno,
200 Gasketopendir,
201 Gasketrewinddir,
202 Gasketreaddir,
203 Gasketclosedir,
204 Gasketstat,
205 Gasketstatfs,
206 Gasketrename,
207 Gasketmktime,
208 Gasketfsync,
209 Gasketchmod,
210 Gasketutime,
211 Gaskettcflush,
212 GasketUgaCreate,
213 Gasketperror,
214 Gasketioctl,
215 Gasketfcntl,
216 Gasketcfsetispeed,
217 Gasketcfsetospeed,
218 Gaskettcgetattr,
219 Gaskettcsetattr,
220 GasketUnixPeCoffGetEntryPoint,
221 GasketUnixPeCoffRelocateImageExtraAction,
222 GasketUnixPeCoffUnloadImageExtraAction
223
224 #else
225 msSleep, /* Sleep */
226 exit, /* Exit */
227 SetTimer,
228 GetLocalTime,
229 gmtime,
230 GetTimeZone,
231 GetDayLight,
232 (UnixPoll)poll,
233 (UnixRead)read,
234 (UnixWrite)write,
235 getenv,
236 (UnixOpen)open,
237 (UnixSeek)lseek,
238 (UnixFtruncate)ftruncate,
239 close,
240 mkdir,
241 rmdir,
242 unlink,
243 GetErrno,
244 opendir,
245 rewinddir,
246 readdir,
247 closedir,
248 (UnixStat)stat,
249 statfs,
250 rename,
251 mktime,
252 fsync,
253 chmod,
254 utime,
255 tcflush,
256 UgaCreate,
257 perror,
258 ioctl,
259 fcntl,
260 cfsetispeed,
261 cfsetospeed,
262 tcgetattr,
263 tcsetattr,
264 SecPeCoffGetEntryPoint,
265 SecPeCoffRelocateImageExtraAction,
266 SecPeCoffLoaderUnloadImageExtraAction
267 #endif
268 };
269
270
271 EFI_UNIX_THUNK_PROTOCOL *gUnix = &mUnixThunkTable;