]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Nt32Pkg/Sec/SecMain.c
Update SecMain code to remove unused logic.
[mirror_edk2.git] / Nt32Pkg / Sec / SecMain.c
index be30d2611d789546ce1abc310da1b96f46ef8266..e503ecf2c3d4c2f1c7a012ffab6d94cebded35af 100644 (file)
@@ -1,4 +1,4 @@
-/*++\r
+/**@file\r
 \r
 Copyright (c) 2006, Intel Corporation\r
 All rights reserved. This program and the accompanying materials\r
@@ -17,20 +17,16 @@ Abstract:
   WinNt emulator of SEC phase. It's really a Win32 application, but this is\r
   Ok since all the other modules for NT32 are NOT Win32 applications.\r
 \r
-  This program processes Windows environment variables and figures out\r
-  what the memory layout will be, how may FD's will be loaded and also\r
-  what the boot mode is.\r
+  This program gets NT32 PCD setting and figures out what the memory layout \r
+  will be, how may FD's will be loaded and also what the boot mode is.\r
 \r
   The SEC registers a set of services with the SEC core. gPrivateDispatchTable\r
   is a list of PPI's produced by the SEC that are availble for usage in PEI.\r
 \r
-  This code produces 128 K of temporary memory for the PEI stack by opening a\r
-  Windows file and mapping it directly to memory addresses.\r
-\r
-  The system.cmd script is used to set windows environment variables that drive\r
-  the configuration opitons of the SEC.\r
+  This code produces 128 K of temporary memory for the PEI stack by directly\r
+  allocate memory space with ReadWrite and Execute attribute.\r
 \r
---*/\r
+**/\r
 \r
 #include "SecMain.h"\r
 \r
