]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmulatorPkg/Unix/Host/EmuThunk.c
EmulatorPkg: formalize line endings
[mirror_edk2.git] / EmulatorPkg / Unix / Host / EmuThunk.c
index a7b12b14e5da290755665f17d64dde1a60a558e1..1a2037f931de8ecb91e105e77b1bf2408e8ea2cc 100644 (file)
-/*++ @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