-/*++\r
+/**@file\r
\r
Copyright (c) 2006, Intel Corporation\r
All rights reserved. This program and the accompanying materials\r
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
\r
NT_FWH_PPI mSecFwhInformationPpi = { SecWinNtFdAddress };\r
\r
+TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPpi = {SecTemporaryRamSupport};\r
\r
EFI_PEI_PPI_DESCRIPTOR gPrivateDispatchTable[] = {\r
{\r
&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
\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
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
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
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
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
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
\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
&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
//\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
// 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
//\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
--*/\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_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_SEC_PEI_HAND_OFF) - 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
SecCoreData->DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);\r
SecCoreData->BootFirmwareVolumeBase = (VOID*)BootFirmwareVolumeBase;\r
SecCoreData->BootFirmwareVolumeSize = FixedPcdGet32(PcdWinNtFirmwareFdSize);\r
- SecCoreData->TemporaryRamBase = (VOID*)(UINTN)TopOfMemory; \r
+ SecCoreData->TemporaryRamBase = (VOID*)(UINTN)LargestRegion; \r
SecCoreData->TemporaryRamSize = STACK_SIZE;\r
- SecCoreData->PeiTemporaryRamBase = SecCoreData->TemporaryRamBase;\r
- SecCoreData->PeiTemporaryRamSize = (UINTN)RShiftU64((UINT64)STACK_SIZE,1);\r
- SecCoreData->StackBase = (VOID*)((UINTN)SecCoreData->TemporaryRamBase + (UINTN)SecCoreData->TemporaryRamSize);\r
- SecCoreData->StackSize = (UINTN)RShiftU64((UINT64)STACK_SIZE,1);\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
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
\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
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
\r
UINTN\r
CountSeperatorsInString (\r
- IN const CHAR16 *String,\r
+ IN CONST CHAR16 *String,\r
IN CHAR16 Seperator\r
)\r
/*++\r
{\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