Added generic EFIABI SEC to InOsEmuPkg. Add library to abstract FV cracking and remove code from original Sec/OS App. Add a PeiServicesLib wrapper for SEC that uses passed in PEI list and can abstract FV reading. Don't load images for XIP code and just run from FV directly on Mac OS X, or from dlopen on Linux. Moved temp ram switch code into generic SEC. Fixed design issue with PeiServiceTablePointerLib.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11646 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
andrewfish
2011-05-14 16:00:22 +00:00
parent 960212a3e4
commit 65e3f333b3
27 changed files with 1524 additions and 772 deletions

View File

@@ -1,309 +0,0 @@
/*++ @file
A simple FV stack so the SEC can extract the SEC Core from an
FV.
Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
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.
**/
#include "SecMain.h"
#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
(ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
EFI_FFS_FILE_STATE
GetFileState (
IN UINT8 ErasePolarity,
IN EFI_FFS_FILE_HEADER *FfsHeader
)
/*++
Routine Description:
Returns the highest bit set of the State field
Arguments:
ErasePolarity - Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
in the Attributes field.
FfsHeader - Pointer to FFS File Header.
Returns:
Returns the highest bit in the State field
**/
{
EFI_FFS_FILE_STATE FileState;
EFI_FFS_FILE_STATE HighestBit;
FileState = FfsHeader->State;
if (ErasePolarity != 0) {
FileState = (EFI_FFS_FILE_STATE)~FileState;
}
HighestBit = 0x80;
while (HighestBit != 0 && (HighestBit & FileState) == 0) {
HighestBit >>= 1;
}
return HighestBit;
}
UINT8
CalculateHeaderChecksum (
IN EFI_FFS_FILE_HEADER *FileHeader
)
/*++
Routine Description:
Calculates the checksum of the header of a file.
Arguments:
FileHeader - Pointer to FFS File Header.
Returns:
Checksum of the header.
**/
{
UINT8 *ptr;
UINTN Index;
UINT8 Sum;
Sum = 0;
ptr = (UINT8 *) FileHeader;
for (Index = 0; Index < sizeof (EFI_FFS_FILE_HEADER) - 3; Index += 4) {
Sum = (UINT8) (Sum + ptr[Index]);
Sum = (UINT8) (Sum + ptr[Index + 1]);
Sum = (UINT8) (Sum + ptr[Index + 2]);
Sum = (UINT8) (Sum + ptr[Index + 3]);
}
for (; Index < sizeof (EFI_FFS_FILE_HEADER); Index++) {
Sum = (UINT8) (Sum + ptr[Index]);
}
//
// State field (since this indicates the different state of file).
//
Sum = (UINT8) (Sum - FileHeader->State);
//
// Checksum field of the file is not part of the header checksum.
//
Sum = (UINT8) (Sum - FileHeader->IntegrityCheck.Checksum.File);
return Sum;
}
EFI_STATUS
SecFfsFindNextFile (
IN EFI_FV_FILETYPE SearchType,
IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
IN OUT EFI_FFS_FILE_HEADER **FileHeader
)
/*++
Routine Description:
Given the input file pointer, search for the next matching file in the
FFS volume as defined by SearchType. The search starts from FileHeader inside
the Firmware Volume defined by FwVolHeader.
Arguments:
SearchType - Filter to find only files of this type.
Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
FwVolHeader - Pointer to the FV header of the volume to search.
This parameter must point to a valid FFS volume.
FileHeader - Pointer to the current file from which to begin searching.
This pointer will be updated upon return to reflect the file
found.
Returns:
EFI_NOT_FOUND - No files matching the search criteria were found
EFI_SUCCESS
**/
{
EFI_FFS_FILE_HEADER *FfsFileHeader;
UINT32 FileLength;
UINT32 FileOccupiedSize;
UINT32 FileOffset;
UINT64 FvLength;
UINT8 ErasePolarity;
UINT8 FileState;
FvLength = FwVolHeader->FvLength;
if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
ErasePolarity = 1;
} else {
ErasePolarity = 0;
}
//
// If FileHeader is not specified (NULL) start with the first file in the
// firmware volume. Otherwise, start from the FileHeader.
//
if (*FileHeader == NULL) {
FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FwVolHeader + FwVolHeader->HeaderLength);
} else {
//
// Length is 24 bits wide so mask upper 8 bits
// FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
//
FileLength = *(UINT32 *) (*FileHeader)->Size & 0x00FFFFFF;
FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) *FileHeader + FileOccupiedSize);
}
FileOffset = (UINT32) ((UINT8 *) FfsFileHeader - (UINT8 *) FwVolHeader);
while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
//
// Get FileState which is the highest bit of the State
//
FileState = GetFileState (ErasePolarity, FfsFileHeader);
switch (FileState) {
case EFI_FILE_HEADER_INVALID:
FileOffset += sizeof (EFI_FFS_FILE_HEADER);
FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));
break;
case EFI_FILE_DATA_VALID:
case EFI_FILE_MARKED_FOR_UPDATE:
if (CalculateHeaderChecksum (FfsFileHeader) == 0) {
FileLength = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF;
FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
if ((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) {
*FileHeader = FfsFileHeader;
return EFI_SUCCESS;
}
FileOffset += FileOccupiedSize;
FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);
} else {
return EFI_NOT_FOUND;
}
break;
case EFI_FILE_DELETED:
FileLength = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF;
FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
FileOffset += FileOccupiedSize;
FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);
break;
default:
return EFI_NOT_FOUND;
}
}
return EFI_NOT_FOUND;
}
EFI_STATUS
SecFfsFindSectionData (
IN EFI_SECTION_TYPE SectionType,
IN EFI_FFS_FILE_HEADER *FfsFileHeader,
IN OUT VOID **SectionData
)
/*++
Routine Description:
Given the input file pointer, search for the next matching section in the
FFS volume.
Arguments:
SearchType - Filter to find only sections of this type.
FfsFileHeader - Pointer to the current file to search.
SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
NULL if section not found
Returns:
EFI_NOT_FOUND - No files matching the search criteria were found
EFI_SUCCESS
**/
{
UINT32 FileSize;
EFI_COMMON_SECTION_HEADER *Section;
UINT32 SectionLength;
UINT32 ParsedLength;
//
// Size is 24 bits wide so mask upper 8 bits.
// Does not include FfsFileHeader header size
// FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
//
Section = (EFI_COMMON_SECTION_HEADER *) (FfsFileHeader + 1);
FileSize = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF;
FileSize -= sizeof (EFI_FFS_FILE_HEADER);
*SectionData = NULL;
ParsedLength = 0;
while (ParsedLength < FileSize) {
if (Section->Type == SectionType) {
*SectionData = (VOID *) (Section + 1);
return EFI_SUCCESS;
}
//
// Size is 24 bits wide so mask upper 8 bits.
// SectionLength is adjusted it is 4 byte aligned.
// Go to the next section
//
SectionLength = *(UINT32 *) Section->Size & 0x00FFFFFF;
SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
ParsedLength += SectionLength;
Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength);
}
return EFI_NOT_FOUND;
}
EFI_STATUS
SecFfsFindPeiCore (
IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
OUT VOID **Pe32Data
)
/*++
Routine Description:
Given the pointer to the Firmware Volume Header find the SEC
core and return it's PE32 image.
Arguments:
FwVolHeader - Pointer to memory mapped FV
Pe32Data - Pointer to SEC PE32 iamge.
Returns:
EFI_SUCCESS - Pe32Data is valid
other - Failure
**/
{
EFI_STATUS Status;
EFI_FFS_FILE_HEADER *FileHeader;
EFI_FV_FILETYPE SearchType;
SearchType = EFI_FV_FILETYPE_PEI_CORE;
FileHeader = NULL;
do {
Status = SecFfsFindNextFile (SearchType, FwVolHeader, &FileHeader);
if (!EFI_ERROR (Status)) {
Status = SecFfsFindSectionData (EFI_SECTION_PE32, FileHeader, Pe32Data);
return Status;
}
} while (!EFI_ERROR (Status));
return Status;
}

