git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2337 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			1006 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1006 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*++
 | 
						|
 | 
						|
Copyright (c) 2006, Intel Corporation
 | 
						|
All rights reserved. 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:
 | 
						|
  WinNt 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 <stdlib.h>
 | 
						|
#include <sys/mman.h>
 | 
						|
#include <sys/fcntl.h>
 | 
						|
#include <unistd.h>
 | 
						|
 | 
						|
//
 | 
						|
// Globals
 | 
						|
//
 | 
						|
EFI_PEI_PE_COFF_LOADER_PROTOCOL_INSTANCE  mPeiEfiPeiPeCoffLoaderInstance = {
 | 
						|
  {
 | 
						|
    SecNt32PeCoffGetImageInfo,
 | 
						|
    SecNt32PeCoffLoadImage,
 | 
						|
    SecNt32PeCoffRelocateImage,
 | 
						|
    SecNt32PeCoffUnloadimage
 | 
						|
  },
 | 
						|
  NULL
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
 | 
						|
EFI_PEI_PE_COFF_LOADER_PROTOCOL           *gPeiEfiPeiPeCoffLoader = &mPeiEfiPeiPeCoffLoaderInstance.PeCoff;
 | 
						|
 | 
						|
UNIX_PEI_LOAD_FILE_PPI                      mSecNtLoadFilePpi     = { SecWinNtPeiLoadFile };
 | 
						|
 | 
						|
PEI_UNIX_AUTOSCAN_PPI                       mSecNtAutoScanPpi     = { SecWinNtPeiAutoScan };
 | 
						|
 | 
						|
PEI_UNIX_THUNK_PPI                          mSecWinNtThunkPpi     = { SecWinNtWinNtThunkAddress };
 | 
						|
 | 
						|
EFI_PEI_PROGRESS_CODE_PPI                 mSecStatusCodePpi     = { SecPeiReportStatusCode };
 | 
						|
 | 
						|
UNIX_FWH_PPI                                mSecFwhInformationPpi = { SecWinNtFdAddress };
 | 
						|
 | 
						|
 | 
						|
EFI_PEI_PPI_DESCRIPTOR  gPrivateDispatchTable[] = {
 | 
						|
  {
 | 
						|
    EFI_PEI_PPI_DESCRIPTOR_PPI,
 | 
						|
    &gEfiPeiPeCoffLoaderGuid,
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_PEI_PPI_DESCRIPTOR_PPI,
 | 
						|
    &gUnixPeiLoadFilePpiGuid,
 | 
						|
    &mSecNtLoadFilePpi
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_PEI_PPI_DESCRIPTOR_PPI,
 | 
						|
    &gPeiUnixAutoScanPpiGuid,
 | 
						|
    &mSecNtAutoScanPpi
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_PEI_PPI_DESCRIPTOR_PPI,
 | 
						|
    &gPeiUnixThunkPpiGuid,
 | 
						|
    &mSecWinNtThunkPpi
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_PEI_PPI_DESCRIPTOR_PPI,
 | 
						|
    &gEfiPeiStatusCodePpiGuid,
 | 
						|
    &mSecStatusCodePpi
 | 
						|
  },
 | 
						|
  {
 | 
						|
    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;
 | 
						|
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_PHYSICAL_ADDRESS *
 | 
						|
MapMemory (
 | 
						|
  INTN fd,
 | 
						|
  UINT64 length,
 | 
						|
  INTN   prot,
 | 
						|
  INTN   flags);
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
MapFile (
 | 
						|
  IN  CHAR8                     *FileName,
 | 
						|
  IN OUT  EFI_PHYSICAL_ADDRESS  *BaseAddress,
 | 
						|
  OUT UINT64                    *Length
 | 
						|
  );
 | 
						|
 | 
						|
 | 
						|
INTN
 | 
						|
EFIAPI
 | 
						|
main (
 | 
						|
  IN  INTN  Argc,
 | 
						|
  IN  CHAR8 **Argv,
 | 
						|
  IN  CHAR8 **Envp
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Main entry point to SEC for WinNt. 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;
 | 
						|
 | 
						|
  MemorySizeStr      = (CHAR16 *)PcdGetPtr (PcdUnixMemorySizeForSecMain);
 | 
						|
  FirmwareVolumesStr = (CHAR16 *)PcdGetPtr (PcdUnixFirmwareVolume);
 | 
						|
 | 
						|
  printf ("\nEDK SEC Main UNIX Emulation Environment from www.TianoCore.org\n");
 | 
						|
 | 
						|
  //
 | 
						|
  // 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", FixedPcdGet32 (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 WinNtOpenFile will allocate a new mapping
 | 
						|
  //
 | 
						|
  InitialStackMemorySize  = 0x20000;
 | 
						|
  InitialStackMemory = (UINTN)MapMemory(0, 
 | 
						|
					(UINT32) InitialStackMemorySize,
 | 
						|
					PROT_READ | PROT_WRITE,
 | 
						|
					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",
 | 
						|
	  (UINTN)(InitialStackMemorySize / 1024),
 | 
						|
	  (unsigned long)InitialStackMemory);
 | 
						|
 | 
						|
  //
 | 
						|
  // 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, 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 WinNt 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
 | 
						|
 | 
						|
/**
 | 
						|
  Extracts ASSERT() information from a status code structure.
 | 
						|
 | 
						|
  Converts the status code specified by CodeType, Value, and Data to the ASSERT()
 | 
						|
  arguments specified by Filename, Description, and LineNumber.  If CodeType is 
 | 
						|
  an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and 
 | 
						|
  Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract 
 | 
						|
  Filename, Description, and LineNumber from the optional data area of the 
 | 
						|
  status code buffer specified by Data.  The optional data area of Data contains 
 | 
						|
  a Null-terminated ASCII string for the FileName, followed by a Null-terminated 
 | 
						|
  ASCII string for the Description, followed by a 32-bit LineNumber.  If the 
 | 
						|
  ASSERT() information could be extracted from Data, then return TRUE.  
 | 
						|
  Otherwise, FALSE is returned.  
 | 
						|
 | 
						|
  If Data is NULL, then ASSERT().
 | 
						|
  If Filename is NULL, then ASSERT().
 | 
						|
  If Description is NULL, then ASSERT().
 | 
						|
  If LineNumber is NULL, then ASSERT().
 | 
						|
 | 
						|
  @param  CodeType     The type of status code being converted.
 | 
						|
  @param  Value        The status code value being converted.
 | 
						|
  @param  Data         Pointer to status code data buffer. 
 | 
						|
  @param  Filename     Pointer to the source file name that generated the ASSERT().
 | 
						|
  @param  Description  Pointer to the description of the ASSERT().
 | 
						|
  @param  LineNumber   Pointer to source line number that generated the ASSERT().
 | 
						|
 | 
						|
  @retval  TRUE   The status code specified by CodeType, Value, and Data was 
 | 
						|
                  converted ASSERT() arguments specified by Filename, Description, 
 | 
						|
                  and LineNumber.
 | 
						|
  @retval  FALSE  The status code specified by CodeType, Value, and Data could 
 | 
						|
                  not be converted to ASSERT() arguments.
 | 
						|
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
BOOLEAN
 | 
						|
ReportStatusCodeExtractAssertInfo (
 | 
						|
  IN EFI_STATUS_CODE_TYPE        CodeType,
 | 
						|
  IN EFI_STATUS_CODE_VALUE       Value,  
 | 
						|
  IN CONST EFI_STATUS_CODE_DATA  *Data, 
 | 
						|
  OUT CHAR8                      **Filename,
 | 
						|
  OUT CHAR8                      **Description,
 | 
						|
  OUT UINT32                     *LineNumber
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_DEBUG_ASSERT_DATA  *AssertData;
 | 
						|
 | 
						|
  ASSERT (Data        != NULL);
 | 
						|
  ASSERT (Filename    != NULL);
 | 
						|
  ASSERT (Description != NULL);
 | 
						|
  ASSERT (LineNumber  != NULL);
 | 
						|
 | 
						|
  if (((CodeType & EFI_STATUS_CODE_TYPE_MASK)      == EFI_ERROR_CODE) && 
 | 
						|
      ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK)  == EFI_ERROR_UNRECOVERED) &&
 | 
						|
      ((Value    & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)) {
 | 
						|
    AssertData   = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);
 | 
						|
    *Filename    = (CHAR8 *)(AssertData + 1);
 | 
						|
    *Description = *Filename + AsciiStrLen (*Filename) + 1;
 | 
						|
    *LineNumber  = AssertData->LineNumber;
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
SecPeiReportStatusCode (
 | 
						|
  IN EFI_PEI_SERVICES           **PeiServices,
 | 
						|
  IN EFI_STATUS_CODE_TYPE       CodeType,
 | 
						|
  IN EFI_STATUS_CODE_VALUE      Value,
 | 
						|
  IN UINT32                     Instance,
 | 
						|
  IN EFI_GUID                   * CallerId,
 | 
						|
  IN 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;
 | 
						|
  EFI_DEBUG_INFO  *DebugInfo;
 | 
						|
  VA_LIST         Marker;
 | 
						|
  CHAR8           PrintBuffer[BYTES_PER_RECORD * 2];
 | 
						|
  CHAR8           *Filename;
 | 
						|
  CHAR8           *Description;
 | 
						|
  UINT32          LineNumber;
 | 
						|
 | 
						|
  if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {
 | 
						|
    //
 | 
						|
    // This supports DEBUG () marcos
 | 
						|
    // Data format
 | 
						|
    //  EFI_STATUS_CODE_DATA
 | 
						|
    //  EFI_DEBUG_INFO
 | 
						|
    //
 | 
						|
    // The first 12 * UINT64 bytes of the string are really an
 | 
						|
    // arguement stack to support varargs on the Format string.
 | 
						|
    //
 | 
						|
    if (Data != NULL) {
 | 
						|
      DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);
 | 
						|
      Marker    = (VA_LIST) (DebugInfo + 1);
 | 
						|
      Format    = (CHAR8 *) (((UINT64 *) Marker) + 12);
 | 
						|
 | 
						|
      AsciiVSPrint (PrintBuffer, BYTES_PER_RECORD, Format, Marker);
 | 
						|
      printf (PrintBuffer);
 | 
						|
    } else {
 | 
						|
      printf ("DEBUG <null>\n");
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&
 | 
						|
      ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED)
 | 
						|
      ) {
 | 
						|
    if (Data != NULL && ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
 | 
						|
      //
 | 
						|
      // Support ASSERT () macro
 | 
						|
      //
 | 
						|
      printf ("ASSERT %s(%d): %s\n", Filename, LineNumber, Description);
 | 
						|
    } else {
 | 
						|
      printf ("ASSERT <null>\n");
 | 
						|
    }
 | 
						|
    CpuBreakpoint ();
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
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_PEI_STARTUP_DESCRIPTOR  *PeiStartup;
 | 
						|
 | 
						|
  //
 | 
						|
  // Compute Top Of Memory for Stack and PEI Core Allocations
 | 
						|
  //
 | 
						|
  TopOfMemory = LargestRegion + LargestRegionSize;
 | 
						|
 | 
						|
  //
 | 
						|
  // Allocate 128KB for the Stack
 | 
						|
  //
 | 
						|
  TopOfStack  = (VOID *)((UINTN)TopOfMemory - sizeof (EFI_PEI_STARTUP_DESCRIPTOR) - CPU_STACK_ALIGNMENT);
 | 
						|
  TopOfStack  = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
 | 
						|
  TopOfMemory = TopOfMemory - STACK_SIZE;
 | 
						|
 | 
						|
  //
 | 
						|
  // Patch value in dispatch table values
 | 
						|
  //
 | 
						|
  gPrivateDispatchTable[0].Ppi = gPeiEfiPeiPeCoffLoader;
 | 
						|
 | 
						|
  //
 | 
						|
  // Bind this information into the SEC hand-off state
 | 
						|
  //
 | 
						|
  PeiStartup = (EFI_PEI_STARTUP_DESCRIPTOR *) (UINTN) TopOfStack;
 | 
						|
  PeiStartup->DispatchTable      = (EFI_PEI_PPI_DESCRIPTOR *) &gPrivateDispatchTable;
 | 
						|
  PeiStartup->SizeOfCacheAsRam   = STACK_SIZE;
 | 
						|
  PeiStartup->BootFirmwareVolume = BootFirmwareVolumeBase;
 | 
						|
 | 
						|
  //
 | 
						|
  // Load the PEI Core from a Firmware Volume
 | 
						|
  //
 | 
						|
  Status = SecWinNtPeiLoadFile (
 | 
						|
            PeiCorePe32File,
 | 
						|
            &PeiImageAddress,
 | 
						|
            &PeiCoreSize,
 | 
						|
            &PeiCoreEntryPoint
 | 
						|
            );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return ;
 | 
						|
  }
 | 
						|
  printf ("Jump to 0x%08lx\n", (unsigned long)PeiCoreEntryPoint);
 | 
						|
  //
 | 
						|
  // Transfer control to the PEI Core
 | 
						|
  //
 | 
						|
  SwitchStack (
 | 
						|
    (SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint,
 | 
						|
    PeiStartup,
 | 
						|
    NULL,
 | 
						|
    TopOfStack
 | 
						|
    );
 | 
						|
  //
 | 
						|
  // If we get here, then the PEI Core returned.  This is an error
 | 
						|
  //
 | 
						|
  return ;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
SecWinNtPeiAutoScan (
 | 
						|
  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
 | 
						|
  WinNtOpenFile.
 | 
						|
 | 
						|
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
 | 
						|
SecWinNtWinNtThunkAddress (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Since the SEC is the only Unix program in stack it must export
 | 
						|
  an interface to do Win API calls. That's what the WinNtThunk address
 | 
						|
  is for. gWinNt is initailized in WinNtThunk.c.
 | 
						|
 | 
						|
Arguments:
 | 
						|
  InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL);
 | 
						|
  InterfaceBase - Address of the gWinNt global
 | 
						|
 | 
						|
Returns:
 | 
						|
  EFI_SUCCESS - Data returned
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  return gUnix;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
SecWinNtPeiLoadFile (
 | 
						|
  IN  VOID                    *Pe32Data,
 | 
						|
  IN  EFI_PHYSICAL_ADDRESS    *ImageAddress,
 | 
						|
  IN  UINT64                  *ImageSize,
 | 
						|
  IN  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                  = gPeiEfiPeiPeCoffLoader->GetImageInfo (gPeiEfiPeiPeCoffLoader, &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) malloc ((UINTN) (ImageContext.ImageSize + (ImageContext.SectionAlignment * 2)));
 | 
						|
  if (ImageContext.ImageAddress == 0) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Align buffer on section boundry
 | 
						|
  //
 | 
						|
  ImageContext.ImageAddress += ImageContext.SectionAlignment;
 | 
						|
  ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);
 | 
						|
 | 
						|
 | 
						|
  Status = gPeiEfiPeiPeCoffLoader->LoadImage (gPeiEfiPeiPeCoffLoader, &ImageContext);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = gPeiEfiPeiPeCoffLoader->RelocateImage (gPeiEfiPeiPeCoffLoader, &ImageContext);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // BugBug: Flush Instruction Cache Here when CPU Lib is ready
 | 
						|
  //
 | 
						|
 | 
						|
  *ImageAddress = ImageContext.ImageAddress;
 | 
						|
  *ImageSize    = ImageContext.ImageSize;
 | 
						|
  *EntryPoint   = ImageContext.EntryPoint;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
SecWinNtFdAddress (
 | 
						|
  IN     UINTN                 Index,
 | 
						|
  IN OUT EFI_PHYSICAL_ADDRESS  *FdBase,
 | 
						|
  IN OUT UINT64                *FdSize
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
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
 | 
						|
 | 
						|
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;
 | 
						|
 | 
						|
  if (*FdBase == 0 && *FdSize == 0) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  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
 | 
						|
EFIAPI
 | 
						|
SecNt32PeCoffGetImageInfo (
 | 
						|
  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,
 | 
						|
  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  Status = PeCoffLoaderGetImageInfo (ImageContext);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  switch (ImageContext->ImageType) {
 | 
						|
 | 
						|
  case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
 | 
						|
    ImageContext->ImageCodeMemoryType = EfiLoaderCode;
 | 
						|
    ImageContext->ImageDataMemoryType = EfiLoaderData;
 | 
						|
    break;
 | 
						|
 | 
						|
  case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
 | 
						|
    ImageContext->ImageCodeMemoryType = EfiBootServicesCode;
 | 
						|
    ImageContext->ImageDataMemoryType = EfiBootServicesData;
 | 
						|
    break;
 | 
						|
 | 
						|
  case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
 | 
						|
  case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
 | 
						|
    ImageContext->ImageCodeMemoryType = EfiRuntimeServicesCode;
 | 
						|
    ImageContext->ImageDataMemoryType = EfiRuntimeServicesData;
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;
 | 
						|
    return RETURN_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
SecNt32PeCoffLoadImage (
 | 
						|
  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,
 | 
						|
  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  Status = PeCoffLoaderLoadImage (ImageContext);
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
SecUnixLoaderBreak (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
SecNt32PeCoffRelocateImage (
 | 
						|
  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL          *This,
 | 
						|
  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext
 | 
						|
  )
 | 
						|
{
 | 
						|
 | 
						|
#if 0
 | 
						|
  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
 | 
						|
  EFI_IMAGE_SECTION_HEADER *Sec;
 | 
						|
  INTN i;
 | 
						|
#endif
 | 
						|
 | 
						|
  fprintf (stderr, 
 | 
						|
	   "Loading %s 0x%08lx - entry point 0x%08lx\n",
 | 
						|
	   ImageContext->PdbPointer,
 | 
						|
	   (unsigned long)ImageContext->ImageAddress,
 | 
						|
	   (unsigned long)ImageContext->EntryPoint);
 | 
						|
 | 
						|
#if 0
 | 
						|
  Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)
 | 
						|
    ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);
 | 
						|
  Sec = (EFI_IMAGE_SECTION_HEADER*)
 | 
						|
    ((UINTN)ImageContext->ImageAddress
 | 
						|
     + ImageContext->PeCoffHeaderOffset
 | 
						|
     + sizeof(UINT32)
 | 
						|
     + sizeof(EFI_IMAGE_FILE_HEADER)
 | 
						|
     + Hdr.Pe32->FileHeader.SizeOfOptionalHeader);
 | 
						|
  for (i = 0; i < Hdr.Pe32->FileHeader.NumberOfSections; i++)
 | 
						|
    fprintf (stderr, "  %s 0x%08lx\n",
 | 
						|
	     Sec[i].Name, (unsigned long)Sec[i].VirtualAddress);
 | 
						|
#endif
 | 
						|
 | 
						|
  SecUnixLoaderBreak ();
 | 
						|
 | 
						|
  return PeCoffLoaderRelocateImage (ImageContext);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
SecNt32PeCoffUnloadimage (
 | 
						|
  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL      *This,
 | 
						|
  IN PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext
 | 
						|
  )
 | 
						|
{
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
_ModuleEntryPoint (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
}
 | 
						|
 |