InOsEmuPkg: Make XIP work properly

Update the InOsEmuPkg to properly function with XIP. Make the Recovery FV read only. Remove the use of global variable writes from XIP code. Add a new global page that can be used in place of writting to the FD by XIP code. Think of this global page as a system SRAM. 

igned-off-by: andrewfish



git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11771 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
andrewfish 2011-06-08 21:52:21 +00:00
parent f65dc3bebd
commit 946bfba2c3
15 changed files with 242 additions and 24 deletions

View File

@ -64,8 +64,12 @@
gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareFdSize|0x0|UINT32|0x00001012 gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareFdSize|0x0|UINT32|0x00001012
gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareBlockSize|0|UINT32|0x00001013 gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareBlockSize|0|UINT32|0x00001013
## Number of Application Processors (APs) in the system 0 means Uniprocessor mode
gInOsEmuPkgTokenSpaceGuid.PcdEmuApCount|L"0"|VOID*|0x00001019 gInOsEmuPkgTokenSpaceGuid.PcdEmuApCount|L"0"|VOID*|0x00001019
## Magic page to implement PEI Services Table Pointer Lib
gInOsEmuPkgTokenSpaceGuid.PcdPeiServicesTablePage|0x1000000000|UINT64|0x0000101b
[PcdsFixedAtBuild, PcdsPatchableInModule] [PcdsFixedAtBuild, PcdsPatchableInModule]
gInOsEmuPkgTokenSpaceGuid.PcdEmuBootMode|1|UINT32|0x00001006 gInOsEmuPkgTokenSpaceGuid.PcdEmuBootMode|1|UINT32|0x00001006
gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareVolume|L"..\\Fv\\Fv_Recovery.fd"|VOID*|0x00001009 gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareVolume|L"..\\Fv\\Fv_Recovery.fd"|VOID*|0x00001009

View File

@ -0,0 +1,38 @@
/*++ @file
The PCD, gInOsEmuPkgTokenSpaceGuid.PcdPeiServicesTablePage, points to a magic page
of memory that is like SRAM on an embedded system. This file defines what goes
where in the magic page.
Copyright (c) 2011, Apple Inc. 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.
**/
#ifndef __EMU_MAGIC_PAGE_LIB_H__
#define __EMU_MAGIC_PAGE_LIB_H__
#include <PiPei.h>
#include <Library/PcdLib.h>
#include <Protocol/EmuThunk.h>
typedef struct {
// Used by PEI Core and PEIMs to store the PEI Services pointer.
// Privilege issues prevent using the PI mechanism in the emulator.
CONST EFI_PEI_SERVICES **PeiServicesTablePointer;
// Used by SecPeiServicesLib
EFI_PEI_PPI_DESCRIPTOR *PpiList;
// Needed by PEI PEI PeCoffLoaderExtraActionLib
EMU_THUNK_PROTOCOL *Thunk;
} EMU_MAGIC_PAGE_LAYOUT;
#define EMU_MAGIC_PAGE() ((EMU_MAGIC_PAGE_LAYOUT *)((UINTN)PcdGet64 (PcdPeiServicesTablePage)))
#endif

View File

@ -23,6 +23,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/BaseLib.h> #include <Library/BaseLib.h>
#include <Library/PeCoffExtraActionLib.h> #include <Library/PeCoffExtraActionLib.h>
#include <Library/EmuMagicPageLib.h>
// //
// Cache of UnixThunk protocol // Cache of UnixThunk protocol
@ -56,7 +57,7 @@ EmuPeCoffGetThunkStucture (
); );
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
mThunk = (EMU_THUNK_PROTOCOL *) ThunkPpi->Thunk (); EMU_MAGIC_PAGE()->Thunk = (EMU_THUNK_PROTOCOL *) ThunkPpi->Thunk ();
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -76,10 +77,10 @@ PeCoffLoaderRelocateImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
) )
{ {
if (mThunk == NULL) { if (EMU_MAGIC_PAGE()->Thunk == NULL) {
EmuPeCoffGetThunkStucture (); EmuPeCoffGetThunkStucture ();
} }
mThunk->PeCoffRelocateImageExtraAction (ImageContext); EMU_MAGIC_PAGE()->Thunk->PeCoffRelocateImageExtraAction (ImageContext);
} }
@ -99,8 +100,8 @@ PeCoffLoaderUnloadImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
) )
{ {
if (mThunk == NULL) { if (EMU_MAGIC_PAGE()->Thunk == NULL) {
EmuPeCoffGetThunkStucture (); EmuPeCoffGetThunkStucture ();
} }
mThunk->PeCoffUnloadImageExtraAction (ImageContext); EMU_MAGIC_PAGE()->Thunk->PeCoffUnloadImageExtraAction (ImageContext);
} }

