They only provided a single #define that is associated with DEBUG() messages sent through ReportStatusCode. That one #define has now been added to <Guid/StatusCodeDataTypeDebug.h> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8489 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			1090 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1090 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/**@file
 | 
						|
 | 
						|
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 Win32 application, but this is
 | 
						|
  Ok since all the other modules for NT32 are NOT Win32 applications.
 | 
						|
 | 
						|
  This program gets NT32 PCD setting 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 directly
 | 
						|
  allocate memory space with ReadWrite and Execute attribute.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "SecMain.h"
 | 
						|
 | 
						|
 | 
						|
 | 
						|
NT_PEI_LOAD_FILE_PPI                      mSecNtLoadFilePpi     = { SecWinNtPeiLoadFile };
 | 
						|
 | 
						|
PEI_NT_AUTOSCAN_PPI                       mSecNtAutoScanPpi     = { SecWinNtPeiAutoScan };
 | 
						|
 | 
						|
PEI_NT_THUNK_PPI                          mSecWinNtThunkPpi     = { SecWinNtWinNtThunkAddress };
 | 
						|
 | 
						|
EFI_PEI_PROGRESS_CODE_PPI                 mSecStatusCodePpi     = { SecPeiReportStatusCode };
 | 
						|
 | 
						|
NT_FWH_PPI                                mSecFwhInformationPpi = { SecWinNtFdAddress };
 | 
						|
 | 
						|
TEMPORARY_RAM_SUPPORT_PPI                 mSecTemporaryRamSupportPpi = {SecTemporaryRamSupport};
 | 
						|
 | 
						|
