+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006 - 2007 Intel Corporation.\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- SecMain.c\r
-\r
-Abstract:\r
- WinNt emulator of SEC phase. It's really a Posix application, but this is\r
- Ok since all the other modules for NT32 are NOT Posix applications.\r
-\r
- This program processes host 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
-\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
- host file and mapping it directly to memory addresses.\r
-\r
- The system.cmd script is used to set host environment variables that drive\r
- the configuration opitons of the SEC.\r
-\r
---*/\r
-\r
-#include "SecMain.h"\r
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <sys/fcntl.h>
-#include <unistd.h>
-\r
-//\r
-// Globals\r
-//\r
-EFI_PEI_PE_COFF_LOADER_PROTOCOL_INSTANCE mPeiEfiPeiPeCoffLoaderInstance = {\r
- {\r
- SecNt32PeCoffGetImageInfo,\r
- SecNt32PeCoffLoadImage,\r
- SecNt32PeCoffRelocateImage,\r
- SecNt32PeCoffUnloadimage\r
- },\r
- NULL\r
-};\r
-\r
-\r
-\r
-EFI_PEI_PE_COFF_LOADER_PROTOCOL *gPeiEfiPeiPeCoffLoader = &mPeiEfiPeiPeCoffLoaderInstance.PeCoff;\r
-\r
-UNIX_PEI_LOAD_FILE_PPI mSecNtLoadFilePpi = { SecWinNtPeiLoadFile };\r
-\r
-PEI_UNIX_AUTOSCAN_PPI mSecNtAutoScanPpi = { SecWinNtPeiAutoScan };\r
-\r
-PEI_UNIX_THUNK_PPI mSecWinNtThunkPpi = { SecWinNtWinNtThunkAddress };\r
-\r
-EFI_PEI_PROGRESS_CODE_PPI mSecStatusCodePpi = { SecPeiReportStatusCode };\r
-\r
-UNIX_FWH_PPI mSecFwhInformationPpi = { SecWinNtFdAddress };\r
-\r
-\r
-EFI_PEI_PPI_DESCRIPTOR gPrivateDispatchTable[] = {\r
- {\r
- EFI_PEI_PPI_DESCRIPTOR_PPI,\r
- &gEfiPeiPeCoffLoaderGuid,\r
- NULL\r
- },\r
- {\r
- EFI_PEI_PPI_DESCRIPTOR_PPI,\r
- &gUnixPeiLoadFilePpiGuid,\r
- &mSecNtLoadFilePpi\r
- },\r
- {\r
- EFI_PEI_PPI_DESCRIPTOR_PPI,\r
- &gPeiUnixAutoScanPpiGuid,\r
- &mSecNtAutoScanPpi\r
- },\r
- {\r
- EFI_PEI_PPI_DESCRIPTOR_PPI,\r
- &gPeiUnixThunkPpiGuid,\r
- &mSecWinNtThunkPpi\r
- },\r
- {\r
- EFI_PEI_PPI_DESCRIPTOR_PPI,\r
- &gEfiPeiStatusCodePpiGuid,\r
- &mSecStatusCodePpi\r
- },\r
- {\r
- EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
- &gUnixFwhPpiGuid,\r
- &mSecFwhInformationPpi\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 host environment variable set by system.cmd.\r
-// The number of array elements is allocated base on parsing\r
-// EFI_FIRMWARE_VOLUMES and the memory is never freed.\r
-//\r
-UINTN gFdInfoCount = 0;\r
-UNIX_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 number of array elements is allocated base on parsing\r
-// EFI_MEMORY_SIZE and the memory is never freed.\r
-//\r
-UINTN gSystemMemoryCount = 0;\r
-UNIX_SYSTEM_MEMORY *gSystemMemory;\r
-\r
-\r
-STATIC
-EFI_PHYSICAL_ADDRESS *
-MapMemory (
- INTN fd,
- UINT64 length,
- INTN prot,
- INTN flags);
-\r
-STATIC
-EFI_STATUS
-MapFile (
- IN CHAR8 *FileName,\r
- IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,\r
- OUT UINT64 *Length\r
- );
-\r
-\r
-INTN\r
-EFIAPI\r
-main (\r
- IN INTN Argc,\r
- IN CHAR8 **Argv,\r
- IN CHAR8 **Envp\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Main entry point to SEC for WinNt. This is a unix program\r
-\r
-Arguments:\r
- Argc - Number of command line arguments\r
- Argv - Array of command line argument strings\r
- Envp - Array of environmemt variable strings\r
-\r
-Returns:\r
- 0 - Normal exit\r
- 1 - Abnormal exit\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS InitialStackMemory;\r
- UINT64 InitialStackMemorySize;\r
- UINTN Index;\r
- UINTN Index1;\r
- UINTN Index2;\r
- UINTN PeiIndex;\r
- CHAR8 *FileName;\r
- BOOLEAN Done;\r
- VOID *PeiCoreFile;\r
- CHAR16 *MemorySizeStr;\r
- CHAR16 *FirmwareVolumesStr;\r
-\r
- setbuf(stdout, 0);\r
- setbuf(stderr, 0);\r
-\r
- MemorySizeStr = (CHAR16 *)PcdGetPtr (PcdUnixMemorySizeForSecMain);\r
- FirmwareVolumesStr = (CHAR16 *)PcdGetPtr (PcdUnixFirmwareVolume);\r
-\r
- printf ("\nEDK SEC Main UNIX Emulation Environment from www.TianoCore.org\n");\r
-\r
- //\r
- // Allocate space for gSystemMemory Array\r
- //\r
- gSystemMemoryCount = CountSeperatorsInString (MemorySizeStr, '!') + 1;\r
- gSystemMemory = calloc (gSystemMemoryCount, sizeof (UNIX_SYSTEM_MEMORY));\r
- if (gSystemMemory == NULL) {\r
- printf ("ERROR : Can not allocate memory for system. Exiting.\n");
- exit (1);\r
- }\r
- //\r
- // Allocate space for gSystemMemory Array\r
- //\r
- gFdInfoCount = CountSeperatorsInString (FirmwareVolumesStr, '!') + 1;\r
- gFdInfo = calloc (gFdInfoCount, sizeof (UNIX_FD_INFO));\r
- if (gFdInfo == NULL) {\r
- printf ("ERROR : Can not allocate memory for fd info. Exiting.\n");
- exit (1);\r
- }\r
- //\r
- // Setup Boot Mode. If BootModeStr == "" then BootMode = 0 (BOOT_WITH_FULL_CONFIGURATION)\r
- //\r
- printf (" BootMode 0x%02x\n", FixedPcdGet32 (PcdUnixBootMode));\r
-\r
- //\r
- // Open up a 128K file 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
- InitialStackMemorySize = 0x20000;\r
- InitialStackMemory = (UINTN)MapMemory(0,
- (UINT32) InitialStackMemorySize,\r
- PROT_READ | PROT_WRITE,
- MAP_ANONYMOUS | MAP_PRIVATE);
- if (InitialStackMemory == 0) {\r
- printf ("ERROR : Can not open SecStack Exiting\n");\r
- exit (1);\r
- }\r
-\r
- printf (" SEC passing in %u KB of temp RAM at 0x%08lx to PEI\n",
- (UINTN)(InitialStackMemorySize / 1024),
- (unsigned long)InitialStackMemory);\r
-\r
- //\r
- // Open All the firmware volumes and remember the info in the gFdInfo global\r
- //\r
- FileName = (CHAR8 *)malloc (StrLen (FirmwareVolumesStr) + 1);
- if (FileName == NULL) {\r
- printf ("ERROR : Can not allocate memory for firmware volume string\n");\r
- exit (1);\r
- }\r
-\r
- Index2 = 0;
- for (Done = FALSE, Index = 0, PeiIndex = 0, PeiCoreFile = NULL;
- FirmwareVolumesStr[Index2] != 0;
- Index++) {\r
- for (Index1 = 0; (FirmwareVolumesStr[Index2] != '!') && (FirmwareVolumesStr[Index2] != 0); Index2++)\r
- FileName[Index1++] = FirmwareVolumesStr[Index2];
- if (FirmwareVolumesStr[Index2] == '!')
- Index2++;
- FileName[Index1] = '\0';\r
-\r
- //\r
- // Open the FD and remmeber where it got mapped into our processes address space\r
- //\r
- Status = MapFile (\r
- FileName,\r
- &gFdInfo[Index].Address,\r
- &gFdInfo[Index].Size\r
- );\r
- if (EFI_ERROR (Status)) {\r
- printf ("ERROR : Can not open Firmware Device File %s (%x). Exiting.\n", FileName, Status);\r
- exit (1);\r
- }\r
-\r
- printf (" FD loaded from %s at 0x%08lx",
- FileName, (unsigned long)gFdInfo[Index].Address);\r
-
- if (PeiCoreFile == NULL) {\r
- //\r
- // Assume the beginning of the FD is an FV and look for the PEI Core.\r
- // Load the first one we find.\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
-\r
- printf ("\n");\r
- }\r
- //\r
- // Calculate memory regions and store the information in the gSystemMemory\r
- // global for later use. The autosizing code will use this data to\r
- // map this memory into the SEC process memory space.\r
- //\r
- Index1 = 0;
- Index = 0;
- while (1) {
- UINTN val = 0;
- //\r
- // Save the size of the memory.
- //\r
- 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++;
- }
-\r
- printf ("\n");\r
-\r
- //\r
- // Hand off to PEI Core\r
- //\r
- SecLoadFromCore ((UINTN) InitialStackMemory, (UINTN) InitialStackMemorySize, (UINTN) gFdInfo[0].Address, PeiCoreFile);\r
-\r
- //\r
- // If we get here, then the PEI Core returned. This is an error as PEI should\r
- // always hand off to DXE.\r
- //\r
- printf ("ERROR : PEI Core returned\n");\r
- exit (1);\r
-}\r
-\r
-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,\r
- IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,\r
- OUT UINT64 *Length\r
- )
-/*++
-
-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;
-}
-\r
-#define BYTES_PER_RECORD 512\r
-\r
-/**\r
- Extracts ASSERT() information from a status code structure.\r
-\r
- Converts the status code specified by CodeType, Value, and Data to the ASSERT()\r
- arguments specified by Filename, Description, and LineNumber. If CodeType is \r
- an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and \r
- Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract \r
- Filename, Description, and LineNumber from the optional data area of the \r
- status code buffer specified by Data. The optional data area of Data contains \r
- a Null-terminated ASCII string for the FileName, followed by a Null-terminated \r
- ASCII string for the Description, followed by a 32-bit LineNumber. If the \r
- ASSERT() information could be extracted from Data, then return TRUE. \r
- Otherwise, FALSE is returned. \r
-\r
- If Data is NULL, then ASSERT().\r
- If Filename is NULL, then ASSERT().\r
- If Description is NULL, then ASSERT().\r
- If LineNumber is NULL, then ASSERT().\r
-\r
- @param CodeType The type of status code being converted.\r
- @param Value The status code value being converted.\r
- @param Data Pointer to status code data buffer. \r
- @param Filename Pointer to the source file name that generated the ASSERT().\r
- @param Description Pointer to the description of the ASSERT().\r
- @param LineNumber Pointer to source line number that generated the ASSERT().\r
-\r
- @retval TRUE The status code specified by CodeType, Value, and Data was \r
- converted ASSERT() arguments specified by Filename, Description, \r
- and LineNumber.\r
- @retval FALSE The status code specified by CodeType, Value, and Data could \r
- not be converted to ASSERT() arguments.\r
-\r
-**/\r
-STATIC\r
-BOOLEAN\r
-ReportStatusCodeExtractAssertInfo (\r
- IN EFI_STATUS_CODE_TYPE CodeType,\r
- IN EFI_STATUS_CODE_VALUE Value, \r
- IN CONST EFI_STATUS_CODE_DATA *Data, \r
- OUT CHAR8 **Filename,\r
- OUT CHAR8 **Description,\r
- OUT UINT32 *LineNumber\r
- )\r
-{\r
- EFI_DEBUG_ASSERT_DATA *AssertData;\r
-\r
- ASSERT (Data != NULL);\r
- ASSERT (Filename != NULL);\r
- ASSERT (Description != NULL);\r
- ASSERT (LineNumber != NULL);\r
-\r
- if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) && \r
- ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED) &&\r
- ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)) {\r
- AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);\r
- *Filename = (CHAR8 *)(AssertData + 1);\r
- *Description = *Filename + AsciiStrLen (*Filename) + 1;\r
- *LineNumber = AssertData->LineNumber;\r
- return TRUE;\r
- }\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-SecPeiReportStatusCode (\r
- IN 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
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine produces the ReportStatusCode PEI service. It's passed\r
- up to the PEI Core via a PPI. T\r
-\r
- This code currently uses the UNIX clib printf. This does not work the same way\r
- as the EFI Print (), as %t, %g, %s as Unicode are not supported.\r
-\r
-Arguments:\r
- (see EFI_PEI_REPORT_STATUS_CODE)\r
-\r
-Returns:\r
- EFI_SUCCESS - Always return success\r
-\r
---*/\r
-// TODO: PeiServices - add argument and description to function comment\r
-// TODO: CodeType - add argument and description to function comment\r
-// TODO: Value - add argument and description to function comment\r
-// TODO: Instance - add argument and description to function comment\r
-// TODO: CallerId - add argument and description to function comment\r
-// TODO: Data - add argument and description to function comment\r
-{\r
- CHAR8 *Format;\r
- EFI_DEBUG_INFO *DebugInfo;\r
- VA_LIST Marker;\r
- CHAR8 PrintBuffer[BYTES_PER_RECORD * 2];\r
- CHAR8 *Filename;\r
- CHAR8 *Description;\r
- UINT32 LineNumber;\r
-\r
- if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {\r
- //\r
- // This supports DEBUG () marcos\r
- // Data format\r
- // EFI_STATUS_CODE_DATA\r
- // EFI_DEBUG_INFO\r
- //\r
- // The first 12 * UINT64 bytes of the string are really an\r
- // arguement stack to support varargs on the Format string.\r
- //\r
- if (Data != NULL) {\r
- DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);\r
- Marker = (VA_LIST) (DebugInfo + 1);\r
- Format = (CHAR8 *) (((UINT64 *) Marker) + 12);\r
-\r
- AsciiVSPrint (PrintBuffer, BYTES_PER_RECORD, Format, Marker);\r
- printf (PrintBuffer);\r
- } else {\r
- printf ("DEBUG <null>\n");\r
- }\r
- }\r
-\r
- if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&\r
- ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED)\r
- ) {\r
- if (Data != NULL && ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {\r
- //\r
- // Support ASSERT () macro\r
- //\r
- printf ("ASSERT %s(%d): %s\n", Filename, LineNumber, Description);\r
- } else {\r
- printf ("ASSERT <null>\n");\r
- }\r
- CpuBreakpoint ();\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-VOID\r
-SecLoadFromCore (\r
- IN UINTN LargestRegion,\r
- IN UINTN LargestRegionSize,\r
- IN UINTN BootFirmwareVolumeBase,\r
- IN VOID *PeiCorePe32File\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- This is the service to load the PEI Core from the Firmware Volume\r
-\r
-Arguments:\r
- LargestRegion - Memory to use for PEI.\r
- LargestRegionSize - Size of Memory to use for PEI\r
- BootFirmwareVolumeBase - Start of the Boot FV\r
- PeiCorePe32File - PEI Core PE32\r
-\r
-Returns:\r
- Success means control is transfered and thus we should never return\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_PEI_STARTUP_DESCRIPTOR *PeiStartup;\r
-\r
- //\r
- // Compute Top Of Memory for Stack and PEI Core Allocations\r
- //\r
- TopOfMemory = LargestRegion + LargestRegionSize;\r
-\r
- //\r
- // Allocate 128KB for the Stack\r
- //\r
- TopOfStack = (VOID *)((UINTN)TopOfMemory - sizeof (EFI_PEI_STARTUP_DESCRIPTOR) - 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
- //\r
- gPrivateDispatchTable[0].Ppi = gPeiEfiPeiPeCoffLoader;\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
-\r
- //\r
- // Load the PEI Core from a Firmware Volume\r
- //\r
- Status = SecWinNtPeiLoadFile (\r
- PeiCorePe32File,\r
- &PeiImageAddress,\r
- &PeiCoreSize,\r
- &PeiCoreEntryPoint\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
- printf ("Jump to 0x%08lx\n", (unsigned long)PeiCoreEntryPoint);
- //\r
- // Transfer control to the PEI Core\r
- //\r
- SwitchStack (\r
- (SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint,\r
- PeiStartup,\r
- NULL,\r
- TopOfStack\r
- );\r
- //\r
- // If we get here, then the PEI Core returned. This is an error\r
- //\r
- return ;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-SecWinNtPeiAutoScan (\r
- IN UINTN Index,\r
- OUT EFI_PHYSICAL_ADDRESS *MemoryBase,\r
- OUT UINT64 *MemorySize\r
- )\r
-/*++\r
-\r
-Routine Description:\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 host environment variable EFI_MEMORY_SIZE.\r
- The size comes from the varaible and the address comes from the call to\r
- WinNtOpenFile.\r
-\r
-Arguments:\r
- Index - Which memory region to use\r
- MemoryBase - Return Base address of memory region\r
- MemorySize - Return size in bytes of the memory region\r
-\r
-Returns:\r
- EFI_SUCCESS - If memory region was mapped\r
- EFI_UNSUPPORTED - If Index is not supported\r
-\r
---*/\r
-{\r
- void *res;
-\r
- if (Index >= gSystemMemoryCount) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- *MemoryBase = 0;\r
- 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;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID *\r
-EFIAPI\r
-SecWinNtWinNtThunkAddress (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Since the SEC is the only Unix program in stack it must export\r
- an interface to do Win API calls. That's what the WinNtThunk address\r
- is for. gWinNt is initailized in WinNtThunk.c.\r
-\r
-Arguments:\r
- InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL);\r
- InterfaceBase - Address of the gWinNt global\r
-\r
-Returns:\r
- EFI_SUCCESS - Data returned\r
-\r
---*/\r
-{\r
- return gUnix;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-SecWinNtPeiLoadFile (\r
- IN VOID *Pe32Data,\r
- IN EFI_PHYSICAL_ADDRESS *ImageAddress,\r
- IN UINT64 *ImageSize,\r
- IN EFI_PHYSICAL_ADDRESS *EntryPoint\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Loads and relocates a PE/COFF image into memory.\r
-\r
-Arguments:\r
- Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated\r
- ImageAddress - The base address of the relocated PE/COFF image\r
- ImageSize - The size of the relocated PE/COFF image\r
- EntryPoint - The entry point of the relocated PE/COFF image\r
-\r
-Returns:\r
- EFI_SUCCESS - The file was loaded and relocated\r
- EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
-\r
- ZeroMem (&ImageContext, sizeof (ImageContext));\r
- ImageContext.Handle = Pe32Data;\r
-\r
- ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) SecImageRead;\r
-\r
- Status = gPeiEfiPeiPeCoffLoader->GetImageInfo (gPeiEfiPeiPeCoffLoader, &ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Allocate space in UNIX (not emulator) memory. Extra space is for alignment\r
- //\r
- ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) malloc ((UINTN) (ImageContext.ImageSize + (ImageContext.SectionAlignment * 2)));\r
- if (ImageContext.ImageAddress == 0) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Align buffer on section boundry\r
- //\r
- ImageContext.ImageAddress += ImageContext.SectionAlignment;\r
- ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);\r
-
-\r
- Status = gPeiEfiPeiPeCoffLoader->LoadImage (gPeiEfiPeiPeCoffLoader, &ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = gPeiEfiPeiPeCoffLoader->RelocateImage (gPeiEfiPeiPeCoffLoader, &ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // BugBug: Flush Instruction Cache Here when CPU Lib is ready\r
- //\r
-\r
- *ImageAddress = ImageContext.ImageAddress;\r
- *ImageSize = ImageContext.ImageSize;\r
- *EntryPoint = ImageContext.EntryPoint;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-SecWinNtFdAddress (\r
- IN UINTN Index,\r
- IN OUT EFI_PHYSICAL_ADDRESS *FdBase,\r
- IN OUT UINT64 *FdSize\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Return the FD Size and base address. Since the FD is loaded from a\r
- file into host memory only the SEC will know it's address.\r
-\r
-Arguments:\r
- Index - Which FD, starts at zero.\r
- FdSize - Size of the FD in bytes\r
- FdBase - Start address of the FD. Assume it points to an FV Header\r
-\r
-Returns:\r
- EFI_SUCCESS - Return the Base address and size of the FV\r
- EFI_UNSUPPORTED - Index does nto map to an FD in the system\r
-\r
---*/\r
-{\r
- if (Index >= gFdInfoCount) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- *FdBase = gFdInfo[Index].Address;\r
- *FdSize = gFdInfo[Index].Size;\r
-\r
- if (*FdBase == 0 && *FdSize == 0) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-SecImageRead (\r
- IN VOID *FileHandle,\r
- IN UINTN FileOffset,\r
- IN OUT UINTN *ReadSize,\r
- OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
-\r
-Arguments:\r
- FileHandle - The handle to the PE/COFF file\r
- FileOffset - The offset, in bytes, into the file to read\r
- ReadSize - The number of bytes to read from the file starting at FileOffset\r
- Buffer - A pointer to the buffer to read the data into.\r
-\r
-Returns:\r
- EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
-\r
---*/\r
-{\r
- CHAR8 *Destination8;\r
- CHAR8 *Source8;\r
- UINTN Length;\r
-\r
- Destination8 = Buffer;\r
- Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
- Length = *ReadSize;\r
- while (Length--) {\r
- *(Destination8++) = *(Source8++);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-UINTN\r
-CountSeperatorsInString (\r
- IN const CHAR16 *String,\r
- IN CHAR16 Seperator\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Count the number of seperators in String\r
-\r
-Arguments:\r
- String - String to process\r
- Seperator - Item to count\r
-\r
-Returns:\r
- Number of Seperator in String\r
-\r
---*/\r
-{\r
- UINTN Count;\r
-\r
- for (Count = 0; *String != '\0'; String++) {\r
- if (*String == Seperator) {\r
- Count++;\r
- }\r
- }\r
-\r
- return Count;\r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-SecNt32PeCoffGetImageInfo (\r
- IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,\r
- 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
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-SecNt32PeCoffLoadImage (\r
- IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,\r
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = PeCoffLoaderLoadImage (ImageContext);\r
- return Status;\r
-}\r
-\r
-VOID
-SecUnixLoaderBreak (
- VOID
- )
-{
-}
-
-EFI_STATUS\r
-EFIAPI\r
-SecNt32PeCoffRelocateImage (\r
- IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,\r
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
- )\r
-{\r
-\r
-#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);\r
- 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);\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-SecNt32PeCoffUnloadimage (\r
- IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,\r
- IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
- )\r
-{\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-_ModuleEntryPoint (\r
- VOID\r
- )\r
-{\r
-}\r
-\r