View File

@ -44,3 +44,6 @@
[Ppis] [Ppis]
gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED
[Pcd]
gInOsEmuPkgTokenSpaceGuid.PcdPeiServicesTablePage

View File

@ -0,0 +1,75 @@
/** @file
PEI Services Table Pointer Library.
Store PEI Services Table pointer via gInOsEmuPkgTokenSpaceGuid.PcdPeiServicesTablePage.
This emulates a platform SRAM. The PI mechaism does not work in the emulator due to
lack of privledge.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
Portiions copyrigth (c) 2011, Apple Inc. All rights reserved.
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 <PiPei.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/DebugLib.h>
#include <Library/EmuMagicPageLib.h>
/**
Caches a pointer PEI Services Table.
Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer
in a CPU specific manner as specified in the CPU binding section of the Platform Initialization
Pre-EFI Initialization Core Interface Specification.
If PeiServicesTablePointer is NULL, then ASSERT().
@param PeiServicesTablePointer The address of PeiServices pointer.
**/
VOID
EFIAPI
SetPeiServicesTablePointer (
IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer
)
{
ASSERT (PeiServicesTablePointer != NULL);
ASSERT (*PeiServicesTablePointer != NULL);
EMU_MAGIC_PAGE()->PeiServicesTablePointer = PeiServicesTablePointer;
}
/**
Retrieves the cached value of the PEI Services Table pointer.
Returns the cached value of the PEI Services Table pointer in a CPU specific manner
as specified in the CPU binding section of the Platform Initialization Pre-EFI
Initialization Core Interface Specification.
If the cached PEI Services Table pointer is NULL, then ASSERT().
@return The pointer to PeiServices.
**/
CONST EFI_PEI_SERVICES **
EFIAPI
GetPeiServicesTablePointer (
VOID
)
{
CONST EFI_PEI_SERVICES **PeiServicesTablePointer;
PeiServicesTablePointer = EMU_MAGIC_PAGE()->PeiServicesTablePointer;
ASSERT (PeiServicesTablePointer != NULL);
ASSERT (*PeiServicesTablePointer != NULL);
return PeiServicesTablePointer;
}

View File

@ -0,0 +1,44 @@
## @file
# PEI Services Table Pointer Library.
#
# Store PEI Services Table pointer via gInOsEmuPkgTokenSpaceGuid.PcdPeiServicesTablePage.
# This emulates a platform SRAM. The PI mechaism does not work in the emulator due to
# lack of privledge.
#
# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2011, Apple Inc. All rights reserved.
#
# 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.
#
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = InOsEmuPkgPeiServicesTablePointerLib
FILE_GUID = 7488FC06-370A-1C41-B05C-7395559A535A
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
LIBRARY_CLASS = PeiServicesTablePointerLib|PEIM PEI_CORE SEC
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC (EBC is for build only)
#
[Sources]
PeiServicesTablePointer.c
[Packages]
MdePkg/MdePkg.dec
InOsEmuPkg/InOsEmuPkg.dec
[LibraryClasses]
DebugLib
[Pcd]
gInOsEmuPkgTokenSpaceGuid.PcdPeiServicesTablePage

View File