EFI_PEI_PPI_DESCRIPTOR  gPrivateDispatchTable[] = {
 | 
						|
  {
 | 
						|
    EFI_PEI_PPI_DESCRIPTOR_PPI,
 | 
						|
    &gNtPeiLoadFilePpiGuid,
 | 
						|
    &mSecNtLoadFilePpi
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_PEI_PPI_DESCRIPTOR_PPI,
 | 
						|
    &gPeiNtAutoScanPpiGuid,
 | 
						|
    &mSecNtAutoScanPpi
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_PEI_PPI_DESCRIPTOR_PPI,
 | 
						|
    &gPeiNtThunkPpiGuid,
 | 
						|
    &mSecWinNtThunkPpi
 | 
						|
  },
 | 
						|
  {
 | 
						|
    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,
 | 
						|
    &gNtFwhPpiGuid,
 | 
						|
    &mSecFwhInformationPpi
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
// Default information about where the FD is located.
 | 
						|
//  This array gets filled in with information from PcdWinNtFirmwareVolume
 | 
						|
//  The number of array elements is allocated base on parsing
 | 
						|
//  PcdWinNtFirmwareVolume and the memory is never freed.
 | 
						|
//
 | 
						|
UINTN                                     gFdInfoCount = 0;
 | 
						|
NT_FD_INFO                                *gFdInfo;
 | 
						|
 | 
						|
//
 | 
						|
// Array that supports seperate memory rantes.
 | 
						|
//  The memory ranges are set by PcdWinNtMemorySizeForSecMain.
 | 
						|
//  The number of array elements is allocated base on parsing
 | 
						|
//  PcdWinNtMemorySizeForSecMain value and the memory is never freed.
 | 
						|
//
 | 
						|
UINTN                                     gSystemMemoryCount = 0;
 | 
						|
NT_SYSTEM_MEMORY                          *gSystemMemory;
 | 
						|
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
SecSwitchStack (
 | 
						|
  UINT32   TemporaryMemoryBase,
 | 
						|
  UINT32   PermenentMemoryBase
 | 
						|
  );
 | 
						|
EFI_STATUS
 | 
						|
SecNt32PeCoffRelocateImage (
 | 
						|
  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext
 | 
						|
  );
 | 
						|
 | 
						|
VOID
 | 
						|
SecPrint (
 | 
						|
  CHAR8  *Format,
 | 
						|
  ...
 | 
						|
  )
 | 
						|
{
 | 
						|
  va_list  Marker;
 | 
						|
  UINTN    CharCount;
 | 
						|
  CHAR8    Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
 | 
						|
 | 
						|
  va_start (Marker, Format);
 | 
						|
  
 | 
						|
  _vsnprintf (Buffer, sizeof (Buffer), Format, Marker);
 | 
						|
 | 
						|
  CharCount = strlen (Buffer);
 | 
						|
  WriteFile (
 | 
						|
    GetStdHandle (STD_OUTPUT_HANDLE), 
 | 
						|
    Buffer,
 | 
						|
    CharCount,
 | 
						|
    (LPDWORD)&CharCount,
 | 
						|
    NULL
 | 
						|
    );
 | 
						|
}
 | 
						|
 | 
						|
INTN
 | 
						|
EFIAPI
 | 
						|
main (
 | 
						|
  IN  INTN  Argc,
 | 
						|
  IN  CHAR8 **Argv,
 | 
						|
  IN  CHAR8 **Envp
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Main entry point to SEC for WinNt. This is a Windows 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;
 | 
						|
  CHAR16                *FileName;
 | 
						|
  CHAR16                *FileNamePtr;
 | 
						|
  BOOLEAN               Done;
 | 
						|
  VOID                  *PeiCoreFile;
 | 
						|
  CHAR16                *MemorySizeStr;
 | 
						|
  CHAR16                *FirmwareVolumesStr;
 | 
						|
  UINTN                 *StackPointer;
 | 
						|
 | 
						|
  MemorySizeStr      = (CHAR16 *) FixedPcdGetPtr (PcdWinNtMemorySizeForSecMain);
 | 
						|
  FirmwareVolumesStr = (CHAR16 *) FixedPcdGetPtr (PcdWinNtFirmwareVolume);
 | 
						|
 | 
						|
  SecPrint ("\nEDK II SEC Main NT Emulation Environment from www.TianoCore.org\n");
 | 
						|
 | 
						|
  //
 | 
						|
  // Make some Windows calls to Set the process to the highest priority in the
 | 
						|
  //  idle class. We need this to have good performance.
 | 
						|
  //
 | 
						|
  SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS);
 | 
						|
  SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
 | 
						|
 | 
						|
  //
 | 
						|
  // Allocate space for gSystemMemory Array
 | 
						|
  //
 | 
						|
  gSystemMemoryCount  = CountSeperatorsInString (MemorySizeStr, '!') + 1;
 | 
						|
  gSystemMemory       = calloc (gSystemMemoryCount, sizeof (NT_SYSTEM_MEMORY));
 | 
						|
  if (gSystemMemory == NULL) {
 | 
						|
    SecPrint ("ERROR : Can not allocate memory for %S.  Exiting.\n", MemorySizeStr);
 | 
						|
    exit (1);
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Allocate space for gSystemMemory Array
 | 
						|
  //
 | 
						|
  gFdInfoCount  = CountSeperatorsInString (FirmwareVolumesStr, '!') + 1;
 | 
						|
  gFdInfo       = calloc (gFdInfoCount, sizeof (NT_FD_INFO));
 | 
						|
  if (gFdInfo == NULL) {
 | 
						|
    SecPrint ("ERROR : Can not allocate memory for %S.  Exiting.\n", FirmwareVolumesStr);
 | 
						|
    exit (1);
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Setup Boot Mode. If BootModeStr == "" then BootMode = 0 (BOOT_WITH_FULL_CONFIGURATION)
 | 
						|
  //
 | 
						|
  SecPrint ("  BootMode 0x%02x\n", FixedPcdGet32 (PcdWinNtBootMode));
 | 
						|
 | 
						|
  //
 | 
						|
  //  Allocate 128K memory 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  = STACK_SIZE;
 | 
						|
  InitialStackMemory = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (InitialStackMemorySize), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 | 
						|
  if (InitialStackMemory == 0) {
 | 
						|
    SecPrint ("ERROR : Can not allocate enough space for SecStack\n");
 | 
						|
    exit (1);
 | 
						|
  }
 | 
						|
 | 
						|
  for (StackPointer = (UINTN*) (UINTN) InitialStackMemory;
 | 
						|
       StackPointer < (UINTN*) ((UINTN)InitialStackMemory + (SIZE_T) InitialStackMemorySize);
 | 
						|
       StackPointer ++) {
 | 
						|
    *StackPointer = 0x5AA55AA5;
 | 
						|
  }
 | 
						|
  
 | 
						|
  SecPrint ("  SEC passing in %d bytes of temp RAM to PEI\n", InitialStackMemorySize);
 | 
						|
 | 
						|
  //
 | 
						|
  // Open All the firmware volumes and remember the info in the gFdInfo global
 | 
						|
  //
 | 
						|
  FileNamePtr = (CHAR16 *)malloc (StrLen ((CHAR16 *)FirmwareVolumesStr) * sizeof(CHAR16));
 | 
						|
  if (FileNamePtr == NULL) {
 | 
						|
    SecPrint ("ERROR : Can not allocate memory for firmware volume string\n");
 | 
						|
    exit (1);
 | 
						|
  }
 | 
						|
 | 
						|
  StrCpy (FileNamePtr, (CHAR16*)FirmwareVolumesStr);
 | 
						|
 | 
						|
  for (Done = FALSE, Index = 0, PeiCoreFile = NULL; !Done; Index++) {
 | 
						|
    FileName = FileNamePtr;
 | 
						|
    for (Index1 = 0; (FileNamePtr[Index1] != '!') && (FileNamePtr[Index1] != 0); Index1++)
 | 
						|
      ;
 | 
						|
    if (FileNamePtr[Index1] == 0) {
 | 
						|
      Done = TRUE;
 | 
						|
    } else {
 | 
						|
      FileNamePtr[Index1]  = '\0';
 | 
						|
      FileNamePtr = FileNamePtr + Index1 + 1;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Open the FD and remmeber where it got mapped into our processes address space
 | 
						|
    //
 | 
						|
    Status = WinNtOpenFile (
 | 
						|
              FileName,
 | 
						|
              0,
 | 
						|
              OPEN_EXISTING,
 | 
						|
              &gFdInfo[Index].Address,
 | 
						|
              &gFdInfo[Index].Size
 | 
						|
              );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      SecPrint ("ERROR : Can not open Firmware Device File %S (0x%X).  Exiting.\n", FileName, Status);
 | 
						|
      exit (1);
 | 
						|
    }
 | 
						|
 | 
						|
    SecPrint ("  FD loaded from");
 | 
						|
    //
 | 
						|
    // printf can't print filenames directly as the \ gets interperted as an
 | 
						|
    //  escape character.
 | 
						|
    //
 | 
						|
    for (Index2 = 0; FileName[Index2] != '\0'; Index2++) {
 | 
						|
      SecPrint ("%c", FileName[Index2]);
 | 
						|
    }
 | 
						|
 | 
						|
    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)) {
 | 
						|
        SecPrint (" contains SEC Core");
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    SecPrint ("\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.
 | 
						|
  //
 | 
						|
  for (Index = 0, Done = FALSE; !Done; Index++) {
 | 
						|
    //
 | 
						|
    // Save the size of the memory and make a Unicode filename SystemMemory00, ...
 | 
						|
    //
 | 
						|
    gSystemMemory[Index].Size = _wtoi (MemorySizeStr) * 0x100000;
 | 
						|
 | 
						|
    //
 | 
						|
    // Find the next region
 | 
						|
    //
 | 
						|
    for (Index1 = 0; MemorySizeStr[Index1] != '!' && MemorySizeStr[Index1] != 0; Index1++)
 | 
						|
      ;
 | 
						|
    if (MemorySizeStr[Index1] == 0) {
 | 
						|
      Done = TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
    MemorySizeStr = MemorySizeStr + Index1 + 1;
 | 
						|
  }
 | 
						|
 | 
						|
  SecPrint ("\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.
 | 
						|
  //
 | 
						|
  SecPrint ("ERROR : PEI Core returned\n");
 | 
						|
  exit (1);
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
WinNtOpenFile (
 | 
						|
  IN  CHAR16                    *FileName,
 | 
						|
  IN  UINT32                    MapSize,
 | 
						|
  IN  DWORD                     CreationDisposition,
 | 
						|
  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
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  HANDLE  NtFileHandle;
 | 
						|
  HANDLE  NtMapHandle;
 | 
						|
  VOID    *VirtualAddress;
 | 
						|
  UINTN   FileSize;
 | 
						|
 | 
						|
  //
 | 
						|
  // Use Win API to open/create a file
 | 
						|
  //
 | 
						|
  NtFileHandle = CreateFile (
 | 
						|
                  FileName,
 | 
						|
                  GENERIC_READ | GENERIC_WRITE,
 | 
						|
                  FILE_SHARE_READ,
 | 
						|
                  NULL,
 | 
						|
                  CreationDisposition,
 | 
						|
                  FILE_ATTRIBUTE_NORMAL,
 | 
						|
                  NULL
 | 
						|
                  );
 | 
						|
  if (NtFileHandle == INVALID_HANDLE_VALUE) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Map the open file into a memory range
 | 
						|
  //
 | 
						|
  NtMapHandle = CreateFileMapping (
 | 
						|
                  NtFileHandle,
 | 
						|
                  NULL,
 | 
						|
                  PAGE_READWRITE,
 | 
						|
                  0,
 | 
						|
                  MapSize,
 | 
						|
                  NULL
 | 
						|
                  );
 | 
						|
  if (NtMapHandle == NULL) {
 | 
						|
    return EFI_DEVICE_ERROR;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Get the virtual address (address in the emulator) of the mapped file
 | 
						|
  //
 | 
						|
  VirtualAddress = MapViewOfFileEx (
 | 
						|
                    NtMapHandle,
 | 
						|
                    FILE_MAP_ALL_ACCESS,
 | 
						|
                    0,
 | 
						|
                    0,
 | 
						|
                    MapSize,
 | 
						|
                    (LPVOID) (UINTN) *BaseAddress
 | 
						|
                    );
 | 
						|
  if (VirtualAddress == NULL) {
 | 
						|
    return EFI_DEVICE_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  if (MapSize == 0) {
 | 
						|
    //
 | 
						|
    // Seek to the end of the file to figure out the true file size.
 | 
						|
    //
 | 
						|
    FileSize = SetFilePointer (
 | 
						|
                NtFileHandle,
 | 
						|
                0,
 | 
						|
                NULL,
 | 
						|
                FILE_END
 | 
						|
                );
 | 
						|
    if (FileSize == -1) {
 | 
						|
      return EFI_DEVICE_ERROR;
 | 
						|
    }
 | 
						|
 | 
						|
    *Length = (UINT64) FileSize;
 | 
						|
  } else {
 | 
						|
    *Length = (UINT64) MapSize;
 | 
						|
  }
 | 
						|
 | 
						|
  *BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAddress;
 | 
						|
 | 
						|
  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 NT 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 ()
 | 
						|
    //
 | 
						|
    SecPrint ("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);
 | 
						|
    SecPrint (PrintBuffer);
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Transfers control to a function starting with a new stack.
 | 
						|
 | 
						|
  Transfers control to the function specified by EntryPoint using the new stack
 | 
						|
  specified by NewStack and passing in the parameters specified by Context1 and
 | 
						|
  Context2. Context1 and Context2 are optional and may be NULL. The function
 | 
						|
  EntryPoint must never return.
 | 
						|
 | 
						|
  If EntryPoint is NULL, then ASSERT().
 | 
						|
  If NewStack is NULL, then ASSERT().
 | 
						|
 | 
						|
  @param  EntryPoint  A pointer to function to call with the new stack.
 | 
						|
  @param  Context1    A pointer to the context to pass into the EntryPoint
 | 
						|
                      function.
 | 
						|
  @param  Context2    A pointer to the context to pass into the EntryPoint
 | 
						|
                      function.
 | 
						|
  @param  NewStack    A pointer to the new stack to use for the EntryPoint
 | 
						|
                      function.
 | 
						|
  @param  NewBsp      A pointer to the new BSP for the EntryPoint on IPF. It's
 | 
						|
                      Reserved on other architectures.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
PeiSwitchStacks (
 | 
						|
  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,
 | 
						|
  IN      VOID                      *Context1,  OPTIONAL
 | 
						|
  IN      VOID                      *Context2,  OPTIONAL
 | 
						|
  IN      VOID                      *Context3,  OPTIONAL
 | 
						|
  IN      VOID                      *NewStack
 | 
						|
  )
 | 
						|
{
 | 
						|
  BASE_LIBRARY_JUMP_BUFFER  JumpBuffer;
 | 
						|
  
 | 
						|
  ASSERT (EntryPoint != NULL);
 | 
						|
  ASSERT (NewStack != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // Stack should be aligned with CPU_STACK_ALIGNMENT
 | 
						|
  //
 | 
						|
  ASSERT (((UINTN)NewStack & (CPU_STACK_ALIGNMENT - 1)) == 0);
 | 
						|
 | 
						|
  JumpBuffer.Eip = (UINTN)EntryPoint;
 | 
						|
  JumpBuffer.Esp = (UINTN)NewStack - sizeof (VOID*);
 | 
						|
  JumpBuffer.Esp -= sizeof (Context1) + sizeof (Context2) + sizeof(Context3);
 | 
						|
  ((VOID**)JumpBuffer.Esp)[1] = Context1;
 | 
						|
  ((VOID**)JumpBuffer.Esp)[2] = Context2;
 | 
						|
  ((VOID**)JumpBuffer.Esp)[3] = Context3;
 | 
						|
 | 
						|
  LongJump (&JumpBuffer, (UINTN)-1);
 | 
						|
  
 | 
						|
 | 
						|
  //
 | 
						|
  // InternalSwitchStack () will never return
 | 
						|
  //
 | 
						|
  ASSERT (FALSE);  
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
  VOID                        *TopOfStack;
 | 
						|
  UINT64                      PeiCoreSize;
 | 
						|
  EFI_PHYSICAL_ADDRESS        PeiCoreEntryPoint;
 | 
						|
  EFI_PHYSICAL_ADDRESS        PeiImageAddress;
 | 
						|
  EFI_SEC_PEI_HAND_OFF        *SecCoreData;
 | 
						|
  UINTN                       PeiStackSize;
 | 
						|
 | 
						|
  //
 | 
						|
  // Compute Top Of Memory for Stack and PEI Core Allocations
 | 
						|
  //
 | 
						|
  PeiStackSize = (UINTN)RShiftU64((UINT64)STACK_SIZE,1);
 | 
						|
 | 
						|
  //
 | 
						|
  // |-----------| <---- TemporaryRamBase + TemporaryRamSize
 | 
						|
  // |   Heap    |
 | 
						|
  // |           |
 | 
						|
  // |-----------| <---- StackBase / PeiTemporaryMemoryBase
 | 
						|
  // |           |
 | 
						|
  // |  Stack    |
 | 
						|
  // |-----------| <---- TemporaryRamBase
 | 
						|
  // 
 | 
						|
  TopOfStack  = (VOID *)(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 = FixedPcdGet32(PcdWinNtFirmwareFdSize);
 | 
						|
  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 = SecWinNtPeiLoadFile (
 | 
						|
            PeiCorePe32File,
 | 
						|
            &PeiImageAddress,
 | 
						|
            &PeiCoreSize,
 | 
						|
            &PeiCoreEntryPoint
 | 
						|
            );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return ;
 | 
						|
  }
 | 
						|
  
 | 
						|
  //
 | 
						|
  // Transfer control to the PEI Core
 | 
						|
  //
 | 
						|
  PeiSwitchStacks (
 | 
						|
    (SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint,
 | 
						|
    SecCoreData,
 | 
						|
    (VOID *) (UINTN) ((EFI_PEI_PPI_DESCRIPTOR *) &gPrivateDispatchTable),
 | 
						|
    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 PcdWinNtMemorySizeForSecMain value.
 | 
						|
  The size comes from the Pcd value and the address comes from the memory space 
 | 
						|
  with ReadWrite and Execute attributes allocated by VirtualAlloc() API.
 | 
						|
 | 
						|
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
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  if (Index >= gSystemMemoryCount) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
  
 | 
						|
  //
 | 
						|
  // Allocate enough memory space for emulator 
 | 
						|
  //
 | 
						|
  gSystemMemory[Index].Memory = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (gSystemMemory[Index].Size), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 | 
						|
  if (gSystemMemory[Index].Memory == 0) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
  
 | 
						|
  *MemoryBase = gSystemMemory[Index].Memory;
 | 
						|
  *MemorySize = gSystemMemory[Index].Size;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
VOID *
 | 
						|
EFIAPI
 | 
						|
SecWinNtWinNtThunkAddress (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Since the SEC is the only Windows 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 gWinNt;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
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                  = PeCoffLoaderGetImageInfo (&ImageContext);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Allocate space in NT (not emulator) memory with ReadWrite and Execute attribue. 
 | 
						|
  // Extra space is for alignment
 | 
						|
  //
 | 
						|
  ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (ImageContext.ImageSize + (ImageContext.SectionAlignment * 2)), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 | 
						|
  if (ImageContext.ImageAddress == 0) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Align buffer on section boundry
 | 
						|
  //
 | 
						|
  ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
 | 
						|
  ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);
 | 
						|
 | 
						|
  Status = PeCoffLoaderLoadImage (&ImageContext);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = SecNt32PeCoffRelocateImage (&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 Windows 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;
 | 
						|
}
 | 
						|
 | 
						|
CHAR16 *
 | 
						|
AsciiToUnicode (
 | 
						|
  IN  CHAR8   *Ascii,
 | 
						|
  IN  UINTN   *StrLen OPTIONAL
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Convert the passed in Ascii string to Unicode.
 | 
						|
  Optionally return the length of the strings.
 | 
						|
 | 
						|
Arguments:
 | 
						|
  Ascii   - Ascii string to convert
 | 
						|
  StrLen  - Length of string
 | 
						|
 | 
						|
Returns:
 | 
						|
  Pointer to malloc'ed Unicode version of Ascii
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINTN   Index;
 | 
						|
  CHAR16  *Unicode;
 | 
						|
 | 
						|
  //
 | 
						|
  // Allocate a buffer for unicode string
 | 
						|
  //
 | 
						|
  for (Index = 0; Ascii[Index] != '\0'; Index++)
 | 
						|
    ;
 | 
						|
  Unicode = malloc ((Index + 1) * sizeof (CHAR16));
 | 
						|
  if (Unicode == NULL) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  for (Index = 0; Ascii[Index] != '\0'; Index++) {
 | 
						|
    Unicode[Index] = (CHAR16) Ascii[Index];
 | 
						|
  }
 | 
						|
 | 
						|
  Unicode[Index] = '\0';
 | 
						|
 | 
						|
  if (StrLen != NULL) {
 | 
						|
    *StrLen = Index;
 | 
						|
  }
 | 
						|
 | 
						|
  return Unicode;
 | 
						|
}
 | 
						|
 | 
						|
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
 | 
						|
SecNt32PeCoffRelocateImage (
 | 
						|
  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS        Status;
 | 
						|
  VOID              *DllEntryPoint;
 | 
						|
  CHAR16            *DllFileName;
 | 
						|
  HMODULE           Library;
 | 
						|
  UINTN             Index;
 | 
						|
 | 
						|
 | 
						|
  Status = PeCoffLoaderRelocateImage (ImageContext);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    //
 | 
						|
    // We could not relocated the image in memory properly
 | 
						|
    //
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // If we load our own PE COFF images the Windows debugger can not source
 | 
						|
  //  level debug our code. If a valid PDB pointer exists usw it to load
 | 
						|
  //  the *.dll file as a library using Windows* APIs. This allows 
 | 
						|
  //  source level debug. The image is still loaded and reloaced
 | 
						|
  //  in the Framework memory space like on a real system (by the code above),
 | 
						|
  //  but the entry point points into the DLL loaded by the code bellow. 
 | 
						|
  //
 | 
						|
 | 
						|
  DllEntryPoint = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // Load the DLL if it's not an EBC image.
 | 
						|
  //
 | 
						|
  if ((ImageContext->PdbPointer != NULL) &&
 | 
						|
      (ImageContext->Machine != EFI_IMAGE_MACHINE_EBC)) {
 | 
						|
    //
 | 
						|
    // Convert filename from ASCII to Unicode
 | 
						|
    //
 | 
						|
    DllFileName = AsciiToUnicode (ImageContext->PdbPointer, &Index);
 | 
						|
 | 
						|
    //
 | 
						|
    // Check that we have a valid filename
 | 
						|
    //
 | 
						|
    if (Index < 5 || DllFileName[Index - 4] != '.') {
 | 
						|
      free (DllFileName);
 | 
						|
 | 
						|
      //
 | 
						|
      // Never return an error if PeCoffLoaderRelocateImage() succeeded.
 | 
						|
      // The image will run, but we just can't source level debug. If we
 | 
						|
      // return an error the image will not run.
 | 
						|
      //
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // Replace .PDB with .DLL on the filename
 | 
						|
    //
 | 
						|
    DllFileName[Index - 3]  = 'D';
 | 
						|
    DllFileName[Index - 2]  = 'L';
 | 
						|
    DllFileName[Index - 1]  = 'L';
 | 
						|
 | 
						|
    //
 | 
						|
    // Load the .DLL file into the user process's address space for source 
 | 
						|
    // level debug
 | 
						|
    //
 | 
						|
    Library = LoadLibraryEx (DllFileName, NULL, DONT_RESOLVE_DLL_REFERENCES);
 | 
						|
    if (Library != NULL) {
 | 
						|
      //
 | 
						|
      // InitializeDriver is the entry point we put in all our EFI DLL's. The
 | 
						|
      // DONT_RESOLVE_DLL_REFERENCES argument to LoadLIbraryEx() supresses the 
 | 
						|
      // normal DLL entry point of DllMain, and prevents other modules that are
 | 
						|
      // referenced in side the DllFileName from being loaded. There is no error 
 | 
						|
      // checking as the we can point to the PE32 image loaded by Tiano. This 
 | 
						|
      // step is only needed for source level debuging
 | 
						|
      //
 | 
						|
      DllEntryPoint = (VOID *) (UINTN) GetProcAddress (Library, "InitializeDriver");
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    if ((Library != NULL) && (DllEntryPoint != NULL)) {
 | 
						|
      ImageContext->EntryPoint  = (EFI_PHYSICAL_ADDRESS) (UINTN) DllEntryPoint;
 | 
						|
      SecPrint ("LoadLibraryEx (%S,\n               NULL, DONT_RESOLVE_DLL_REFERENCES)\n", DllFileName);
 | 
						|
    } else {
 | 
						|
      SecPrint ("WARNING: No source level debug %S. \n", DllFileName);
 | 
						|
    }
 | 
						|
 | 
						|
    free (DllFileName);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Never return an error if PeCoffLoaderRelocateImage() succeeded.
 | 
						|
  // The image will run, but we just can't source level debug. If we
 | 
						|
  // return an error the image will not run.
 | 
						|
  //
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 |