]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UnixPkg/Sec/SecMain.c
UnixPkg: Remove UnixPkg files (It is replaced by EmulatorPkg)
[mirror_edk2.git] / UnixPkg / Sec / SecMain.c
diff --git a/UnixPkg/Sec/SecMain.c b/UnixPkg/Sec/SecMain.c
deleted file mode 100644 (file)
index f0627be..0000000
+++ /dev/null
@@ -1,1340 +0,0 @@
-/*++
-
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
-Portions copyright (c) 2008 - 2010, 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.
-
-Module Name:
-
-  SecMain.c
-
-Abstract:
-  Unix emulator of SEC phase. It's really a Posix application, but this is
-  Ok since all the other modules for NT32 are NOT Posix applications.
-
-  This program processes host environment variables and figures out
-  what the memory layout will be, how may FD's will be loaded and also
-  what the boot mode is.
-
-  The SEC registers a set of services with the SEC core. gPrivateDispatchTable
-  is a list of PPI's produced by the SEC that are availble for usage in PEI.
-
-  This code produces 128 K of temporary memory for the PEI stack by opening a
-  host file and mapping it directly to memory addresses.
-
-  The system.cmd script is used to set host environment variables that drive
-  the configuration opitons of the SEC.
-
---*/
-
-#include "SecMain.h"
-#include <sys/mman.h>
-#include <Ppi/UnixPeiLoadFile.h>
-#include <Ppi/TemporaryRamSupport.h>
-#include <dlfcn.h>
-
-#ifdef __APPLE__
-#define MAP_ANONYMOUS MAP_ANON
-char *gGdbWorkingFileName = NULL;
-#endif
-
-
-//
-// Globals
-//
-#if defined(__APPLE__) || defined(MDE_CPU_X64)
-UNIX_PEI_LOAD_FILE_PPI                    mSecUnixLoadFilePpi        = { GasketSecUnixPeiLoadFile };
-PEI_UNIX_AUTOSCAN_PPI                     mSecUnixAutoScanPpi        = { GasketSecUnixPeiAutoScan };
-PEI_UNIX_THUNK_PPI                        mSecUnixThunkPpi           = { GasketSecUnixUnixThunkAddress };
-EFI_PEI_PROGRESS_CODE_PPI                 mSecStatusCodePpi          = { GasketSecPeiReportStatusCode };
-UNIX_FWH_PPI                              mSecFwhInformationPpi      = { GasketSecUnixFdAddress };
-EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI         mSecTemporaryRamSupportPpi = { GasketSecTemporaryRamSupport };
-#else
-UNIX_PEI_LOAD_FILE_PPI                    mSecUnixLoadFilePpi        = { SecUnixPeiLoadFile };
-PEI_UNIX_AUTOSCAN_PPI                     mSecUnixAutoScanPpi        = { SecUnixPeiAutoScan };
-PEI_UNIX_THUNK_PPI                        mSecUnixThunkPpi           = { SecUnixUnixThunkAddress };
-EFI_PEI_PROGRESS_CODE_PPI                 mSecStatusCodePpi          = { SecPeiReportStatusCode };
-UNIX_FWH_PPI                              mSecFwhInformationPpi      = { SecUnixFdAddress };
-EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI         mSecTemporaryRamSupportPpi = { SecTemporaryRamSupport };
-#endif
-
-EFI_PEI_PPI_DESCRIPTOR  gPrivateDispatchTable[] = {
-  {
-    EFI_PEI_PPI_DESCRIPTOR_PPI,
-    &gUnixPeiLoadFilePpiGuid,
-    &mSecUnixLoadFilePpi
-  },
-  {
-    EFI_PEI_PPI_DESCRIPTOR_PPI,
-    &gPeiUnixAutoScanPpiGuid,
-    &mSecUnixAutoScanPpi
-  },
-  {
-    EFI_PEI_PPI_DESCRIPTOR_PPI,
-    &gPeiUnixThunkPpiGuid,
-    &mSecUnixThunkPpi
-  },
-  {
-    EFI_PEI_PPI_DESCRIPTOR_PPI,
-    &gEfiPeiStatusCodePpiGuid,
-    &mSecStatusCodePpi
-  },
-  {
-    EFI_PEI_PPI_DESCRIPTOR_PPI,
-    &gEfiTemporaryRamSupportPpiGuid,
-    &mSecTemporaryRamSupportPpi
-  },
-  {
-    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
-    &gUnixFwhPpiGuid,
-    &mSecFwhInformationPpi
-  }
-};
-
-
-//
-// Default information about where the FD is located.
-//  This array gets filled in with information from EFI_FIRMWARE_VOLUMES
-//  EFI_FIRMWARE_VOLUMES is a host environment variable set by system.cmd.
-//  The number of array elements is allocated base on parsing
-//  EFI_FIRMWARE_VOLUMES and the memory is never freed.
-//
-UINTN                                     gFdInfoCount = 0;
-UNIX_FD_INFO                                *gFdInfo;
-
-//
-// Array that supports seperate memory rantes.
-//  The memory ranges are set in system.cmd via the EFI_MEMORY_SIZE variable.
-//  The number of array elements is allocated base on parsing
-//  EFI_MEMORY_SIZE and the memory is never freed.
-//
-UINTN                                     gSystemMemoryCount = 0;
-UNIX_SYSTEM_MEMORY                       *gSystemMemory;
-
-
-
-UINTN                        mImageContextModHandleArraySize = 0;
-IMAGE_CONTEXT_TO_MOD_HANDLE  *mImageContextModHandleArray = NULL;
-
-
-VOID
-EFIAPI
-SecSwitchStack (
-  UINT32   TemporaryMemoryBase,
-  UINT32   PermenentMemoryBase
-  );
-
-EFI_PHYSICAL_ADDRESS *
-MapMemory (
-  INTN fd,
-  UINT64 length,
-  INTN   prot,
-  INTN   flags);
-
-EFI_STATUS
-MapFile (
-  IN  CHAR8                     *FileName,
-  IN OUT  EFI_PHYSICAL_ADDRESS  *BaseAddress,
-  OUT UINT64                    *Length
-  );
-
-EFI_STATUS
-EFIAPI
-SecNt32PeCoffRelocateImage (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext
-  );
-
-
-int
-main (
-  IN  int   Argc,
-  IN  char  **Argv,
-  IN  char  **Envp
-  )
-/*++
-
-Routine Description:
-  Main entry point to SEC for Unix. This is a unix program
-
-Arguments:
-  Argc - Number of command line arguments
-  Argv - Array of command line argument strings
-  Envp - Array of environmemt variable strings
-
-Returns:
-  0 - Normal exit
-  1 - Abnormal exit
-
---*/
-{
-  EFI_STATUS            Status;
-  EFI_PHYSICAL_ADDRESS  InitialStackMemory;
-  UINT64                InitialStackMemorySize;
-  UINTN                 Index;
-  UINTN                 Index1;
-  UINTN                 Index2;
-  UINTN                 PeiIndex;
-  CHAR8                 *FileName;
-  BOOLEAN               Done;
-  VOID                  *PeiCoreFile;
-  CHAR16                *MemorySizeStr;
-  CHAR16                *FirmwareVolumesStr;
-  UINTN                 *StackPointer;
-
-  setbuf(stdout, 0);
-  setbuf(stderr, 0);
-
-  MemorySizeStr      = (CHAR16 *) PcdGetPtr (PcdUnixMemorySizeForSecMain);
-  FirmwareVolumesStr = (CHAR16 *) PcdGetPtr (PcdUnixFirmwareVolume);
-
-  printf ("\nEDK SEC Main UNIX Emulation Environment from edk2.sourceforge.net\n");
-
-#ifdef __APPLE__
-  //
-  // We can't use dlopen on OS X, so we need a scheme to get symboles into gdb
-  // We need to create a temp file that contains gdb commands so we can load
-  // symbols when we load every PE/COFF image.
-  //
-  Index = strlen (*Argv);
-  gGdbWorkingFileName = malloc (Index + strlen(".gdb") + 1);
-  strcpy (gGdbWorkingFileName, *Argv);
-  strcat (gGdbWorkingFileName, ".gdb");
-#endif
-
-
-  //
-  // Allocate space for gSystemMemory Array
-  //
-  gSystemMemoryCount  = CountSeperatorsInString (MemorySizeStr, '!') + 1;
-  gSystemMemory       = calloc (gSystemMemoryCount, sizeof (UNIX_SYSTEM_MEMORY));
-  if (gSystemMemory == NULL) {
-    printf ("ERROR : Can not allocate memory for system.  Exiting.\n");
-    exit (1);
-  }
-  //
-  // Allocate space for gSystemMemory Array
-  //
-  gFdInfoCount  = CountSeperatorsInString (FirmwareVolumesStr, '!') + 1;
-  gFdInfo       = calloc (gFdInfoCount, sizeof (UNIX_FD_INFO));
-  if (gFdInfo == NULL) {
-    printf ("ERROR : Can not allocate memory for fd info.  Exiting.\n");
-    exit (1);
-  }
-  //
-  // Setup Boot Mode. If BootModeStr == "" then BootMode = 0 (BOOT_WITH_FULL_CONFIGURATION)
-  //
-  printf ("  BootMode 0x%02x\n", (unsigned int)PcdGet32 (PcdUnixBootMode));
-
-  //
-  // Open up a 128K file to emulate temp memory for PEI.
-  //  on a real platform this would be SRAM, or using the cache as RAM.
-  //  Set InitialStackMemory to zero so UnixOpenFile will allocate a new mapping
-  //
-  InitialStackMemorySize  = STACK_SIZE;
-  InitialStackMemory = (UINTN)MapMemory(0,
-          (UINT32) InitialStackMemorySize,
-          PROT_READ | PROT_WRITE | PROT_EXEC,
-          MAP_ANONYMOUS | MAP_PRIVATE);
-  if (InitialStackMemory == 0) {
-    printf ("ERROR : Can not open SecStack Exiting\n");
-    exit (1);
-  }
-
-  printf ("  SEC passing in %u KB of temp RAM at 0x%08lx to PEI\n",
-    (unsigned int)(InitialStackMemorySize / 1024),
-    (unsigned long)InitialStackMemory);
-
-  for (StackPointer = (UINTN*) (UINTN) InitialStackMemory;
-     StackPointer < (UINTN*)(UINTN)((UINTN) InitialStackMemory + (UINT64) InitialStackMemorySize);
-     StackPointer ++) {
-    *StackPointer = 0x5AA55AA5;
-  }
-
-  //
-  // Open All the firmware volumes and remember the info in the gFdInfo global
-  //
-  FileName = (CHAR8 *)malloc (StrLen (FirmwareVolumesStr) + 1);
-  if (FileName == NULL) {
-    printf ("ERROR : Can not allocate memory for firmware volume string\n");
-    exit (1);
-  }
-
-  Index2 = 0;
-  for (Done = FALSE, Index = 0, PeiIndex = 0, PeiCoreFile = NULL;
-       FirmwareVolumesStr[Index2] != 0;
-       Index++) {
-    for (Index1 = 0; (FirmwareVolumesStr[Index2] != '!') && (FirmwareVolumesStr[Index2] != 0); Index2++)
-      FileName[Index1++] = FirmwareVolumesStr[Index2];
-    if (FirmwareVolumesStr[Index2] == '!')
-      Index2++;
-    FileName[Index1]  = '\0';
-
-    //
-    // Open the FD and remmeber where it got mapped into our processes address space
-    //
-    Status = MapFile (
-          FileName,
-          &gFdInfo[Index].Address,
-          &gFdInfo[Index].Size
-          );
-    if (EFI_ERROR (Status)) {
-      printf ("ERROR : Can not open Firmware Device File %s (%x).  Exiting.\n", FileName, (unsigned int)Status);
-      exit (1);
-    }
-
-    printf ("  FD loaded from %s at 0x%08lx",
-      FileName, (unsigned long)gFdInfo[Index].Address);
-
-    if (PeiCoreFile == NULL) {
-      //
-      // Assume the beginning of the FD is an FV and look for the PEI Core.
-      // Load the first one we find.
-      //
-      Status = SecFfsFindPeiCore ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) gFdInfo[Index].Address, &PeiCoreFile);
-      if (!EFI_ERROR (Status)) {
-        PeiIndex = Index;
-        printf (" contains SEC Core");
-      }
-    }
-
-    printf ("\n");
-  }
-  //
-  // Calculate memory regions and store the information in the gSystemMemory
-  //  global for later use. The autosizing code will use this data to
-  //  map this memory into the SEC process memory space.
-  //
-  Index1 = 0;
-  Index = 0;
-  while (1) {
-    UINTN val = 0;
-    //
-    // Save the size of the memory.
-    //
-    while (MemorySizeStr[Index1] >= '0' && MemorySizeStr[Index1] <= '9') {
-      val = val * 10 + MemorySizeStr[Index1] - '0';
-      Index1++;
-    }
-    gSystemMemory[Index++].Size = val * 0x100000;
-    if (MemorySizeStr[Index1] == 0)
-      break;
-    Index1++;
-  }
-
-  printf ("\n");
-
-  //
-  // Hand off to PEI Core
-  //
-  SecLoadFromCore ((UINTN) InitialStackMemory, (UINTN) InitialStackMemorySize, (UINTN) gFdInfo[0].Address, PeiCoreFile);
-
-  //
-  // If we get here, then the PEI Core returned. This is an error as PEI should
-  //  always hand off to DXE.
-  //
-  printf ("ERROR : PEI Core returned\n");
-  exit (1);
-}
-
-EFI_PHYSICAL_ADDRESS *
-MapMemory (
-  INTN fd,
-  UINT64 length,
-  INTN   prot,
-  INTN   flags)
-{
-  STATIC UINTN base  = 0x40000000;
-  CONST UINTN  align = (1 << 24);
-  VOID         *res  = NULL;
-  BOOLEAN      isAligned = 0;
-
-  //
-  // Try to get an aligned block somewhere in the address space of this
-  // process.
-  //
-  while((!isAligned) && (base != 0)) {
-    res = mmap ((void *)base, length, prot, flags, fd, 0);
-    if (res == MAP_FAILED) {
-      return NULL;
-    }
-    if ((((UINTN)res) & ~(align-1)) == (UINTN)res) {
-      isAligned=1;
-    }
-    else {
-      munmap(res, length);
-      base += align;
-    }
-  }
-  return res;
-}
-
-EFI_STATUS
-MapFile (
-  IN  CHAR8                     *FileName,
-  IN OUT  EFI_PHYSICAL_ADDRESS  *BaseAddress,
-  OUT UINT64                    *Length
-  )
-/*++
-
-Routine Description:
-  Opens and memory maps a file using Unix services. If BaseAddress is non zero
-  the process will try and allocate the memory starting at BaseAddress.
-
-Arguments:
-  FileName            - The name of the file to open and map
-  MapSize             - The amount of the file to map in bytes
-  CreationDisposition - The flags to pass to CreateFile().  Use to create new files for
-                        memory emulation, and exiting files for firmware volume emulation
-  BaseAddress         - The base address of the mapped file in the user address space.
-                         If passed in as NULL the a new memory region is used.
-                         If passed in as non NULL the request memory region is used for
-                          the mapping of the file into the process space.
-  Length              - The size of the mapped region in bytes
-
-Returns:
-  EFI_SUCCESS      - The file was opened and mapped.
-  EFI_NOT_FOUND    - FileName was not found in the current directory
-  EFI_DEVICE_ERROR - An error occured attempting to map the opened file
-
---*/
-{
-  int fd;
-  VOID    *res;
-  UINTN   FileSize;
-
-  fd = open (FileName, O_RDONLY);
-  if (fd < 0)
-    return EFI_NOT_FOUND;
-  FileSize = lseek (fd, 0, SEEK_END);
-
-#if 0
-  if (IsMain)
-    {
-      /* Read entry address.  */
-      lseek (fd, FileSize - 0x20, SEEK_SET);
-      if (read (fd, &EntryAddress, 4) != 4)
-  {
-    close (fd);
-    return EFI_DEVICE_ERROR;
-  }
-    }
-#endif
-
-  res = MapMemory(fd, FileSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
-
-  close (fd);
-
-  if (res == MAP_FAILED)
-    return EFI_DEVICE_ERROR;
-
-  *Length = (UINT64) FileSize;
-  *BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) res;
-
-  return EFI_SUCCESS;
-}
-
-#define BYTES_PER_RECORD  512
-
-EFI_STATUS
-EFIAPI
-SecPeiReportStatusCode (
-  IN CONST EFI_PEI_SERVICES     **PeiServices,
-  IN EFI_STATUS_CODE_TYPE       CodeType,
-  IN EFI_STATUS_CODE_VALUE      Value,
-  IN UINT32                     Instance,
-  IN CONST EFI_GUID             *CallerId,
-  IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL
-  )
-/*++
-
-Routine Description:
-
-  This routine produces the ReportStatusCode PEI service. It's passed
-  up to the PEI Core via a PPI. T
-
-  This code currently uses the UNIX clib printf. This does not work the same way
-  as the EFI Print (), as %t, %g, %s as Unicode are not supported.
-
-Arguments:
-  (see EFI_PEI_REPORT_STATUS_CODE)
-
-Returns:
-  EFI_SUCCESS - Always return success
-
---*/
-// TODO:    PeiServices - add argument and description to function comment
-// TODO:    CodeType - add argument and description to function comment
-// TODO:    Value - add argument and description to function comment
-// TODO:    Instance - add argument and description to function comment
-// TODO:    CallerId - add argument and description to function comment
-// TODO:    Data - add argument and description to function comment
-{
-  CHAR8           *Format;
-  BASE_LIST       Marker;
-  CHAR8           PrintBuffer[BYTES_PER_RECORD * 2];
-  CHAR8           *Filename;
-  CHAR8           *Description;
-  UINT32          LineNumber;
-  UINT32          ErrorLevel;
-
-
-  if (Data == NULL) {
-  } else if (ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
-    //
-    // Processes ASSERT ()
-    //
-    printf ("ASSERT %s(%d): %s\n", Filename, (int)LineNumber, Description);
-
-  } else if (ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
-    //
-    // Process DEBUG () macro
-    //
-    AsciiBSPrint (PrintBuffer, BYTES_PER_RECORD, Format, Marker);
-    printf ("%s", PrintBuffer);
-  }
-
-  return EFI_SUCCESS;
-}
-
-VOID
-EFIAPI
-PeiSwitchStacks (
-  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,
-  IN      VOID                      *Context1,  OPTIONAL
-  IN      VOID                      *Context2,  OPTIONAL
-  IN      VOID                      *Context3,  OPTIONAL
-  IN      VOID                      *NewStack
-  );
-
-VOID
-SecLoadFromCore (
-  IN  UINTN   LargestRegion,
-  IN  UINTN   LargestRegionSize,
-  IN  UINTN   BootFirmwareVolumeBase,
-  IN  VOID    *PeiCorePe32File
-  )
-/*++
-
-Routine Description:
-  This is the service to load the PEI Core from the Firmware Volume
-
-Arguments:
-  LargestRegion           - Memory to use for PEI.
-  LargestRegionSize       - Size of Memory to use for PEI
-  BootFirmwareVolumeBase  - Start of the Boot FV
-  PeiCorePe32File         - PEI Core PE32
-
-Returns:
-  Success means control is transfered and thus we should never return
-
---*/
-{
-  EFI_STATUS                  Status;
-  EFI_PHYSICAL_ADDRESS        TopOfMemory;
-  VOID                        *TopOfStack;
-  UINT64                      PeiCoreSize;
-  EFI_PHYSICAL_ADDRESS        PeiCoreEntryPoint;
-  EFI_PHYSICAL_ADDRESS        PeiImageAddress;
-  EFI_SEC_PEI_HAND_OFF        *SecCoreData;
-  UINTN                       PeiStackSize;
-  EFI_PEI_PPI_DESCRIPTOR      *DispatchTable;
-  UINTN                       DispatchTableSize;
-
-  //
-  // Compute Top Of Memory for Stack and PEI Core Allocations
-  //
-  TopOfMemory  = LargestRegion + LargestRegionSize;
-  PeiStackSize = (UINTN)RShiftU64((UINT64)STACK_SIZE,1);
-
-  //
-  // |-----------| <---- TemporaryRamBase + TemporaryRamSize
-  // |   Heap    |
-  // |           |
-  // |-----------| <---- StackBase / PeiTemporaryMemoryBase
-  // |           |
-  // |  Stack    |
-  // |-----------| <---- TemporaryRamBase
-  //
-  TopOfStack  = (VOID *)(LargestRegion + PeiStackSize);
-  TopOfMemory = LargestRegion + PeiStackSize;
-
-  //
-  // Reservet space for storing PeiCore's parament in stack.
-  //
-  TopOfStack  = (VOID *)((UINTN)TopOfStack - sizeof (EFI_SEC_PEI_HAND_OFF) - CPU_STACK_ALIGNMENT);
-  TopOfStack  = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
-
-
-  //
-  // Bind this information into the SEC hand-off state
-  //
-  SecCoreData                        = (EFI_SEC_PEI_HAND_OFF*)(UINTN) TopOfStack;
-  SecCoreData->DataSize               = sizeof(EFI_SEC_PEI_HAND_OFF);
-  SecCoreData->BootFirmwareVolumeBase = (VOID*)BootFirmwareVolumeBase;
-  SecCoreData->BootFirmwareVolumeSize = PcdGet32 (PcdUnixFirmwareFdSize);
-  SecCoreData->TemporaryRamBase       = (VOID*)(UINTN)LargestRegion;
-  SecCoreData->TemporaryRamSize       = STACK_SIZE;
-  SecCoreData->StackBase              = SecCoreData->TemporaryRamBase;
-  SecCoreData->StackSize              = PeiStackSize;
-  SecCoreData->PeiTemporaryRamBase    = (VOID*) ((UINTN) SecCoreData->TemporaryRamBase + PeiStackSize);
-  SecCoreData->PeiTemporaryRamSize    = STACK_SIZE - PeiStackSize;
-
-  //
-  // Load the PEI Core from a Firmware Volume
-  //
-  Status = SecUnixPeiLoadFile (
-            PeiCorePe32File,
-            &PeiImageAddress,
-            &PeiCoreSize,
-            &PeiCoreEntryPoint
-            );
-  if (EFI_ERROR (Status)) {
-    return ;
-  }
-
-  DispatchTableSize = sizeof (gPrivateDispatchTable);
-  DispatchTableSize += OverrideDispatchTableExtraSize ();
-
-  DispatchTable = malloc (DispatchTableSize);
-  if (DispatchTable == NULL) {
-    return;
-  }
-
-  //
-  // Allow an override for extra PPIs to be passed up to PEI
-  // This is an easy way to enable OS specific customizations
-  //
-  OverrideDispatchTable (&gPrivateDispatchTable[0], sizeof (gPrivateDispatchTable), DispatchTable, DispatchTableSize);
-
-  //
-  // Transfer control to the PEI Core
-  //
-  PeiSwitchStacks (
-    (SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint,
-    SecCoreData,
-    (VOID *)DispatchTable,
-    NULL,
-    TopOfStack
-    );
-  //
-  // If we get here, then the PEI Core returned.  This is an error
-  //
-  return ;
-}
-
-EFI_STATUS
-EFIAPI
-SecUnixPeiAutoScan (
-  IN  UINTN                 Index,
-  OUT EFI_PHYSICAL_ADDRESS  *MemoryBase,
-  OUT UINT64                *MemorySize
-  )
-/*++
-
-Routine Description:
-  This service is called from Index == 0 until it returns EFI_UNSUPPORTED.
-  It allows discontiguous memory regions to be supported by the emulator.
-  It uses gSystemMemory[] and gSystemMemoryCount that were created by
-  parsing the host environment variable EFI_MEMORY_SIZE.
-  The size comes from the varaible and the address comes from the call to
-  UnixOpenFile.
-
-Arguments:
-  Index      - Which memory region to use
-  MemoryBase - Return Base address of memory region
-  MemorySize - Return size in bytes of the memory region
-
-Returns:
-  EFI_SUCCESS - If memory region was mapped
-  EFI_UNSUPPORTED - If Index is not supported
-
---*/
-{
-  void *res;
-
-  if (Index >= gSystemMemoryCount) {
-    return EFI_UNSUPPORTED;
-  }
-
-  *MemoryBase = 0;
-  res = MapMemory(0, gSystemMemory[Index].Size,
-      PROT_READ | PROT_WRITE | PROT_EXEC,
-      MAP_PRIVATE | MAP_ANONYMOUS);
-  if (res == MAP_FAILED)
-    return EFI_DEVICE_ERROR;
-  *MemorySize = gSystemMemory[Index].Size;
-  *MemoryBase = (UINTN)res;
-  gSystemMemory[Index].Memory = *MemoryBase;
-
-  return EFI_SUCCESS;
-}
-
-VOID *
-EFIAPI
-SecUnixUnixThunkAddress (
-  VOID
-  )
-/*++
-
-Routine Description:
-  Since the SEC is the only Unix program in stack it must export
-  an interface to do POSIX calls.  gUnix is initailized in UnixThunk.c.
-
-Arguments:
-  InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL);
-  InterfaceBase - Address of the gUnix global
-
-Returns:
-  EFI_SUCCESS - Data returned
-
---*/
-{
-  return gUnix;
-}
-
-
-EFI_STATUS
-SecUnixPeiLoadFile (
-  IN  VOID                    *Pe32Data,
-  OUT EFI_PHYSICAL_ADDRESS    *ImageAddress,
-  OUT UINT64                  *ImageSize,
-  OUT EFI_PHYSICAL_ADDRESS    *EntryPoint
-  )
-/*++
-
-Routine Description:
-  Loads and relocates a PE/COFF image into memory.
-
-Arguments:
-  Pe32Data         - The base address of the PE/COFF file that is to be loaded and relocated
-  ImageAddress     - The base address of the relocated PE/COFF image
-  ImageSize        - The size of the relocated PE/COFF image
-  EntryPoint       - The entry point of the relocated PE/COFF image
-
-Returns:
-  EFI_SUCCESS   - The file was loaded and relocated
-  EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
-
---*/
-{
-  EFI_STATUS                            Status;
-  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;
-
-  ZeroMem (&ImageContext, sizeof (ImageContext));
-  ImageContext.Handle     = Pe32Data;
-
-  ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) SecImageRead;
-
-  Status                  = PeCoffLoaderGetImageInfo (&ImageContext);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-
-  //
-  // Allocate space in UNIX (not emulator) memory. Extra space is for alignment
-  //
-  ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) MapMemory (
-    0,
-    (UINT32) (ImageContext.ImageSize + (ImageContext.SectionAlignment * 2)),
-    PROT_READ | PROT_WRITE | PROT_EXEC,
-    MAP_ANONYMOUS | MAP_PRIVATE
-    );
-  if (ImageContext.ImageAddress == 0) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  //
-  // Align buffer on section boundry
-  //
-  ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
-  ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)(ImageContext.SectionAlignment - 1));
-
-
-  Status = PeCoffLoaderLoadImage (&ImageContext);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  Status = PeCoffLoaderRelocateImage (&ImageContext);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-
-  SecPeCoffRelocateImageExtraAction (&ImageContext);
-
-  //
-  // BugBug: Flush Instruction Cache Here when CPU Lib is ready
-  //
-
-  *ImageAddress = ImageContext.ImageAddress;
-  *ImageSize    = ImageContext.ImageSize;
-  *EntryPoint   = ImageContext.EntryPoint;
-
-  return EFI_SUCCESS;
-}
-
-
-RETURN_STATUS
-EFIAPI
-SecPeCoffGetEntryPoint (
-  IN     VOID  *Pe32Data,
-  IN OUT VOID  **EntryPoint
-  )
-{
-  EFI_STATUS              Status;
-  EFI_PHYSICAL_ADDRESS    ImageAddress;
-  UINT64                  ImageSize;
-  EFI_PHYSICAL_ADDRESS    PhysEntryPoint;
-
-  Status = SecUnixPeiLoadFile (Pe32Data, &ImageAddress, &ImageSize, &PhysEntryPoint);
-
-  *EntryPoint = (VOID *)(UINTN)PhysEntryPoint;
-  return Status;
-}
-
-
-
-EFI_STATUS
-EFIAPI
-SecUnixFdAddress (
-  IN     UINTN                 Index,
-  IN OUT EFI_PHYSICAL_ADDRESS  *FdBase,
-  IN OUT UINT64                *FdSize,
-  IN OUT EFI_PHYSICAL_ADDRESS  *FixUp
-  )
-/*++
-
-Routine Description:
-  Return the FD Size and base address. Since the FD is loaded from a
-  file into host memory only the SEC will know it's address.
-
-Arguments:
-  Index  - Which FD, starts at zero.
-  FdSize - Size of the FD in bytes
-  FdBase - Start address of the FD. Assume it points to an FV Header
-  FixUp  - Difference between actual FD address and build address
-
-Returns:
-  EFI_SUCCESS     - Return the Base address and size of the FV
-  EFI_UNSUPPORTED - Index does nto map to an FD in the system
-
---*/
-{
-  if (Index >= gFdInfoCount) {
-    return EFI_UNSUPPORTED;
-  }
-
-  *FdBase = gFdInfo[Index].Address;
-  *FdSize = gFdInfo[Index].Size;
-  *FixUp  = 0;
-
-  if (*FdBase == 0 && *FdSize == 0) {
-    return EFI_UNSUPPORTED;
-  }
-
-  if (Index == 0) {
-    //
-    // FD 0 has XIP code and well known PCD values
-    // If the memory buffer could not be allocated at the FD build address
-    // the Fixup is the difference.
-    //
-    *FixUp = *FdBase - PcdGet64 (PcdUnixFdBaseAddress);
-  }
-
-  return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-SecImageRead (
-  IN     VOID    *FileHandle,
-  IN     UINTN   FileOffset,
-  IN OUT UINTN   *ReadSize,
-  OUT    VOID    *Buffer
-  )
-/*++
-
-Routine Description:
-  Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
-
-Arguments:
-  FileHandle - The handle to the PE/COFF file
-  FileOffset - The offset, in bytes, into the file to read
-  ReadSize   - The number of bytes to read from the file starting at FileOffset
-  Buffer     - A pointer to the buffer to read the data into.
-
-Returns:
-  EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
-
---*/
-{
-  CHAR8 *Destination8;
-  CHAR8 *Source8;
-  UINTN Length;
-
-  Destination8  = Buffer;
-  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
-  Length        = *ReadSize;
-  while (Length--) {
-    *(Destination8++) = *(Source8++);
-  }
-
-  return EFI_SUCCESS;
-}
-
-UINTN
-CountSeperatorsInString (
-  IN  const CHAR16   *String,
-  IN  CHAR16         Seperator
-  )
-/*++
-
-Routine Description:
-  Count the number of seperators in String
-
-Arguments:
-  String    - String to process
-  Seperator - Item to count
-
-Returns:
-  Number of Seperator in String
-
---*/
-{
-  UINTN Count;
-
-  for (Count = 0; *String != '\0'; String++) {
-    if (*String == Seperator) {
-      Count++;
-    }
-  }
-
-  return Count;
-}
-
-
-EFI_STATUS
-AddHandle (
-  IN  PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext,
-  IN  VOID                                 *ModHandle
-  )
-/*++
-
-Routine Description:
-  Store the ModHandle in an array indexed by the Pdb File name.
-  The ModHandle is needed to unload the image.
-
-Arguments:
-  ImageContext - Input data returned from PE Laoder Library. Used to find the
-                 .PDB file name of the PE Image.
-  ModHandle    - Returned from LoadLibraryEx() and stored for call to
-                 FreeLibrary().
-
-Returns:
-  EFI_SUCCESS - ModHandle was stored.
-
---*/
-{
-  UINTN                       Index;
-  IMAGE_CONTEXT_TO_MOD_HANDLE *Array;
-  UINTN                       PreviousSize;
-
-
-  Array = mImageContextModHandleArray;
-  for (Index = 0; Index < mImageContextModHandleArraySize; Index++, Array++) {
-    if (Array->ImageContext == NULL) {
-      //
-      // Make a copy of the stirng and store the ModHandle
-      //
-      Array->ImageContext = ImageContext;
-      Array->ModHandle    = ModHandle;
-      return EFI_SUCCESS;
-    }
-  }
-
-  //
-  // No free space in mImageContextModHandleArray so grow it by
-  // IMAGE_CONTEXT_TO_MOD_HANDLE entires. realloc will
-  // copy the old values to the new locaiton. But it does
-  // not zero the new memory area.
-  //
-  PreviousSize = mImageContextModHandleArraySize * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE);
-  mImageContextModHandleArraySize += MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE;
-
-  mImageContextModHandleArray = realloc (mImageContextModHandleArray, mImageContextModHandleArraySize * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE));
-  if (mImageContextModHandleArray == NULL) {
-    ASSERT (FALSE);
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  memset (mImageContextModHandleArray + PreviousSize, 0, MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE));
-
-  return AddHandle (ImageContext, ModHandle);
-}
-
-
-VOID *
-RemoveHandle (
-  IN  PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext
-  )
-/*++
-
-Routine Description:
-  Return the ModHandle and delete the entry in the array.
-
-Arguments:
-  ImageContext - Input data returned from PE Laoder Library. Used to find the
-                 .PDB file name of the PE Image.
-
-Returns:
-  ModHandle - ModHandle assoicated with ImageContext is returned
-  NULL      - No ModHandle associated with ImageContext
-
---*/
-{
-  UINTN                        Index;
-  IMAGE_CONTEXT_TO_MOD_HANDLE  *Array;
-
-  if (ImageContext->PdbPointer == NULL) {
-    //
-    // If no PDB pointer there is no ModHandle so return NULL
-    //
-    return NULL;
-  }
-
-  Array = mImageContextModHandleArray;
-  for (Index = 0; Index < mImageContextModHandleArraySize; Index++, Array++) {
-    if (Array->ImageContext == ImageContext) {
-      //
-      // If you find a match return it and delete the entry
-      //
-      Array->ImageContext = NULL;
-      return Array->ModHandle;
-    }
-  }
-
-  return NULL;
-}
-
-
-
-//
-// Target for gdb breakpoint in a script that uses gGdbWorkingFileName to source a
-// add-symbol-file command. Hey what can you say scripting in gdb is not that great....
-//
-// Put .gdbinit in the CWD where you do gdb SecMain.dll for source level debug
-//
-// cat .gdbinit
-// b SecGdbScriptBreak
-// command
-// silent
-// source SecMain.dll.gdb
-// c
-// end
-//
-VOID
-SecGdbScriptBreak (
-  VOID
-  )
-{
-}
-
-VOID
-SecUnixLoaderBreak (
-  VOID
-  )
-{
-}
-
-BOOLEAN
-IsPdbFile (
-  IN  CHAR8   *PdbFileName
-  )
-{
-  UINTN Len;
-
-  if (PdbFileName == NULL) {
-    return FALSE;
-  }
-
-  Len = strlen (PdbFileName);
-  if ((Len < 5)|| (PdbFileName[Len - 4] != '.')) {
-    return FALSE;
-  }
-
-  if ((PdbFileName[Len - 3] == 'D' || PdbFileName[Len - 3] == 'd') &&
-      (PdbFileName[Len - 2] == 'L' || PdbFileName[Len - 2] == 'l') &&
-      (PdbFileName[Len - 1] == 'L' || PdbFileName[Len - 1] == 'l')) {
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-
-#define MAX_SPRINT_BUFFER_SIZE 0x200
-
-void
-PrintLoadAddress (
-  IN PE_COFF_LOADER_IMAGE_CONTEXT          *ImageContext
-  )
-{
-  if (ImageContext->PdbPointer == NULL) {
-    fprintf (stderr,
-      "0x%08lx Loading NO DEBUG with entry point 0x%08lx\n",
-      (unsigned long)(ImageContext->ImageAddress),
-      (unsigned long)ImageContext->EntryPoint
-      );
-  } else {
-    fprintf (stderr,
-      "0x%08lx Loading %s with entry point 0x%08lx\n",
-      (unsigned long)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders),
-      ImageContext->PdbPointer,
-      (unsigned long)ImageContext->EntryPoint
-      );
-  }
-  // Keep output synced up
-  fflush (stderr);
-}
-
-
-VOID
-EFIAPI
-SecPeCoffRelocateImageExtraAction (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext
-  )
-{
-
-#ifdef __APPLE__
-  BOOLEAN EnabledOnEntry;
-
-   //
-   // Make sure writting of the file is an atomic operation
-   //
-   if (UnixInterruptEanbled ()) {
-     UnixDisableInterrupt ();
-     EnabledOnEntry = TRUE;
-   } else {
-     EnabledOnEntry = FALSE;
-   }
-
-  PrintLoadAddress (ImageContext);
-
-  //
-  // In mach-o (OS X executable) dlopen() can only load files in the MH_DYLIB of MH_BUNDLE format.
-  // To convert to PE/COFF we need to construct a mach-o with the MH_PRELOAD format. We create
-  // .dSYM files for the PE/COFF images that can be used by gdb for source level debugging.
-  //
-  FILE  *GdbTempFile;
-
-  //
-  // In the Mach-O to PE/COFF conversion the size of the PE/COFF headers is not accounted for.
-  // Thus we need to skip over the PE/COFF header when giving load addresses for our symbol table.
-  //
-  if (ImageContext->PdbPointer != NULL && !IsPdbFile (ImageContext->PdbPointer)) {
-    //
-    // Now we have a database of the images that are currently loaded
-    //
-
-    //
-    // 'symbol-file' will clear out currnet symbol mappings in gdb.
-    // you can do a 'add-symbol-file filename address' for every image we loaded to get source
-    // level debug in gdb. Note Sec, being a true application will work differently.
-    //
-    // We add the PE/COFF header size into the image as the mach-O does not have a header in
-    // loaded into system memory.
-    //
-    // This gives us a data base of gdb commands and after something is unloaded that entry will be
-    // removed. We don't yet have the scheme of how to comunicate with gdb, but we have the
-    // data base of info ready to roll.
-    //
-    // We could use qXfer:libraries:read, but OS X GDB does not currently support it.
-    //  <library-list>
-    //    <library name="/lib/libc.so.6">   // ImageContext->PdbPointer
-    //      <segment address="0x10000000"/> // ImageContext->ImageAddress + ImageContext->SizeOfHeaders
-    //    </library>
-    //  </library-list>
-    //
-
-    //
-    // Write the file we need for the gdb script
-    //
-    GdbTempFile = fopen (gGdbWorkingFileName, "w");
-    if (GdbTempFile != NULL) {
-      fprintf (GdbTempFile, "add-symbol-file %s 0x%08lx\n", ImageContext->PdbPointer, (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders));
-      fclose (GdbTempFile);
-
-      //
-      // Target for gdb breakpoint in a script that uses gGdbWorkingFileName to set a breakpoint.
-      // Hey what can you say scripting in gdb is not that great....
-      //
-      SecGdbScriptBreak ();
-    } else {
-      ASSERT (FALSE);
-    }
-
-    AddHandle (ImageContext, ImageContext->PdbPointer);
-
-    if (EnabledOnEntry) {
-      UnixEnableInterrupt ();
-    }
-
-    
-  }
-
-#else
-
-  void        *Handle = NULL;
-  void        *Entry = NULL;
-
-  if (ImageContext->PdbPointer == NULL) {
-    return;
-  }
-
-  if (!IsPdbFile (ImageContext->PdbPointer)) {
-    return;
-  }
-
-  fprintf (stderr,
-     "Loading %s 0x%08lx - entry point 0x%08lx\n",
-     ImageContext->PdbPointer,
-     (unsigned long)ImageContext->ImageAddress,
-     (unsigned long)ImageContext->EntryPoint);
-
-  Handle = dlopen (ImageContext->PdbPointer, RTLD_NOW);
-
-  if (Handle) {
-    Entry = dlsym (Handle, "_ModuleEntryPoint");
-  } else {
-    printf("%s\n", dlerror());
-  }
-
-  if (Entry != NULL) {
-    ImageContext->EntryPoint = (UINTN)Entry;
-    printf("Change %s Entrypoint to :0x%08lx\n", ImageContext->PdbPointer, (unsigned long)Entry);
-  }
-
-  SecUnixLoaderBreak ();
-
-#endif
-
-  return;
-}
-
-
-VOID
-EFIAPI
-SecPeCoffLoaderUnloadImageExtraAction (
-  IN PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext
-  )
-{
-  VOID *Handle;
-
-  Handle = RemoveHandle (ImageContext);
-
-#ifdef __APPLE__
-  FILE  *GdbTempFile;
-  BOOLEAN EnabledOnEntry;
-
-  if (Handle != NULL) {
-    //
-    // Need to skip .PDB files created from VC++
-    //
-    if (!IsPdbFile (ImageContext->PdbPointer)) {
-       if (UnixInterruptEanbled ()) {
-         UnixDisableInterrupt ();
-         EnabledOnEntry = TRUE;
-       } else {
-         EnabledOnEntry = FALSE;
-       }
-       
-      //
-      // Write the file we need for the gdb script
-      //
-      GdbTempFile = fopen (gGdbWorkingFileName, "w");
-      if (GdbTempFile != NULL) {
-        fprintf (GdbTempFile, "remove-symbol-file %s\n", ImageContext->PdbPointer);
-        fclose (GdbTempFile);
-
-        //
-        // Target for gdb breakpoint in a script that uses gGdbWorkingFileName to set a breakpoint.
-        // Hey what can you say scripting in gdb is not that great....
-        //
-        SecGdbScriptBreak ();
-      } else {
-        ASSERT (FALSE);
-      }
-      
-      if (EnabledOnEntry) {
-        UnixEnableInterrupt ();
-      }
-    }
-  }
-
-#else
-  //
-  // Don't want to confuse gdb with symbols for something that got unloaded
-  //
-  if (Handle != NULL) {
-    dlclose (Handle);
-  }
-
-#endif
-  return;
-}
-
-VOID
-ModuleEntryPoint (
-  VOID
-  )
-{
-}
-
-EFI_STATUS
-EFIAPI
-SecTemporaryRamSupport (
-  IN CONST EFI_PEI_SERVICES   **PeiServices,
-  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
-  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
-  IN UINTN                    CopySize
-  )
-{
-  //
-  // Migrate the whole temporary memory to permenent memory.
-  //
-  CopyMem (
-    (VOID*)(UINTN)PermanentMemoryBase,
-    (VOID*)(UINTN)TemporaryMemoryBase,
-    CopySize
-    );
-
-  //
-  // SecSwitchStack function must be invoked after the memory migration
-  // immediatly, also we need fixup the stack change caused by new call into
-  // permenent memory.
-  //
-  SecSwitchStack (
-    (UINT32) TemporaryMemoryBase,
-    (UINT32) PermanentMemoryBase
-    );
-
-  //
-  // We need *not* fix the return address because currently,
-  // The PeiCore is excuted in flash.
-  //
-
-  //
-  // Simulate to invalid temporary memory, terminate temporary memory
-  //
-  //ZeroMem ((VOID*)(UINTN)TemporaryMemoryBase, CopySize);
-
-  return EFI_SUCCESS;
-}