@ -14,11 +14,10 @@
#include <PiPei.h> #include <PiPei.h>
#include <Library/EmuMagicPageLib.h>
#include <Library/PeiServicesLib.h> #include <Library/PeiServicesLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/PpiListLib.h>
@ -116,8 +115,7 @@ PeiServicesLocatePpi (
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
} }
for (PpiList = EMU_MAGIC_PAGE()->PpiList; ; PpiList++) {
for (PpiList = (EFI_PEI_PPI_DESCRIPTOR *)gPpiList; ; PpiList++) {
if (CompareGuid (PpiList->Guid, Guid)) { if (CompareGuid (PpiList->Guid, Guid)) {
if (PpiDescriptor != NULL) { if (PpiDescriptor != NULL) {
*PpiDescriptor = PpiList; *PpiDescriptor = PpiList;

View File

@ -40,6 +40,10 @@
BaseMemoryLib BaseMemoryLib
PpiListLib PpiListLib
[Pcd]
gInOsEmuPkgTokenSpaceGuid.PcdPeiServicesTablePage

View File

@ -82,7 +82,7 @@ _ModuleEntryPoint (
UINTN SecReseveredMemorySize; UINTN SecReseveredMemorySize;
UINTN Index; UINTN Index;
gPpiList = PpiList; EMU_MAGIC_PAGE()->PpiList = PpiList;
ProcessLibraryConstructorList (); ProcessLibraryConstructorList ();
DEBUG ((EFI_D_ERROR, "SEC Has Started\n")); DEBUG ((EFI_D_ERROR, "SEC Has Started\n"));

View File

@ -19,11 +19,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <PiPei.h> #include <PiPei.h>
#include <Library/EmuMagicPageLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/PeiServicesLib.h> #include <Library/PeiServicesLib.h>
#include <Library/PeCoffGetEntryPointLib.h> #include <Library/PeCoffGetEntryPointLib.h>
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/PpiListLib.h>
#include <Ppi/TemporaryRamSupport.h> #include <Ppi/TemporaryRamSupport.h>

View File

@ -42,3 +42,5 @@
[Ppis] [Ppis]
gEfiTemporaryRamSupportPpiGuid gEfiTemporaryRamSupportPpiGuid
[Pcd]
gInOsEmuPkgTokenSpaceGuid.PcdPeiServicesTablePage

View File

@ -57,7 +57,7 @@ EMU_SYSTEM_MEMORY *gSystemMemory;
UINTN mImageContextModHandleArraySize = 0; UINTN mImageContextModHandleArraySize = 0;
IMAGE_CONTEXT_TO_MOD_HANDLE *mImageContextModHandleArray = NULL; IMAGE_CONTEXT_TO_MOD_HANDLE *mImageContextModHandleArray = NULL;
EFI_PEI_PPI_DESCRIPTOR *gPpiList;
/*++ /*++
@ -127,7 +127,6 @@ main (
// EmuSecLibConstructor (); // EmuSecLibConstructor ();
gPpiList = GetThunkPpiList (); gPpiList = GetThunkPpiList ();
@ -371,7 +370,7 @@ MapFile (
FileSize = lseek (fd, 0, SEEK_END); 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_EXEC, MAP_PRIVATE);
close (fd); close (fd);
@ -394,9 +393,10 @@ MapFd0 (
) )
{ {
int fd; int fd;
VOID *res, *res2; void *res, *res2, *res3;
UINTN FileSize; UINTN FileSize;
UINTN FvSize; UINTN FvSize;
void *EmuMagicPage;
fd = open (FileName, O_RDWR); fd = open (FileName, O_RDWR);
if (fd < 0) { if (fd < 0) {
@ -407,6 +407,21 @@ MapFd0 (
FvSize = FixedPcdGet64 (PcdEmuFlashFvRecoverySize); FvSize = FixedPcdGet64 (PcdEmuFlashFvRecoverySize);
// Assume start of FD is Recovery FV, and make it write protected // Assume start of FD is Recovery FV, and make it write protected
res = mmap (
(void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase),
FvSize,
PROT_READ | PROT_EXEC,
MAP_PRIVATE,
fd,
0
);
if (res == MAP_FAILED) {
perror ("MapFd0() Failed res =");
close (fd);
return EFI_DEVICE_ERROR;
} else if (res != (void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase)) {
// We could not load at the build address, so we need to allow writes
munmap (res, FvSize);
res = mmap ( res = mmap (
(void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase), (void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase),
FvSize, FvSize,
@ -416,10 +431,11 @@ MapFd0 (
0 0
); );
if (res == MAP_FAILED) { if (res == MAP_FAILED) {
perror ("MapFile() Failed res ="); perror ("MapFd0() Failed res =");
close (fd); close (fd);
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
}
// Map the rest of the FD as read/write // Map the rest of the FD as read/write
res2 = mmap ( res2 = mmap (
@ -432,10 +448,32 @@ MapFd0 (
); );
close (fd); close (fd);
if (res2 == MAP_FAILED) { if (res2 == MAP_FAILED) {
perror ("MapFile() Failed res2 ="); perror ("MapFd0() Failed res2 =");
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
//
// If enabled use the magic page to communicate between modules
// This replaces the PI PeiServicesTable pointer mechanism that
// deos not work in the emulator. It also allows the removal of
// writable globals from SEC, PEI_CORE (libraries), PEIMs
//
EmuMagicPage = (void *)(UINTN)FixedPcdGet64 (PcdPeiServicesTablePage);
if (EmuMagicPage != NULL) {
res3 = mmap (
(void *)EmuMagicPage,
4096,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
0,
0
);
if (res3 != EmuMagicPage) {
printf ("MapFd0(): Could not allocate PeiServicesTablePage @ %lx\n", (long unsigned int)EmuMagicPage);
return EFI_DEVICE_ERROR;
}
}
*Length = (UINT64) FileSize; *Length = (UINT64) FileSize;
*BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) res; *BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) res;
@ -631,6 +669,7 @@ SecPeCoffGetEntryPoint (
return Status; return Status;
} }
if (ImageContext.ImageAddress != (UINTN)Pe32Data) {
// //
// Relocate image to match the address where it resides // Relocate image to match the address where it resides
// //
@ -644,6 +683,17 @@ SecPeCoffGetEntryPoint (
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
} else {
//
// Or just return image entry point
//
ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer (Pe32Data);
Status = PeCoffLoaderGetEntryPoint (Pe32Data, EntryPoint);
if (EFI_ERROR (Status)) {
return Status;
}
ImageContext.EntryPoint = (UINTN)*EntryPoint;
}
// On Unix a dlopen is done that will change the entry point // On Unix a dlopen is done that will change the entry point
SecPeCoffRelocateImageExtraAction (&ImageContext); SecPeCoffRelocateImageExtraAction (&ImageContext);

View File

@ -29,9 +29,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/ThunkPpiList.h> #include <Library/ThunkPpiList.h>
#include <Library/ThunkProtocolList.h> #include <Library/ThunkProtocolList.h>
#include <Library/PpiListLib.h>
#include <Library/PeiServicesLib.h> #include <Library/PeiServicesLib.h>
#include <Library/PeCoffGetEntryPointLib.h> #include <Library/PeCoffGetEntryPointLib.h>
#include <Library/EmuMagicPageLib.h>
#include <Ppi/EmuThunk.h> #include <Ppi/EmuThunk.h>
#include <Ppi/StatusCode.h> #include <Ppi/StatusCode.h>

View File

@ -101,7 +101,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwSpareBase gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwSpareBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
gInOsEmuPkgTokenSpaceGuid.PcdPeiServicesTablePage
[BuildOptions] [BuildOptions]

View File

@ -109,7 +109,8 @@
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
##### DevicePathTextLib|InOsEmuPkg/Library/DevicePathTextLib/DevicePathTextLib.inf #### DevicePathTextLib|InOsEmuPkg/Library/DevicePathTextLib/DevicePathTextLib.inf
PeiServicesTablePointerLib|InOsEmuPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointerLibMagicPage.inf
[LibraryClasses.common.SEC] [LibraryClasses.common.SEC]
PeiServicesLib|InOsEmuPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf PeiServicesLib|InOsEmuPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf
@ -145,11 +146,9 @@
[LibraryClasses.common.PEI_CORE] [LibraryClasses.common.PEI_CORE]
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PeiServicesTablePointerLib|InOsEmuPkg/Library/PeiCoreServicesTablePointerLib/PeiCoreServicesTablePointerLib.inf
[LibraryClasses.common.PEIM] [LibraryClasses.common.PEIM]
PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
PeiServicesTablePointerLib|InOsEmuPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
[LibraryClasses.common.DXE_CORE] [LibraryClasses.common.DXE_CORE]
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf