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
//\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
VOID *PeiCoreFile;\r
CHAR16 *MemorySizeStr;\r
CHAR16 *FirmwareVolumesStr;\r
-\r
- MemorySizeStr = (CHAR16 *)L"64!64";\r
- FirmwareVolumesStr = (CHAR16 *)L"..\\Fv\\Fv_Recovery.fd";\r
+ \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
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
// 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
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
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
\r
//\r
// Compute Top Of Memory for Stack and PEI Core Allocations\r
//\r
// Allocate 128KB for the Stack\r
//\r
- TopOfStack = (VOID *)((UINTN)TopOfMemory - sizeof (EFI_PEI_STARTUP_DESCRIPTOR) - CPU_STACK_ALIGNMENT);\r
+ TopOfStack = (VOID *)((UINTN)TopOfMemory - 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
// 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)TopOfMemory; \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
\r
//\r
// Load the PEI Core from a Firmware Volume\r
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
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