-/*++ @file
- Since the SEC is the only program in our emulation we
- must use a UEFI/PI mechanism to export APIs to other modules.
- This is the role of the EFI_EMU_THUNK_PROTOCOL.
-
- The mUnixThunkTable exists so that a change to EFI_EMU_THUNK_PROTOCOL
- will cause an error in initializing the array if all the member functions
- are not added. It looks like adding a element to end and not initializing
- it may cause the table to be initaliized with the members at the end being
- set to zero. This is bad as jumping to zero will crash.
-
-Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>
-Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.<BR>
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "Host.h"
-
-#ifdef __APPLE__
-#define DebugAssert _Mangle__DebugAssert
-
-#include <assert.h>
-#include <CoreServices/CoreServices.h>
-#include <mach/mach.h>
-#include <mach/mach_time.h>
-
-#undef DebugAssert
-#endif
-
-int settimer_initialized;
-struct timeval settimer_timeval;
-void (*settimer_callback)(UINT64 delta);
-
-BOOLEAN gEmulatorInterruptEnabled = FALSE;
-
-
-UINTN
-SecWriteStdErr (
- IN UINT8 *Buffer,
- IN UINTN NumberOfBytes
- )
-{
- ssize_t Return;
-
- Return = write (STDERR_FILENO, (const void *)Buffer, (size_t)NumberOfBytes);
-
- return (Return == -1) ? 0 : Return;
-}
-
-
-EFI_STATUS
-SecConfigStdIn (
- VOID
- )
-{
- struct termios tty;
-
- //
- // Need to turn off line buffering, ECHO, and make it unbuffered.
- //
- tcgetattr (STDIN_FILENO, &tty);
- tty.c_lflag &= ~(ICANON | ECHO);
- tcsetattr (STDIN_FILENO, TCSANOW, &tty);
-
-// setvbuf (STDIN_FILENO, NULL, _IONBF, 0);
-
- // now ioctl FIONREAD will do what we need
- return EFI_SUCCESS;
-}
-
-UINTN
-SecWriteStdOut (
- IN UINT8 *Buffer,
- IN UINTN NumberOfBytes
- )
-{
- ssize_t Return;
-
- Return = write (STDOUT_FILENO, (const void *)Buffer, (size_t)NumberOfBytes);
-
- return (Return == -1) ? 0 : Return;
-}
-
-UINTN
-SecReadStdIn (
- IN UINT8 *Buffer,
- IN UINTN NumberOfBytes
- )
-{
- ssize_t Return;
-
- Return = read (STDIN_FILENO, Buffer, (size_t)NumberOfBytes);
-
- return (Return == -1) ? 0 : Return;
-}
-
-BOOLEAN
-SecPollStdIn (
- VOID
- )
-{
- int Result;
- int Bytes;
-
- Result = ioctl (STDIN_FILENO, FIONREAD, &Bytes);
- if (Result == -1) {
- return FALSE;
- }
-
- return (BOOLEAN)(Bytes > 0);
-}
-
-
-VOID *
-SecMalloc (
- IN UINTN Size
- )
-{
- return malloc ((size_t)Size);
-}
-
-VOID *
-SecValloc (
- IN UINTN Size
- )
-{
- return valloc ((size_t)Size);
-}
-
-BOOLEAN
-SecFree (
- IN VOID *Ptr
- )
-{
- if (EfiSystemMemoryRange (Ptr)) {
- // If an address range is in the EFI memory map it was alloced via EFI.
- // So don't free those ranges and let the caller know.
- return FALSE;
- }
-
- free (Ptr);
- return TRUE;
-}
-
-
-void
-settimer_handler (int sig)
-{
- struct timeval timeval;
- UINT64 delta;
-
- gettimeofday (&timeval, NULL);
- delta = ((UINT64)timeval.tv_sec * 1000) + (timeval.tv_usec / 1000)
- - ((UINT64)settimer_timeval.tv_sec * 1000)
- - (settimer_timeval.tv_usec / 1000);
- settimer_timeval = timeval;
-
- if (settimer_callback) {
- ReverseGasketUint64 (settimer_callback, delta);
- }
-}
-
-VOID
-SecSetTimer (
- IN UINT64 PeriodMs,
- IN EMU_SET_TIMER_CALLBACK CallBack
- )
-{
- struct itimerval timerval;
- UINT32 remainder;
-
- if (!settimer_initialized) {
- struct sigaction act;
-
- settimer_initialized = 1;
- act.sa_handler = settimer_handler;
- act.sa_flags = 0;
- sigemptyset (&act.sa_mask);
- gEmulatorInterruptEnabled = TRUE;
- if (sigaction (SIGALRM, &act, NULL) != 0) {
- printf ("SetTimer: sigaction error %s\n", strerror (errno));
- }
- if (gettimeofday (&settimer_timeval, NULL) != 0) {
- printf ("SetTimer: gettimeofday error %s\n", strerror (errno));
- }
- }
- timerval.it_value.tv_sec = DivU64x32(PeriodMs, 1000);
- DivU64x32Remainder(PeriodMs, 1000, &remainder);
- timerval.it_value.tv_usec = remainder * 1000;
- timerval.it_value.tv_sec = DivU64x32(PeriodMs, 1000);
- timerval.it_interval = timerval.it_value;
-
- if (setitimer (ITIMER_REAL, &timerval, NULL) != 0) {
- printf ("SetTimer: setitimer error %s\n", strerror (errno));
- }
- settimer_callback = CallBack;
-}
-
-
-VOID
-SecEnableInterrupt (
- VOID
- )
-{
- sigset_t sigset;
-
- gEmulatorInterruptEnabled = TRUE;
- // Since SetTimer() uses SIGALRM we emulate turning on and off interrupts
- // by enabling/disabling SIGALRM.
- sigemptyset (&sigset);
- sigaddset (&sigset, SIGALRM);
- pthread_sigmask (SIG_UNBLOCK, &sigset, NULL);
-}
-
-
-VOID
-SecDisableInterrupt (
- VOID
- )
-{
- sigset_t sigset;
-
- // Since SetTimer() uses SIGALRM we emulate turning on and off interrupts
- // by enabling/disabling SIGALRM.
- sigemptyset (&sigset);
- sigaddset (&sigset, SIGALRM);
- pthread_sigmask (SIG_BLOCK, &sigset, NULL);
- gEmulatorInterruptEnabled = FALSE;
-}
-
-
-BOOLEAN
-SecInterruptEanbled (void)
-{
- return gEmulatorInterruptEnabled;
-}
-
-
-UINT64
-QueryPerformanceFrequency (
- VOID
- )
-{
- // Hard code to nanoseconds
- return 1000000000ULL;
-}
-
-UINT64
-QueryPerformanceCounter (
- VOID
- )
-{
-#if __APPLE__
- UINT64 Start;
- static mach_timebase_info_data_t sTimebaseInfo;
-
-
- Start = mach_absolute_time ();
-
- // Convert to nanoseconds.
-
- // If this is the first time we've run, get the timebase.
- // We can use denom == 0 to indicate that sTimebaseInfo is
- // uninitialised because it makes no sense to have a zero
- // denominator is a fraction.
-
- if ( sTimebaseInfo.denom == 0 ) {
- (void) mach_timebase_info(&sTimebaseInfo);
- }
-
- // Do the maths. We hope that the multiplication doesn't
- // overflow; the price you pay for working in fixed point.
-
- return (Start * sTimebaseInfo.numer) / sTimebaseInfo.denom;
-#else
- // Need to figure out what to do for Linux?
- return 0;
-#endif
-}
-
-
-
-VOID
-SecSleep (
- IN UINT64 Nanoseconds
- )
-{
- struct timespec rq, rm;
- struct timeval start, end;
- unsigned long MicroSec;
-
- rq.tv_sec = DivU64x32 (Nanoseconds, 1000000000);
- rq.tv_nsec = ModU64x32 (Nanoseconds, 1000000000);
-
- //
- // nanosleep gets interrupted by our timer tic.
- // we need to track wall clock time or we will stall for way too long
- //
- gettimeofday (&start, NULL);
- end.tv_sec = start.tv_sec + rq.tv_sec;
- MicroSec = (start.tv_usec + rq.tv_nsec/1000);
- end.tv_usec = MicroSec % 1000000;
- if (MicroSec > 1000000) {
- end.tv_sec++;
- }
-
- while (nanosleep (&rq, &rm) == -1) {
- if (errno != EINTR) {
- break;
- }
- gettimeofday (&start, NULL);
- if (start.tv_sec > end.tv_sec) {
- break;
- } if ((start.tv_sec == end.tv_sec) && (start.tv_usec > end.tv_usec)) {
- break;
- }
- rq = rm;
- }
-}
-
-
-VOID
-SecCpuSleep (
- VOID
- )
-{
- struct timespec rq, rm;
-
- // nanosleep gets interrupted by the timer tic
- rq.tv_sec = 1;
- rq.tv_nsec = 0;
-
- nanosleep (&rq, &rm);
-}
-
-
-VOID
-SecExit (
- UINTN Status
- )
-{
- exit (Status);
-}
-
-
-VOID
-SecGetTime (
- OUT EFI_TIME *Time,
- OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL
- )
-{
- struct tm *tm;
- time_t t;
-
- t = time (NULL);
- tm = localtime (&t);
-
- Time->Year = 1900 + tm->tm_year;
- Time->Month = tm->tm_mon + 1;
- Time->Day = tm->tm_mday;
- Time->Hour = tm->tm_hour;
- Time->Minute = tm->tm_min;
- Time->Second = tm->tm_sec;
- Time->Nanosecond = 0;
- Time->TimeZone = timezone;
- Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0)
- | (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0);
-
- if (Capabilities != NULL) {
- Capabilities->Resolution = 1;
- Capabilities->Accuracy = 50000000;
- Capabilities->SetsToZero = FALSE;
- }
-}
-
-
-
-VOID
-SecSetTime (
- IN EFI_TIME *Time
- )
-{
- // Don't change the time on the system
- // We could save delta to localtime() and have SecGetTime adjust return values?
- return;
-}
-
-
-EFI_STATUS
-SecGetNextProtocol (
- IN BOOLEAN EmuBusDriver,
- OUT EMU_IO_THUNK_PROTOCOL **Instance OPTIONAL
- )
-{
- return GetNextThunkProtocol (EmuBusDriver, Instance);
-}
-
-
-EMU_THUNK_PROTOCOL gEmuThunkProtocol = {
- GasketSecWriteStdErr,
- GasketSecConfigStdIn,
- GasketSecWriteStdOut,
- GasketSecReadStdIn,
- GasketSecPollStdIn,
- GasketSecMalloc,
- GasketSecValloc,
- GasketSecFree,
- GasketSecPeCoffGetEntryPoint,
- GasketSecPeCoffRelocateImageExtraAction,
- GasketSecPeCoffUnloadImageExtraAction,
- GasketSecEnableInterrupt,
- GasketSecDisableInterrupt,
- GasketQueryPerformanceFrequency,
- GasketQueryPerformanceCounter,
- GasketSecSleep,
- GasketSecCpuSleep,
- GasketSecExit,
- GasketSecGetTime,
- GasketSecSetTime,
- GasketSecSetTimer,
- GasketSecGetNextProtocol
-};
-
-
-VOID
-SecInitThunkProtocol (
- VOID
- )
-{
- // timezone and daylight lib globals depend on tzset be called 1st.
- tzset ();
-}
-
+/*++ @file\r
+ Since the SEC is the only program in our emulation we\r
+ must use a UEFI/PI mechanism to export APIs to other modules.\r
+ This is the role of the EFI_EMU_THUNK_PROTOCOL.\r
+\r
+ The mUnixThunkTable exists so that a change to EFI_EMU_THUNK_PROTOCOL\r
+ will cause an error in initializing the array if all the member functions\r
+ are not added. It looks like adding a element to end and not initializing\r
+ it may cause the table to be initaliized with the members at the end being\r
+ set to zero. This is bad as jumping to zero will crash.\r
+\r
+Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Host.h"\r
+\r
+#ifdef __APPLE__\r
+#define DebugAssert _Mangle__DebugAssert\r
+\r
+#include <assert.h>\r
+#include <CoreServices/CoreServices.h>\r
+#include <mach/mach.h>\r
+#include <mach/mach_time.h>\r
+\r
+#undef DebugAssert\r
+#endif\r
+\r
+int settimer_initialized;\r
+struct timeval settimer_timeval;\r
+void (*settimer_callback)(UINT64 delta);\r
+\r
+BOOLEAN gEmulatorInterruptEnabled = FALSE;\r
+\r
+\r
+UINTN\r
+SecWriteStdErr (\r
+ IN UINT8 *Buffer,\r
+ IN UINTN NumberOfBytes\r
+ )\r
+{\r
+ ssize_t Return;\r
+\r
+ Return = write (STDERR_FILENO, (const void *)Buffer, (size_t)NumberOfBytes);\r
+\r
+ return (Return == -1) ? 0 : Return;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+SecConfigStdIn (\r
+ VOID\r
+ )\r
+{\r
+ struct termios tty;\r
+\r
+ //\r
+ // Need to turn off line buffering, ECHO, and make it unbuffered.\r
+ //\r
+ tcgetattr (STDIN_FILENO, &tty);\r
+ tty.c_lflag &= ~(ICANON | ECHO);\r
+ tcsetattr (STDIN_FILENO, TCSANOW, &tty);\r
+\r
+// setvbuf (STDIN_FILENO, NULL, _IONBF, 0);\r
+\r
+ // now ioctl FIONREAD will do what we need\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+UINTN\r
+SecWriteStdOut (\r
+ IN UINT8 *Buffer,\r
+ IN UINTN NumberOfBytes\r
+ )\r
+{\r
+ ssize_t Return;\r
+\r
+ Return = write (STDOUT_FILENO, (const void *)Buffer, (size_t)NumberOfBytes);\r
+\r
+ return (Return == -1) ? 0 : Return;\r
+}\r
+\r
+UINTN\r
+SecReadStdIn (\r
+ IN UINT8 *Buffer,\r
+ IN UINTN NumberOfBytes\r
+ )\r
+{\r
+ ssize_t Return;\r
+\r
+ Return = read (STDIN_FILENO, Buffer, (size_t)NumberOfBytes);\r
+\r
+ return (Return == -1) ? 0 : Return;\r
+}\r
+\r
+BOOLEAN\r
+SecPollStdIn (\r
+ VOID\r
+ )\r
+{\r
+ int Result;\r
+ int Bytes;\r
+\r
+ Result = ioctl (STDIN_FILENO, FIONREAD, &Bytes);\r
+ if (Result == -1) {\r
+ return FALSE;\r
+ }\r
+\r
+ return (BOOLEAN)(Bytes > 0);\r
+}\r
+\r
+\r
+VOID *\r
+SecMalloc (\r
+ IN UINTN Size\r
+ )\r
+{\r
+ return malloc ((size_t)Size);\r
+}\r
+\r
+VOID *\r
+SecValloc (\r
+ IN UINTN Size\r
+ )\r
+{\r
+ return valloc ((size_t)Size);\r
+}\r
+\r
+BOOLEAN\r
+SecFree (\r
+ IN VOID *Ptr\r
+ )\r
+{\r
+ if (EfiSystemMemoryRange (Ptr)) {\r
+ // If an address range is in the EFI memory map it was alloced via EFI.\r
+ // So don't free those ranges and let the caller know.\r
+ return FALSE;\r
+ }\r
+\r
+ free (Ptr);\r
+ return TRUE;\r
+}\r
+\r
+\r
+void\r
+settimer_handler (int sig)\r
+{\r
+ struct timeval timeval;\r
+ UINT64 delta;\r
+\r
+ gettimeofday (&timeval, NULL);\r
+ delta = ((UINT64)timeval.tv_sec * 1000) + (timeval.tv_usec / 1000)\r
+ - ((UINT64)settimer_timeval.tv_sec * 1000)\r
+ - (settimer_timeval.tv_usec / 1000);\r
+ settimer_timeval = timeval;\r
+\r
+ if (settimer_callback) {\r
+ ReverseGasketUint64 (settimer_callback, delta);\r
+ }\r
+}\r
+\r
+VOID\r
+SecSetTimer (\r
+ IN UINT64 PeriodMs,\r
+ IN EMU_SET_TIMER_CALLBACK CallBack\r
+ )\r
+{\r
+ struct itimerval timerval;\r
+ UINT32 remainder;\r
+\r
+ if (!settimer_initialized) {\r
+ struct sigaction act;\r
+\r
+ settimer_initialized = 1;\r
+ act.sa_handler = settimer_handler;\r
+ act.sa_flags = 0;\r
+ sigemptyset (&act.sa_mask);\r
+ gEmulatorInterruptEnabled = TRUE;\r
+ if (sigaction (SIGALRM, &act, NULL) != 0) {\r
+ printf ("SetTimer: sigaction error %s\n", strerror (errno));\r
+ }\r
+ if (gettimeofday (&settimer_timeval, NULL) != 0) {\r
+ printf ("SetTimer: gettimeofday error %s\n", strerror (errno));\r
+ }\r
+ }\r
+ timerval.it_value.tv_sec = DivU64x32(PeriodMs, 1000);\r
+ DivU64x32Remainder(PeriodMs, 1000, &remainder);\r
+ timerval.it_value.tv_usec = remainder * 1000;\r
+ timerval.it_value.tv_sec = DivU64x32(PeriodMs, 1000);\r
+ timerval.it_interval = timerval.it_value;\r
+\r
+ if (setitimer (ITIMER_REAL, &timerval, NULL) != 0) {\r
+ printf ("SetTimer: setitimer error %s\n", strerror (errno));\r
+ }\r
+ settimer_callback = CallBack;\r
+}\r
+\r
+\r
+VOID\r
+SecEnableInterrupt (\r
+ VOID\r
+ )\r
+{\r
+ sigset_t sigset;\r
+\r
+ gEmulatorInterruptEnabled = TRUE;\r
+ // Since SetTimer() uses SIGALRM we emulate turning on and off interrupts\r
+ // by enabling/disabling SIGALRM.\r
+ sigemptyset (&sigset);\r
+ sigaddset (&sigset, SIGALRM);\r
+ pthread_sigmask (SIG_UNBLOCK, &sigset, NULL);\r
+}\r
+\r
+\r
+VOID\r
+SecDisableInterrupt (\r
+ VOID\r
+ )\r
+{\r
+ sigset_t sigset;\r
+\r
+ // Since SetTimer() uses SIGALRM we emulate turning on and off interrupts\r
+ // by enabling/disabling SIGALRM.\r
+ sigemptyset (&sigset);\r
+ sigaddset (&sigset, SIGALRM);\r
+ pthread_sigmask (SIG_BLOCK, &sigset, NULL);\r
+ gEmulatorInterruptEnabled = FALSE;\r
+}\r
+\r
+\r
+BOOLEAN\r
+SecInterruptEanbled (void)\r
+{\r
+ return gEmulatorInterruptEnabled;\r
+}\r
+\r
+\r
+UINT64\r
+QueryPerformanceFrequency (\r
+ VOID\r
+ )\r
+{\r
+ // Hard code to nanoseconds\r
+ return 1000000000ULL;\r
+}\r
+\r
+UINT64\r
+QueryPerformanceCounter (\r
+ VOID\r
+ )\r
+{\r
+#if __APPLE__\r
+ UINT64 Start;\r
+ static mach_timebase_info_data_t sTimebaseInfo;\r
+\r
+\r
+ Start = mach_absolute_time ();\r
+\r
+ // Convert to nanoseconds.\r
+\r
+ // If this is the first time we've run, get the timebase.\r
+ // We can use denom == 0 to indicate that sTimebaseInfo is\r
+ // uninitialised because it makes no sense to have a zero\r
+ // denominator is a fraction.\r
+\r
+ if ( sTimebaseInfo.denom == 0 ) {\r
+ (void) mach_timebase_info(&sTimebaseInfo);\r
+ }\r
+\r
+ // Do the maths. We hope that the multiplication doesn't\r
+ // overflow; the price you pay for working in fixed point.\r
+\r
+ return (Start * sTimebaseInfo.numer) / sTimebaseInfo.denom;\r
+#else\r
+ // Need to figure out what to do for Linux?\r
+ return 0;\r
+#endif\r
+}\r
+\r
+\r
+\r
+VOID\r
+SecSleep (\r
+ IN UINT64 Nanoseconds\r
+ )\r
+{\r
+ struct timespec rq, rm;\r
+ struct timeval start, end;\r
+ unsigned long MicroSec;\r
+\r
+ rq.tv_sec = DivU64x32 (Nanoseconds, 1000000000);\r
+ rq.tv_nsec = ModU64x32 (Nanoseconds, 1000000000);\r
+\r
+ //\r
+ // nanosleep gets interrupted by our timer tic.\r
+ // we need to track wall clock time or we will stall for way too long\r
+ //\r
+ gettimeofday (&start, NULL);\r
+ end.tv_sec = start.tv_sec + rq.tv_sec;\r
+ MicroSec = (start.tv_usec + rq.tv_nsec/1000);\r
+ end.tv_usec = MicroSec % 1000000;\r
+ if (MicroSec > 1000000) {\r
+ end.tv_sec++;\r
+ }\r
+\r
+ while (nanosleep (&rq, &rm) == -1) {\r
+ if (errno != EINTR) {\r
+ break;\r
+ }\r
+ gettimeofday (&start, NULL);\r
+ if (start.tv_sec > end.tv_sec) {\r
+ break;\r
+ } if ((start.tv_sec == end.tv_sec) && (start.tv_usec > end.tv_usec)) {\r
+ break;\r
+ }\r
+ rq = rm;\r
+ }\r
+}\r
+\r
+\r
+VOID\r
+SecCpuSleep (\r
+ VOID\r
+ )\r
+{\r
+ struct timespec rq, rm;\r
+\r
+ // nanosleep gets interrupted by the timer tic\r
+ rq.tv_sec = 1;\r
+ rq.tv_nsec = 0;\r
+\r
+ nanosleep (&rq, &rm);\r
+}\r
+\r
+\r
+VOID\r
+SecExit (\r
+ UINTN Status\r
+ )\r
+{\r
+ exit (Status);\r
+}\r
+\r
+\r
+VOID\r
+SecGetTime (\r
+ OUT EFI_TIME *Time,\r
+ OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL\r
+ )\r
+{\r
+ struct tm *tm;\r
+ time_t t;\r
+\r
+ t = time (NULL);\r
+ tm = localtime (&t);\r
+\r
+ Time->Year = 1900 + tm->tm_year;\r
+ Time->Month = tm->tm_mon + 1;\r
+ Time->Day = tm->tm_mday;\r
+ Time->Hour = tm->tm_hour;\r
+ Time->Minute = tm->tm_min;\r
+ Time->Second = tm->tm_sec;\r
+ Time->Nanosecond = 0;\r
+ Time->TimeZone = timezone;\r
+ Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0)\r
+ | (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0);\r
+\r
+ if (Capabilities != NULL) {\r
+ Capabilities->Resolution = 1;\r
+ Capabilities->Accuracy = 50000000;\r
+ Capabilities->SetsToZero = FALSE;\r
+ }\r
+}\r
+\r
+\r
+\r
+VOID\r
+SecSetTime (\r
+ IN EFI_TIME *Time\r
+ )\r
+{\r
+ // Don't change the time on the system\r
+ // We could save delta to localtime() and have SecGetTime adjust return values?\r
+ return;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+SecGetNextProtocol (\r
+ IN BOOLEAN EmuBusDriver,\r
+ OUT EMU_IO_THUNK_PROTOCOL **Instance OPTIONAL\r
+ )\r
+{\r
+ return GetNextThunkProtocol (EmuBusDriver, Instance);\r
+}\r
+\r
+\r
+EMU_THUNK_PROTOCOL gEmuThunkProtocol = {\r
+ GasketSecWriteStdErr,\r
+ GasketSecConfigStdIn,\r
+ GasketSecWriteStdOut,\r
+ GasketSecReadStdIn,\r
+ GasketSecPollStdIn,\r
+ GasketSecMalloc,\r
+ GasketSecValloc,\r
+ GasketSecFree,\r
+ GasketSecPeCoffGetEntryPoint,\r
+ GasketSecPeCoffRelocateImageExtraAction,\r
+ GasketSecPeCoffUnloadImageExtraAction,\r
+ GasketSecEnableInterrupt,\r
+ GasketSecDisableInterrupt,\r
+ GasketQueryPerformanceFrequency,\r
+ GasketQueryPerformanceCounter,\r
+ GasketSecSleep,\r
+ GasketSecCpuSleep,\r
+ GasketSecExit,\r
+ GasketSecGetTime,\r
+ GasketSecSetTime,\r
+ GasketSecSetTimer,\r
+ GasketSecGetNextProtocol\r
+};\r
+\r
+\r
+VOID\r
+SecInitThunkProtocol (\r
+ VOID\r
+ )\r
+{\r
+ // timezone and daylight lib globals depend on tzset be called 1st.\r
+ tzset ();\r
+}\r
+\r