View File

@@ -109,15 +109,6 @@ GasketSecGetNextProtocol (
// PPIs produced by SEC
EFI_STATUS
EFIAPI
GasketSecUnixPeiLoadFile (
IN VOID *Pe32Data,
IN EFI_PHYSICAL_ADDRESS *ImageAddress,
IN UINT64 *ImageSize,
OUT EFI_PHYSICAL_ADDRESS *EntryPoint
);
EFI_STATUS
EFIAPI

View File

@@ -27,13 +27,9 @@ char *gGdbWorkingFileName = NULL;
EMU_THUNK_PPI mSecEmuThunkPpi = {
GasketSecUnixPeiAutoScan,
GasketSecUnixFdAddress,
GasketSecEmuThunkAddress,
GasketSecUnixPeiLoadFile
GasketSecEmuThunkAddress
};
EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPpi = {
GasketSecTemporaryRamSupport
};
@@ -44,8 +40,8 @@ EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPpi = {
// The number of array elements is allocated base on parsing
// EFI_FIRMWARE_VOLUMES and the memory is never freed.
//
UINTN gFdInfoCount = 0;
EMU_FD_INFO *gFdInfo;
UINTN gFdInfoCount = 0;
EMU_FD_INFO *gFdInfo;
//
// Array that supports seperate memory rantes.
@@ -53,8 +49,8 @@ EMU_FD_INFO *gFdInfo;
// The number of array elements is allocated base on parsing
// EFI_MEMORY_SIZE and the memory is never freed.
//
UINTN gSystemMemoryCount = 0;
EMU_SYSTEM_MEMORY *gSystemMemory;
UINTN gSystemMemoryCount = 0;
EMU_SYSTEM_MEMORY *gSystemMemory;
@@ -63,33 +59,6 @@ IMAGE_CONTEXT_TO_MOD_HANDLE *mImageContextModHandleArray = NULL;
EFI_PHYSICAL_ADDRESS *
MapMemory (
INTN fd,
UINT64 length,
INTN prot,
INTN flags);
EFI_STATUS
MapFile (
IN CHAR8 *FileName,
IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
OUT UINT64 *Length
);
EFI_STATUS
EFIAPI
SecNt32PeCoffRelocateImage (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
);
int
main (
IN int Argc,
IN char **Argv,
IN char **Envp
)
/*++
Routine Description:
@@ -105,6 +74,12 @@ Returns:
1 - Abnormal exit
**/
int
main (
IN int Argc,
IN char **Argv,
IN char **Envp
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS InitialStackMemory;
@@ -115,25 +90,24 @@ Returns:
UINTN PeiIndex;
CHAR8 *FileName;
BOOLEAN Done;
VOID *PeiCoreFile;
EFI_PEI_FILE_HANDLE FileHandle;
VOID *SecFile;
CHAR16 *MemorySizeStr;
CHAR16 *FirmwareVolumesStr;
UINTN *StackPointer;
setbuf(stdout, 0);
setbuf(stderr, 0);
setbuf (stdout, 0);
setbuf (stderr, 0);
MemorySizeStr = (CHAR16 *) PcdGetPtr (PcdEmuMemorySize);
FirmwareVolumesStr = (CHAR16 *) PcdGetPtr (PcdEmuFirmwareVolume);
printf ("\nEDK SEC Main UNIX Emulation Environment from edk2.sourceforge.net\n");
printf ("\nEDK II UNIX Emulation Environment from edk2.sourceforge.net\n");
//
// PPIs pased into PEI_CORE
//
AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI, &gEfiTemporaryRamSupportPpiGuid, &mSecTemporaryRamSupportPpi);
AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI, &gEmuThunkPpiGuid, &mSecEmuThunkPpi);
AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI, &gEmuPeiServicesTableUpdatePpiGuid, NULL);
SecInitThunkProtocol ();
@@ -149,6 +123,10 @@ Returns:
AddThunkProtocol (&gPthreadThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuApCount), FALSE);
// EmuSecLibConstructor ();
gPpiList = GetThunkPpiList ();
#ifdef __APPLE__
//
@@ -185,23 +163,24 @@ Returns:
printf (" BootMode 0x%02x\n", (unsigned int)PcdGet32 (PcdEmuBootMode));
//
// Open up a 128K file to emulate temp memory for PEI.
// Open up a 128K file to emulate temp memory for SEC.
// on a real platform this would be SRAM, or using the cache as RAM.
// Set InitialStackMemory to zero so UnixOpenFile will allocate a new mapping
//
InitialStackMemorySize = STACK_SIZE;
InitialStackMemory = (UINTN)MapMemory(0,
(UINT32) InitialStackMemorySize,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANONYMOUS | MAP_PRIVATE);
InitialStackMemory = (UINTN)MapMemory (
0, (UINT32) InitialStackMemorySize,
PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE
);
if (InitialStackMemory == 0) {
printf ("ERROR : Can not open SecStack Exiting\n");
exit (1);
}
printf (" SEC passing in %u KB of temp RAM at 0x%08lx to PEI\n",
printf (" OS Emulator passing in %u KB of temp RAM at 0x%08lx to SEC\n",
(unsigned int)(InitialStackMemorySize / 1024),
(unsigned long)InitialStackMemory);
(unsigned long)InitialStackMemory
);
for (StackPointer = (UINTN*) (UINTN) InitialStackMemory;
StackPointer < (UINTN*)(UINTN)((UINTN) InitialStackMemory + (UINT64) InitialStackMemorySize);
@@ -219,40 +198,49 @@ Returns:
}
Index2 = 0;
for (Done = FALSE, Index = 0, PeiIndex = 0, PeiCoreFile = NULL;
for (Done = FALSE, Index = 0, PeiIndex = 0, SecFile = NULL;
FirmwareVolumesStr[Index2] != 0;
Index++) {
for (Index1 = 0; (FirmwareVolumesStr[Index2] != '!') && (FirmwareVolumesStr[Index2] != 0); Index2++)
for (Index1 = 0; (FirmwareVolumesStr[Index2] != '!') && (FirmwareVolumesStr[Index2] != 0); Index2++) {
FileName[Index1++] = FirmwareVolumesStr[Index2];
if (FirmwareVolumesStr[Index2] == '!')
}
if (FirmwareVolumesStr[Index2] == '!') {
Index2++;
}
FileName[Index1] = '\0';
//
// Open the FD and remmeber where it got mapped into our processes address space
//
Status = MapFile (
FileName,
&gFdInfo[Index].Address,
&gFdInfo[Index].Size
);
FileName,
&gFdInfo[Index].Address,
&gFdInfo[Index].Size
);
if (EFI_ERROR (Status)) {
printf ("ERROR : Can not open Firmware Device File %s (%x). Exiting.\n", FileName, (unsigned int)Status);
exit (1);
}
printf (" FD loaded from %s at 0x%08lx",
FileName, (unsigned long)gFdInfo[Index].Address);
printf (" FD loaded from %s at 0x%08lx",FileName, (unsigned long)gFdInfo[Index].Address);
if (PeiCoreFile == NULL) {
if (SecFile == NULL) {
//
// Assume the beginning of the FD is an FV and look for the PEI Core.
// Assume the beginning of the FD is an FV and look for the SEC Core.
// Load the first one we find.
//
Status = SecFfsFindPeiCore ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) gFdInfo[Index].Address, &PeiCoreFile);
FileHandle = NULL;
Status = PeiServicesFfsFindNextFile (
EFI_FV_FILETYPE_SECURITY_CORE,
(EFI_PEI_FV_HANDLE)(UINTN)gFdInfo[Index].Address,
&FileHandle
);
if (!EFI_ERROR (Status)) {
PeiIndex = Index;
printf (" contains SEC Core");
Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SecFile);
if (!EFI_ERROR (Status)) {
PeiIndex = Index;
printf (" contains SEC Core");
}
}
}
@@ -275,26 +263,28 @@ Returns:
Index1++;
}
gSystemMemory[Index++].Size = val * 0x100000;
if (MemorySizeStr[Index1] == 0)
if (MemorySizeStr[Index1] == 0) {
break;
}
Index1++;
}
printf ("\n");
//
// Hand off to PEI Core
// Hand off to SEC
//
SecLoadFromCore ((UINTN) InitialStackMemory, (UINTN) InitialStackMemorySize, (UINTN) gFdInfo[0].Address, PeiCoreFile);
SecLoadFromCore ((UINTN) InitialStackMemory, (UINTN) InitialStackMemorySize, (UINTN) gFdInfo[0].Address, SecFile);
//
// If we get here, then the PEI Core returned. This is an error as PEI should
// always hand off to DXE.
// If we get here, then the SEC Core returned. This is an error as SEC should
// always hand off to PEI Core and then on to DXE Core.
//
printf ("ERROR : PEI Core returned\n");
printf ("ERROR : SEC returned\n");
exit (1);
}
EFI_PHYSICAL_ADDRESS *
MapMemory (
INTN fd,
@@ -318,8 +308,7 @@ MapMemory (
}
if ((((UINTN)res) & ~(align-1)) == (UINTN)res) {
isAligned=1;
}
else {
} else {
munmap(res, length);
base += align;
}
@@ -327,12 +316,7 @@ MapMemory (
return res;
}
EFI_STATUS
MapFile (
IN CHAR8 *FileName,
IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
OUT UINT64 *Length
)
/*++
Routine Description:
@@ -356,24 +340,32 @@ Returns:
EFI_DEVICE_ERROR - An error occured attempting to map the opened file
**/
EFI_STATUS
MapFile (
IN CHAR8 *FileName,
IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
OUT UINT64 *Length
)
{
int fd;
VOID *res;
UINTN FileSize;
fd = open (FileName, O_RDONLY);
if (fd < 0)
if (fd < 0) {
return EFI_NOT_FOUND;
}
FileSize = lseek (fd, 0, SEEK_END);
res = MapMemory(fd, FileSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
res = MapMemory (fd, FileSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
close (fd);
if (res == MAP_FAILED)
if (res == MAP_FAILED) {
return EFI_DEVICE_ERROR;
}
*Length = (UINT64) FileSize;
*BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) res;
@@ -382,6 +374,21 @@ Returns:
/*++
Routine Description:
This is the service to load the SEC Core from the Firmware Volume
Arguments:
LargestRegion - Memory to use for SEC.
LargestRegionSize - Size of Memory to use for PEI
BootFirmwareVolumeBase - Start of the Boot FV
PeiCorePe32File - SEC PE32
Returns:
Success means control is transfered and thus we should never return
**/
VOID
SecLoadFromCore (
IN UINTN LargestRegion,
@@ -389,28 +396,11 @@ SecLoadFromCore (
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;
EFI_PHYSICAL_ADDRESS TopOfMemory;
VOID *TopOfStack;
UINT64 PeiCoreSize;
EFI_PHYSICAL_ADDRESS PeiCoreEntryPoint;
EFI_PHYSICAL_ADDRESS PeiImageAddress;
EFI_SEC_PEI_HAND_OFF *SecCoreData;
UINTN PeiStackSize;
@@ -442,7 +432,7 @@ Returns:
//
// Bind this information into the SEC hand-off state
//
SecCoreData = (EFI_SEC_PEI_HAND_OFF*)(UINTN) TopOfStack;
SecCoreData = (EFI_SEC_PEI_HAND_OFF*)(UINTN) TopOfStack;
SecCoreData->DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
SecCoreData->BootFirmwareVolumeBase = (VOID*)BootFirmwareVolumeBase;
SecCoreData->BootFirmwareVolumeSize = PcdGet32 (PcdEmuFirmwareFdSize);
@@ -454,41 +444,30 @@ Returns:
SecCoreData->PeiTemporaryRamSize = STACK_SIZE - PeiStackSize;
//
// Load the PEI Core from a Firmware Volume
// Find the SEC Core Entry Point
//
Status = SecUnixPeiLoadFile (
PeiCorePe32File,
&PeiImageAddress,
&PeiCoreSize,
&PeiCoreEntryPoint
);
Status = SecPeCoffGetEntryPoint (PeiCorePe32File, (VOID **)&PeiCoreEntryPoint);
if (EFI_ERROR (Status)) {
return ;
}
//
// Transfer control to the PEI Core
// Transfer control to the SEC Core
//
PeiSwitchStacks (
(SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint,
SecCoreData,
(VOID *)GetThunkPpiList (),
(VOID *)gPpiList,
NULL,
TopOfStack
);
//
// If we get here, then the PEI Core returned. This is an error
// If we get here, then the SEC Core returned. This is an error
//
return ;
}
EFI_STATUS
EFIAPI
SecUnixPeiAutoScan (
IN UINTN Index,
OUT EFI_PHYSICAL_ADDRESS *MemoryBase,
OUT UINT64 *MemorySize
)
/*++
Routine Description:
@@ -509,6 +488,13 @@ Returns:
EFI_UNSUPPORTED - If Index is not supported
**/
EFI_STATUS
EFIAPI
SecUnixPeiAutoScan (
IN UINTN Index,
OUT EFI_PHYSICAL_ADDRESS *MemoryBase,
OUT UINT64 *MemorySize
)
{
void *res;
@@ -517,11 +503,14 @@ Returns:
}
*MemoryBase = 0;
res = MapMemory(0, gSystemMemory[Index].Size,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS);
if (res == MAP_FAILED)
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;
@@ -529,11 +518,7 @@ Returns:
return EFI_SUCCESS;
}
VOID *
EFIAPI
SecEmuThunkAddress (
VOID
)
/*++
Routine Description:
@@ -548,93 +533,16 @@ Returns:
EFI_SUCCESS - Data returned
**/
VOID *
EFIAPI
SecEmuThunkAddress (
VOID
)
{
return &gEmuThunkProtocol;
}
EFI_STATUS
SecUnixPeiLoadFile (
IN VOID *Pe32Data,
OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
OUT UINT64 *ImageSize,
OUT 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 UNIX (not emulator) memory. Extra space is for alignment
//
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) MapMemory (
0,
(UINT32) (ImageContext.ImageSize + (ImageContext.SectionAlignment * 2)),
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANONYMOUS | MAP_PRIVATE
);
if (ImageContext.ImageAddress == 0) {
return EFI_OUT_OF_RESOURCES;
}
//
// Align buffer on section boundry
//
ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)(ImageContext.SectionAlignment - 1));
Status = PeCoffLoaderLoadImage (&ImageContext);
if (EFI_ERROR (Status)) {
return Status;
}
Status = PeCoffLoaderRelocateImage (&ImageContext);
if (EFI_ERROR (Status)) {
return Status;
}
SecPeCoffRelocateImageExtraAction (&ImageContext);
//
// BugBug: Flush Instruction Cache Here when CPU Lib is ready
//
*ImageAddress = ImageContext.ImageAddress;
*ImageSize = ImageContext.ImageSize;
*EntryPoint = ImageContext.EntryPoint;
return EFI_SUCCESS;
}
RETURN_STATUS
EFIAPI
@@ -643,27 +551,28 @@ SecPeCoffGetEntryPoint (
IN OUT VOID **EntryPoint
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS ImageAddress;
UINT64 ImageSize;
EFI_PHYSICAL_ADDRESS PhysEntryPoint;
EFI_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data;
ImageContext.SizeOfHeaders = PeCoffGetSizeOfHeaders (Pe32Data);
ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer (Pe32Data);
Status = PeCoffLoaderGetEntryPoint (Pe32Data, EntryPoint);
if (!EFI_ERROR (Status)) {
return Status;
}
Status = SecUnixPeiLoadFile (Pe32Data, &ImageAddress, &ImageSize, &PhysEntryPoint);
ImageContext.EntryPoint = (UINTN)EntryPoint;
*EntryPoint = (VOID *)(UINTN)PhysEntryPoint;
// On Unix a dlopen is done that will change the entry point
SecPeCoffRelocateImageExtraAction (&ImageContext);
*EntryPoint = (VOID *)(UINTN)ImageContext.EntryPoint;
return Status;
}
EFI_STATUS
EFIAPI
SecUnixFdAddress (
IN UINTN Index,
IN OUT EFI_PHYSICAL_ADDRESS *FdBase,
IN OUT UINT64 *FdSize,
IN OUT EFI_PHYSICAL_ADDRESS *FixUp
)
/*++
Routine Description:
@@ -681,6 +590,14 @@ Returns:
EFI_UNSUPPORTED - Index does nto map to an FD in the system
**/
EFI_STATUS
EFIAPI
SecUnixFdAddress (
IN UINTN Index,
IN OUT EFI_PHYSICAL_ADDRESS *FdBase,
IN OUT UINT64 *FdSize,
IN OUT EFI_PHYSICAL_ADDRESS *FixUp
)
{
if (Index >= gFdInfoCount) {
return EFI_UNSUPPORTED;
@@ -706,49 +623,7 @@ Returns:
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;
}
UINTN
CountSeperatorsInString (
IN const CHAR16 *String,
IN CHAR16 Seperator
)
/*++
Routine Description:
@@ -762,6 +637,11 @@ Returns:
Number of Seperator in String
**/
UINTN
CountSeperatorsInString (
IN const CHAR16 *String,
IN CHAR16 Seperator
)
{
UINTN Count;
@@ -775,11 +655,6 @@ Returns:
}
EFI_STATUS
AddHandle (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
IN VOID *ModHandle
)
/*++
Routine Description:
@@ -796,6 +671,11 @@ Returns:
EFI_SUCCESS - ModHandle was stored.
**/
EFI_STATUS
AddHandle (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
IN VOID *ModHandle
)
{
UINTN Index;
IMAGE_CONTEXT_TO_MOD_HANDLE *Array;
@@ -835,10 +715,6 @@ Returns:
}
VOID *
RemoveHandle (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
/*++
Routine Description:
@@ -853,6 +729,10 @@ Returns:
NULL - No ModHandle associated with ImageContext
**/
VOID *
RemoveHandle (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
{
UINTN Index;
IMAGE_CONTEXT_TO_MOD_HANDLE *Array;
@@ -890,7 +770,7 @@ Returns:
// b SecGdbScriptBreak
// command
// silent
// source SecMain.dll.gdb
// source SecMain.gdb
// c
// end
//
@@ -1057,11 +937,13 @@ SecPeCoffRelocateImageExtraAction (
return;
}
fprintf (stderr,
fprintf (
stderr,
"Loading %s 0x%08lx - entry point 0x%08lx\n",
ImageContext->PdbPointer,
(unsigned long)ImageContext->ImageAddress,
(unsigned long)ImageContext->EntryPoint);
(unsigned long)ImageContext->EntryPoint
);
Handle = dlopen (ImageContext->PdbPointer, RTLD_NOW);
@@ -1073,7 +955,7 @@ SecPeCoffRelocateImageExtraAction (
if (Entry != NULL) {
ImageContext->EntryPoint = (UINTN)Entry;
printf("Change %s Entrypoint to :0x%08lx\n", ImageContext->PdbPointer, (unsigned long)Entry);
printf ("Change %s Entrypoint to :0x%08lx\n", ImageContext->PdbPointer, (unsigned long)Entry);
}
SecUnixLoaderBreak ();

View File

@@ -28,11 +28,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/ThunkPpiList.h>
#include <Library/ThunkProtocolList.h>
#include <Library/PpiListLib.h>
#include <Library/PeiServicesLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Ppi/EmuThunk.h>
#include <Ppi/StatusCode.h>
#include <Ppi/TemporaryRamSupport.h>
#include <Ppi/EmuPeiServicesTableUpdate.h>
#include <Protocol/SimplePointer.h>
#include <Protocol/SimpleTextIn.h>
@@ -289,7 +290,23 @@ VOID
SecInitThunkProtocol (
VOID
);
EFI_PHYSICAL_ADDRESS *
MapMemory (
INTN fd,
UINT64 length,
INTN prot,
INTN flags);
EFI_STATUS
MapFile (
IN CHAR8 *FileName,
IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
OUT UINT64 *Length
);
VOID SecSleep (UINT64 Milliseconds);
VOID SecEnableInterrupt (VOID);

View File

@@ -32,7 +32,6 @@
[Sources]
SecMain.c
EmuThunk.c
FwVol.c
X11GraphicsWindow.c
Pthreads.c
PosixFileSystem.c
@@ -46,7 +45,6 @@
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
InOsEmuPkg/InOsEmuPkg.dec
InOsEmuPkg/InOsEmuPkg.dec
[LibraryClasses]
DebugLib
@@ -57,13 +55,13 @@
PeCoffLib
ThunkPpiList
ThunkProtocolList
PpiListLib
PeiServicesLib
PeCoffGetEntryPointLib
[Ppis]
gEfiPeiStatusCodePpiGuid # PPI ALWAYS_PRODUCED
gEfiTemporaryRamSupportPpiGuid
gEmuThunkPpiGuid
gEmuPeiServicesTableUpdatePpiGuid
[Protocols]
gEmuIoThunkProtocolGuid

View File

@@ -727,30 +727,6 @@ ASM_PFX(ReverseGasketUint64Uint64):
ret
// Sec PPI Callbacks - Check Me
ASM_GLOBAL ASM_PFX(GasketSecUnixPeiLoadFile)
ASM_PFX(GasketSecUnixPeiLoadFile):
pushq %rbp // stack frame is for the debugger
movq %rsp, %rbp
pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI
pushq %rdi
movq %rcx, %rdi // Swizzle args
movq %rdx, %rsi
movq %r8, %rdx
movq %r9, %rcx
call ASM_PFX(SecUnixPeiLoadFile)
popq %rdi // restore state
popq %rsi
popq %rbp
ret
ASM_GLOBAL ASM_PFX(GasketSecUnixPeiAutoScan)
ASM_PFX(GasketSecUnixPeiAutoScan):
pushq %rbp // stack frame is for the debugger

View File

@@ -52,61 +52,3 @@ ASM_PFX(PeiSwitchStacks):
// EFI_STATUS
// EFIAPI
// SecTemporaryRamSupport (
// IN CONST EFI_PEI_SERVICES **PeiServices, // %rcx
// IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, // %rdx
// IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, // %r8
// IN UINTN CopySize // %r9
// )
//
ASM_GLOBAL ASM_PFX(GasketSecTemporaryRamSupport)
ASM_PFX(GasketSecTemporaryRamSupport):
// Adjust callers %rbp to account for stack move
subq %rdx, %rbp // Calc offset of %rbp in Temp Memory
addq %r8, %rbp // add in permanent base to offset
pushq %rbp // stack frame is for the debugger
movq %rsp, %rbp
pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI
pushq %rdi
pushq %rdx // Save TemporaryMemoryBase
pushq %r8 // Save PermanentMemoryBase
pushq %r9 // Save CopySize
//
// Copy all of temp RAM to permanent memory, including stack
//
// CopyMem (PermanentMemoryBase, TemporaryMemoryBase, CopySize);
// %rdi, %rsi, %rdx
movq %r8, %rdi // Swizzle args
movq %rdx, %rsi
movq %r9, %rdx
call ASM_PFX(CopyMem)
// Temp mem stack now copied to permanent location. %esp still in temp memory
popq %r9 // CopySize (old stack)
popq %r8 // PermanentMemoryBase (old stack)
popq %rdx // TemporaryMemoryBase (old stack)
movq %rsp, %rcx // Move to new stack
subq %rdx, %rcx // Calc offset of stack in Temp Memory
addq %r8, %rcx // Calc PermanentMemoryBase address
movq %rcx, %rsp // Update stack
// Stack now points to permanent memory
// ZeroMem (TemporaryMemoryBase /* rdi */, CopySize /* rsi */);
movq %rdx, %rdi
movq %r9, %rsi
call ASM_PFX(ZeroMem)
// This data comes off the NEW stack
popq %rdi
popq %rsi
popq %rbp
ret

View File

@@ -110,15 +110,27 @@
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
[LibraryClasses.common.SEC]
PeiServicesLib|InOsEmuPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PeCoffGetEntryPointLib|InOsEmuPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf
PeCoffExtraActionLib|InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf
SerialPortLib|InOsEmuPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
PpiListLib|InOsEmuPkg/Library/SecPpiListLib/SecPpiListLib.inf
[LibraryClasses.common.USER_DEFINED, LibraryClasses.common.BASE]
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
PpiListLib|InOsEmuPkg/Library/SecPpiListLib/SecPpiListLib.inf
ThunkPpiList|InOsEmuPkg/Library/ThunkPpiList/ThunkPpiList.inf
ThunkProtocolList|InOsEmuPkg/Library/ThunkProtocolList/ThunkProtocolList.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
PpiListLib|InOsEmuPkg/Library/SecPpiListLib/SecPpiListLib.inf
PeiServicesLib|InOsEmuPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf
# PeCoffExtraActionLib|InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf
[LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
@@ -128,11 +140,11 @@
PeCoffGetEntryPointLib|InOsEmuPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf
PeCoffExtraActionLib|InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf
ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
SerialPortLib|InOsEmuPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
[LibraryClasses.common.PEI_CORE]
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PeiServicesTablePointerLib|InOsEmuPkg/Library/PeiCoreServicesTablePointerLib/PeiCoreServicesTablePointerLib.inf
SerialPortLib|InOsEmuPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
[LibraryClasses.common.PEIM]
PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
@@ -252,6 +264,11 @@
##
InOsEmuPkg/Unix/Sec/SecMain.inf
!else
#
# Generic SEC
#
InOsEmuPkg/Sec/Sec.inf
##
# PEI Phase modules
##
@@ -261,10 +278,7 @@
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
}
MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf {
<LibraryClasses>
SerialPortLib|InOsEmuPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
}
MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
InOsEmuPkg/BootModePei/BootModePei.inf

View File

@@ -167,6 +167,7 @@ APRIORI DXE {
INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
INF InOsEmuPkg/MetronomeDxe/Metronome.inf
}
INF InOsEmuPkg/Sec/Sec.inf
INF MdeModulePkg/Core/Pei/PeiMain.inf
INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
@@ -293,6 +294,13 @@ FILE FREEFORM = PCD(gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile) {
# }
#
############################################################################
[Rule.Common.SEC]
FILE SEC = $(NAMED_GUID) {
PE32 PE32 Align=32 $(INF_OUTPUT)/$(MODULE_NAME).efi
UI STRING ="$(MODULE_NAME)" Optional
VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
}
[Rule.Common.PEI_CORE]
FILE PEI_CORE = $(NAMED_GUID) {