@@ -62,6 +58,7 @@ EFI_PEI_PROGRESS_CODE_PPI                 mSecStatusCodePpi     = { SecPeiReport
 \r
 NT_FWH_PPI                                mSecFwhInformationPpi = { SecWinNtFdAddress };\r
 \r
+TEMPORARY_RAM_SUPPORT_PPI                 mSecTemporaryRamSupportPpi = {SecTemporaryRamSupport};\r
 \r
 EFI_PEI_PPI_DESCRIPTOR  gPrivateDispatchTable[] = {\r
   {\r
@@ -89,6 +86,11 @@ EFI_PEI_PPI_DESCRIPTOR  gPrivateDispatchTable[] = {
     &gEfiPeiStatusCodePpiGuid,\r
     &mSecStatusCodePpi\r
   },\r
+  {\r
+    EFI_PEI_PPI_DESCRIPTOR_PPI,\r
+    &gEfiTemporaryRamSupportPpiGuid,\r
+    &mSecTemporaryRamSupportPpi\r
+  },\r
   {\r
     EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
     &gNtFwhPpiGuid,\r
@@ -99,19 +101,18 @@ EFI_PEI_PPI_DESCRIPTOR  gPrivateDispatchTable[] = {
 \r
 //\r
 // Default information about where the FD is located.\r
-//  This array gets filled in with information from EFI_FIRMWARE_VOLUMES\r
-//  EFI_FIRMWARE_VOLUMES is a Windows environment variable set by system.cmd.\r
+//  This array gets filled in with information from PcdWinNtFirmwareVolume\r
 //  The number of array elements is allocated base on parsing\r
-//  EFI_FIRMWARE_VOLUMES and the memory is never freed.\r
+//  PcdWinNtFirmwareVolume and the memory is never freed.\r
 //\r
 UINTN                                     gFdInfoCount = 0;\r
 NT_FD_INFO                                *gFdInfo;\r
 \r
 //\r
 // Array that supports seperate memory rantes.\r
-//  The memory ranges are set in system.cmd via the EFI_MEMORY_SIZE variable.\r
+//  The memory ranges are set by PcdWinNtMemorySizeForSecMain.\r
 //  The number of array elements is allocated base on parsing\r
-//  EFI_MEMORY_SIZE and the memory is never freed.\r
+//  PcdWinNtMemorySizeForSecMain value and the memory is never freed.\r
 //\r
 UINTN                                     gSystemMemoryCount = 0;\r
 NT_SYSTEM_MEMORY                          *gSystemMemory;\r
@@ -121,7 +122,12 @@ UINTN                   mPdbNameModHandleArraySize = 0;
 PDB_NAME_TO_MOD_HANDLE  *mPdbNameModHandleArray = NULL;\r
 \r
 \r
-\r
+VOID\r
+EFIAPI\r
+SecSwitchStack (\r
+  UINT32   TemporaryMemoryBase,\r
+  UINT32   PermenentMemoryBase\r
+  );\r
 \r
 INTN\r
 EFIAPI\r
@@ -152,16 +158,16 @@ Returns:
   UINTN                 Index;\r
   UINTN                 Index1;\r
   UINTN                 Index2;\r
-  UINTN                 PeiIndex;\r
   CHAR16                *FileName;\r
   CHAR16                *FileNamePtr;\r
   BOOLEAN               Done;\r
   VOID                  *PeiCoreFile;\r
   CHAR16                *MemorySizeStr;\r
   CHAR16                *FirmwareVolumesStr;\r
+  UINTN                 *StackPointer;\r
 \r
-  MemorySizeStr      = (CHAR16 *)L"64!64";\r
-  FirmwareVolumesStr = (CHAR16 *)L"..\\Fv\\Fv_Recovery.fd";\r
+  MemorySizeStr      = (CHAR16 *) FixedPcdGetPtr (PcdWinNtMemorySizeForSecMain);\r
+  FirmwareVolumesStr = (CHAR16 *) FixedPcdGetPtr (PcdWinNtFirmwareVolume);\r
 \r
   printf ("\nEDK SEC Main NT Emulation Environment from www.TianoCore.org\n");\r
 \r
@@ -178,7 +184,7 @@ Returns:
   gSystemMemoryCount  = CountSeperatorsInString (MemorySizeStr, '!') + 1;\r
   gSystemMemory       = calloc (gSystemMemoryCount, sizeof (NT_SYSTEM_MEMORY));\r
   if (gSystemMemory == NULL) {\r
-    printf ("ERROR : Can not allocate memory for %s.  Exiting.\n", MemorySizeStr);\r
+    wprintf (L"ERROR : Can not allocate memory for %s.  Exiting.\n", MemorySizeStr);\r
     exit (1);\r
   }\r
   //\r
@@ -187,7 +193,7 @@ Returns:
   gFdInfoCount  = CountSeperatorsInString (FirmwareVolumesStr, '!') + 1;\r
   gFdInfo       = calloc (gFdInfoCount, sizeof (NT_FD_INFO));\r
   if (gFdInfo == NULL) {\r
-    printf ("ERROR : Can not allocate memory for %s.  Exiting.\n", FirmwareVolumesStr);\r
+    wprintf (L"ERROR : Can not allocate memory for %s.  Exiting.\n", FirmwareVolumesStr);\r
     exit (1);\r
   }\r
   //\r
@@ -196,25 +202,24 @@ Returns:
   printf ("  BootMode 0x%02x\n", FixedPcdGet32 (PcdWinNtBootMode));\r
 \r
   //\r
-  // Open up a 128K file to emulate temp memory for PEI.\r
+  //  Allocate 128K memory to emulate temp memory for PEI.\r
   //  on a real platform this would be SRAM, or using the cache as RAM.\r
   //  Set InitialStackMemory to zero so WinNtOpenFile will allocate a new mapping\r
   //\r
-  InitialStackMemory      = 0;\r
-  InitialStackMemorySize  = 0x20000;\r
-  Status = WinNtOpenFile (\r
-            L"SecStack",\r
-            (UINT32) InitialStackMemorySize,\r
-            OPEN_ALWAYS,\r
-            &InitialStackMemory,\r
-            &InitialStackMemorySize\r
-            );\r
-  if (EFI_ERROR (Status)) {\r
-    printf ("ERROR : Can not open SecStack Exiting\n");\r
+  InitialStackMemorySize  = STACK_SIZE;\r
+  InitialStackMemory = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (InitialStackMemorySize), MEM_COMMIT, PAGE_EXECUTE_READWRITE);\r
+  if (InitialStackMemory == 0) {\r
+    printf ("ERROR : Can not allocate enough space for SecStack\n");\r
     exit (1);\r
   }\r
 \r
-  printf ("  SEC passing in %d bytes of temp RAM to PEI\n", InitialStackMemorySize);\r
+  for (StackPointer = (UINTN*) (UINTN) InitialStackMemory;\r
+       StackPointer < (UINTN*) ((UINTN)InitialStackMemory + (SIZE_T) InitialStackMemorySize);\r
+       StackPointer ++) {\r
+    *StackPointer = 0x5AA55AA5;\r
+  }\r
+  \r
+  wprintf (L"  SEC passing in %d bytes of temp RAM to PEI\n", InitialStackMemorySize);\r
 \r
   //\r
   // Open All the firmware volumes and remember the info in the gFdInfo global\r
@@ -227,7 +232,7 @@ Returns:
 \r
   StrCpy (FileNamePtr, (CHAR16*)FirmwareVolumesStr);\r
 \r
-  for (Done = FALSE, Index = 0, PeiIndex = 0, PeiCoreFile = NULL; !Done; Index++) {\r
+  for (Done = FALSE, Index = 0, PeiCoreFile = NULL; !Done; Index++) {\r
     FileName = FileNamePtr;\r
     for (Index1 = 0; (FileNamePtr[Index1] != '!') && (FileNamePtr[Index1] != 0); Index1++)\r
       ;\r
@@ -249,7 +254,7 @@ Returns:
               &gFdInfo[Index].Size\r
               );\r
     if (EFI_ERROR (Status)) {\r
-      printf ("ERROR : Can not open Firmware Device File %S (%r).  Exiting.\n", FileName, Status);\r
+      printf ("ERROR : Can not open Firmware Device File %S (0x%X).  Exiting.\n", FileName, Status);\r
       exit (1);\r
     }\r
 \r
@@ -269,7 +274,6 @@ Returns:
       //\r
       Status = SecFfsFindPeiCore ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) gFdInfo[Index].Address, &PeiCoreFile);\r
       if (!EFI_ERROR (Status)) {\r
-        PeiIndex = Index;\r
         printf (" contains SEC Core");\r
       }\r
     }\r
@@ -286,7 +290,6 @@ Returns:
     // Save the size of the memory and make a Unicode filename SystemMemory00, ...\r
     //\r
     gSystemMemory[Index].Size = _wtoi (MemorySizeStr) * 0x100000;\r
-    _snwprintf (gSystemMemory[Index].FileName, NT_SYSTEM_MEMORY_FILENAME_SIZE, L"SystemMemory%02d", Index);\r
 \r
     //\r
     // Find the next region\r
@@ -426,12 +429,12 @@ Returns:
 EFI_STATUS\r
 EFIAPI\r
 SecPeiReportStatusCode (\r
-  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN CONST EFI_PEI_SERVICES           **PeiServices,\r
   IN EFI_STATUS_CODE_TYPE       CodeType,\r
   IN EFI_STATUS_CODE_VALUE      Value,\r
   IN UINT32                     Instance,\r
-  IN EFI_GUID                   *CallerId,\r
-  IN EFI_STATUS_CODE_DATA       *Data OPTIONAL\r
+  IN CONST EFI_GUID                   *CallerId,\r
+  IN CONST EFI_STATUS_CODE_DATA       *Data OPTIONAL\r
   )\r
 /*++\r
 \r
@@ -471,7 +474,7 @@ Returns:
     //\r
     // Processes ASSERT ()\r
     //\r
-    printf ("ASSERT %s(%d): %s\n", Filename, LineNumber, Description);\r
+    printf ("ASSERT %s(%d): %s\n", Filename, (int)LineNumber, Description);\r
 \r
   } else if (ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {\r
     //\r
@@ -484,6 +487,63 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Transfers control to a function starting with a new stack.\r
+\r
+  Transfers control to the function specified by EntryPoint using the new stack\r
+  specified by NewStack and passing in the parameters specified by Context1 and\r
+  Context2. Context1 and Context2 are optional and may be NULL. The function\r
+  EntryPoint must never return.\r
+\r
+  If EntryPoint is NULL, then ASSERT().\r
+  If NewStack is NULL, then ASSERT().\r
+\r
+  @param  EntryPoint  A pointer to function to call with the new stack.\r
+  @param  Context1    A pointer to the context to pass into the EntryPoint\r
+                      function.\r
+  @param  Context2    A pointer to the context to pass into the EntryPoint\r
+                      function.\r
+  @param  NewStack    A pointer to the new stack to use for the EntryPoint\r
+                      function.\r
+  @param  NewBsp      A pointer to the new BSP for the EntryPoint on IPF. It's\r
+                      Reserved on other architectures.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PeiSwitchStacks (\r
+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,\r
+  IN      VOID                      *Context1,  OPTIONAL\r
+  IN      VOID                      *Context2,  OPTIONAL\r
+  IN      VOID                      *Context3,  OPTIONAL\r
+  IN      VOID                      *NewStack\r
+  )\r
+{\r
+  BASE_LIBRARY_JUMP_BUFFER  JumpBuffer;\r
+  \r
+  ASSERT (EntryPoint != NULL);\r
+  ASSERT (NewStack != NULL);\r
+\r
+  //\r
+  // Stack should be aligned with CPU_STACK_ALIGNMENT\r
+  //\r
+  ASSERT (((UINTN)NewStack & (CPU_STACK_ALIGNMENT - 1)) == 0);\r
+\r
+  JumpBuffer.Eip = (UINTN)EntryPoint;\r
+  JumpBuffer.Esp = (UINTN)NewStack - sizeof (VOID*);\r
+  JumpBuffer.Esp -= sizeof (Context1) + sizeof (Context2) + sizeof(Context3);\r
+  ((VOID**)JumpBuffer.Esp)[1] = Context1;\r
+  ((VOID**)JumpBuffer.Esp)[2] = Context2;\r
+  ((VOID**)JumpBuffer.Esp)[3] = Context3;\r
+\r
+  LongJump (&JumpBuffer, (UINTN)-1);\r
+  \r
+\r
+  //\r
+  // InternalSwitchStack () will never return\r
+  //\r
+  ASSERT (FALSE);  \r
+}\r
 \r
 VOID\r
 SecLoadFromCore (\r
@@ -509,24 +569,34 @@ Returns:
 --*/\r
 {\r
   EFI_STATUS                  Status;\r
-  EFI_PHYSICAL_ADDRESS        TopOfMemory;\r
   VOID                        *TopOfStack;\r
   UINT64                      PeiCoreSize;\r
   EFI_PHYSICAL_ADDRESS        PeiCoreEntryPoint;\r
   EFI_PHYSICAL_ADDRESS        PeiImageAddress;\r
-  EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartup;\r
+  EFI_SEC_PEI_HAND_OFF        *SecCoreData;\r
+  UINTN                       PeiStackSize;\r
 \r
   //\r
   // Compute Top Of Memory for Stack and PEI Core Allocations\r
   //\r
-  TopOfMemory = LargestRegion + LargestRegionSize;\r
+  PeiStackSize = (UINTN)RShiftU64((UINT64)STACK_SIZE,1);\r
 \r
   //\r
-  // Allocate 128KB for the Stack\r
+  // |-----------| <---- TemporaryRamBase + TemporaryRamSize\r
+  // |   Heap    |\r
+  // |           |\r
+  // |-----------| <---- StackBase / PeiTemporaryMemoryBase\r
+  // |           |\r
+  // |  Stack    |\r
+  // |-----------| <---- TemporaryRamBase\r
+  // \r
+  TopOfStack  = (VOID *)(LargestRegion + PeiStackSize);\r
+\r
   //\r
-  TopOfStack  = (VOID *)((UINTN)TopOfMemory - sizeof (EFI_PEI_STARTUP_DESCRIPTOR) - CPU_STACK_ALIGNMENT);\r
+  // Reservet space for storing PeiCore's parament in stack.\r
+  // \r
+  TopOfStack  = (VOID *)((UINTN)TopOfStack - sizeof (EFI_SEC_PEI_HAND_OFF) - CPU_STACK_ALIGNMENT);\r
   TopOfStack  = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);\r
-  TopOfMemory = TopOfMemory - STACK_SIZE;\r
 \r
   //\r
   // Patch value in dispatch table values\r
@@ -536,10 +606,16 @@ Returns:
   //\r
   // Bind this information into the SEC hand-off state\r
   //\r
-  PeiStartup = (EFI_PEI_STARTUP_DESCRIPTOR *) (UINTN) TopOfStack;\r
-  PeiStartup->DispatchTable      = (EFI_PEI_PPI_DESCRIPTOR *) &gPrivateDispatchTable;\r
-  PeiStartup->SizeOfCacheAsRam   = STACK_SIZE;\r
-  PeiStartup->BootFirmwareVolume = BootFirmwareVolumeBase;\r
+  SecCoreData                        = (EFI_SEC_PEI_HAND_OFF*)(UINTN) TopOfStack;\r
+  SecCoreData->DataSize               = sizeof(EFI_SEC_PEI_HAND_OFF);\r
+  SecCoreData->BootFirmwareVolumeBase = (VOID*)BootFirmwareVolumeBase;\r
+  SecCoreData->BootFirmwareVolumeSize = FixedPcdGet32(PcdWinNtFirmwareFdSize);\r
+  SecCoreData->TemporaryRamBase       = (VOID*)(UINTN)LargestRegion; \r
+  SecCoreData->TemporaryRamSize       = STACK_SIZE;\r
+  SecCoreData->StackBase              = SecCoreData->TemporaryRamBase;\r
+  SecCoreData->StackSize              = PeiStackSize;\r
+  SecCoreData->PeiTemporaryRamBase    = (VOID*) ((UINTN) SecCoreData->TemporaryRamBase + PeiStackSize);\r
+  SecCoreData->PeiTemporaryRamSize    = STACK_SIZE - PeiStackSize;\r
 \r
   //\r
   // Load the PEI Core from a Firmware Volume\r
@@ -553,12 +629,14 @@ Returns:
   if (EFI_ERROR (Status)) {\r
     return ;\r
   }\r
+  \r
   //\r
   // Transfer control to the PEI Core\r
   //\r
-  SwitchStack (\r
+  PeiSwitchStacks (\r
     (SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint,\r
-    PeiStartup,\r
+    SecCoreData,\r
+    (VOID *) (UINTN) ((EFI_PEI_PPI_DESCRIPTOR *) &gPrivateDispatchTable),\r
     NULL,\r
     TopOfStack\r
     );\r
@@ -581,9 +659,9 @@ Routine Description:
   This service is called from Index == 0 until it returns EFI_UNSUPPORTED.\r
   It allows discontiguous memory regions to be supported by the emulator.\r
   It uses gSystemMemory[] and gSystemMemoryCount that were created by\r
-  parsing the Windows environment variable EFI_MEMORY_SIZE.\r
-  The size comes from the varaible and the address comes from the call to\r
-  WinNtOpenFile.\r
+  parsing PcdWinNtMemorySizeForSecMain value.\r
+  The size comes from the Pcd value and the address comes from the memory space \r
+  with ReadWrite and Execute attributes allocated by VirtualAlloc() API.\r
 \r
 Arguments:\r
   Index      - Which memory region to use\r
@@ -596,24 +674,22 @@ Returns:
 \r
 --*/\r
 {\r
-  EFI_STATUS  Status;\r
-\r
   if (Index >= gSystemMemoryCount) {\r
     return EFI_UNSUPPORTED;\r
   }\r
+  \r
+  //\r
+  // Allocate enough memory space for emulator \r
+  //\r
+  gSystemMemory[Index].Memory = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (gSystemMemory[Index].Size), MEM_COMMIT, PAGE_EXECUTE_READWRITE);\r
+  if (gSystemMemory[Index].Memory == 0) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  \r
+  *MemoryBase = gSystemMemory[Index].Memory;\r
+  *MemorySize = gSystemMemory[Index].Size;\r
 \r
-  *MemoryBase = 0;\r
-  Status = WinNtOpenFile (\r
-            gSystemMemory[Index].FileName,\r
-            (UINT32) gSystemMemory[Index].Size,\r
-            OPEN_ALWAYS,\r
-            MemoryBase,\r
-            MemorySize\r
-            );\r
-\r
-  gSystemMemory[Index].Memory = *MemoryBase;\r
-\r
-  return Status;\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 VOID *\r
@@ -679,9 +755,10 @@ Returns:
     return Status;\r
   }\r
   //\r
-  // Allocate space in NT (not emulator) memory. Extra space is for alignment\r
+  // Allocate space in NT (not emulator) memory with ReadWrite and Execute attribue. \r
+  // Extra space is for alignment\r
   //\r
-  ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) malloc ((UINTN) (ImageContext.ImageSize + (ImageContext.SectionAlignment * 2)));\r
+  ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (ImageContext.ImageSize + (ImageContext.SectionAlignment * 2)), MEM_COMMIT, PAGE_EXECUTE_READWRITE);\r
   if (ImageContext.ImageAddress == 0) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -836,7 +913,7 @@ Returns:
 \r
 UINTN\r
 CountSeperatorsInString (\r
-  IN  const CHAR16   *String,\r
+  IN  CONST CHAR16   *String,\r
   IN  CHAR16         Seperator\r
   )\r
 /*++\r
@@ -981,37 +1058,7 @@ SecNt32PeCoffGetImageInfo (
   IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-\r
-  Status = PeCoffLoaderGetImageInfo (ImageContext);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  switch (ImageContext->ImageType) {\r
-\r
-  case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:\r
-    ImageContext->ImageCodeMemoryType = EfiLoaderCode;\r
-    ImageContext->ImageDataMemoryType = EfiLoaderData;\r
-    break;\r
-\r
-  case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:\r
-    ImageContext->ImageCodeMemoryType = EfiBootServicesCode;\r
-    ImageContext->ImageDataMemoryType = EfiBootServicesData;\r
-    break;\r
-\r
-  case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:\r
-  case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:\r
-    ImageContext->ImageCodeMemoryType = EfiRuntimeServicesCode;\r
-    ImageContext->ImageDataMemoryType = EfiRuntimeServicesData;\r
-    break;\r
-\r
-  default:\r
-    ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;\r
-    return RETURN_UNSUPPORTED;\r
-  }\r
-\r
-  return Status;\r
+  return PeCoffLoaderGetImageInfo (ImageContext);\r
 }\r
 \r
 EFI_STATUS\r
@@ -1021,10 +1068,7 @@ SecNt32PeCoffLoadImage (
   IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-\r
-  Status = PeCoffLoaderLoadImage (ImageContext);\r
-  return Status;\r
+  return PeCoffLoaderLoadImage (ImageContext);\r
 }\r
 \r
 EFI_STATUS\r
@@ -1151,3 +1195,44 @@ _ModuleEntryPoint (
 {\r
 }\r
 \r
+EFI_STATUS\r
+EFIAPI\r
+SecTemporaryRamSupport (\r
+  IN CONST EFI_PEI_SERVICES   **PeiServices,\r
+  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,\r
+  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,\r
+  IN UINTN                    CopySize\r
+  )\r
+{\r
+  //\r
+  // Migrate the whole temporary memory to permenent memory.\r
+  // \r
+  CopyMem (\r
+    (VOID*)(UINTN)PermanentMemoryBase, \r
+    (VOID*)(UINTN)TemporaryMemoryBase, \r
+    CopySize\r
+    );\r
+\r
+  //\r
+  // SecSwitchStack function must be invoked after the memory migration\r
+  // immediatly, also we need fixup the stack change caused by new call into \r
+  // permenent memory.\r
+  // \r
+  SecSwitchStack (\r
+    (UINT32) TemporaryMemoryBase,\r
+    (UINT32) PermanentMemoryBase\r
+    );\r
+\r
+  //\r
+  // We need *not* fix the return address because currently, \r
+  // The PeiCore is excuted in flash.\r
+  //\r
+\r
+  //\r
+  // Simulate to invalid CAR, terminate CAR\r
+  // \r
+  //ZeroMem ((VOID*)(UINTN)TemporaryMemoryBase, CopySize);\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r