From 946bfba2c321425f22fecb53349b779594543919 Mon Sep 17 00:00:00 2001 From: andrewfish Date: Wed, 8 Jun 2011 21:52:21 +0000 Subject: [PATCH] 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 --- InOsEmuPkg/InOsEmuPkg.dec | 4 + InOsEmuPkg/Include/Library/EmuMagicPageLib.h | 38 ++++++++++ .../PeiEmuPeCoffExtraActionLib.c | 11 +-- .../PeiEmuPeCoffExtraActionLib.inf | 3 + .../PeiServicesTablePointer.c | 75 +++++++++++++++++++ .../PeiServicesTablePointerLibMagicPage.inf | 44 +++++++++++ .../SecPeiServicesLib/PeiServicesLib.c | 6 +- .../SecPeiServicesLib/SecPeiServicesLib.inf | 4 + InOsEmuPkg/Sec/Sec.c | 2 +- InOsEmuPkg/Sec/Sec.h | 2 +- InOsEmuPkg/Sec/Sec.inf | 4 +- InOsEmuPkg/Unix/Sec/SecMain.c | 64 ++++++++++++++-- InOsEmuPkg/Unix/Sec/SecMain.h | 2 +- InOsEmuPkg/Unix/Sec/SecMain.inf | 2 +- InOsEmuPkg/Unix/UnixX64.dsc | 5 +- 15 files changed, 242 insertions(+), 24 deletions(-) create mode 100644 InOsEmuPkg/Include/Library/EmuMagicPageLib.h create mode 100644 InOsEmuPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointer.c create mode 100644 InOsEmuPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointerLibMagicPage.inf diff --git a/InOsEmuPkg/InOsEmuPkg.dec b/InOsEmuPkg/InOsEmuPkg.dec index e476dd20f0..14983ecbda 100644 --- a/InOsEmuPkg/InOsEmuPkg.dec +++ b/InOsEmuPkg/InOsEmuPkg.dec @@ -64,8 +64,12 @@ gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareFdSize|0x0|UINT32|0x00001012 gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareBlockSize|0|UINT32|0x00001013 + ## Number of Application Processors (APs) in the system 0 means Uniprocessor mode gInOsEmuPkgTokenSpaceGuid.PcdEmuApCount|L"0"|VOID*|0x00001019 + ## Magic page to implement PEI Services Table Pointer Lib + gInOsEmuPkgTokenSpaceGuid.PcdPeiServicesTablePage|0x1000000000|UINT64|0x0000101b + [PcdsFixedAtBuild, PcdsPatchableInModule] gInOsEmuPkgTokenSpaceGuid.PcdEmuBootMode|1|UINT32|0x00001006 gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareVolume|L"..\\Fv\\Fv_Recovery.fd"|VOID*|0x00001009 diff --git a/InOsEmuPkg/Include/Library/EmuMagicPageLib.h b/InOsEmuPkg/Include/Library/EmuMagicPageLib.h new file mode 100644 index 0000000000..03dfcacd7a --- /dev/null +++ b/InOsEmuPkg/Include/Library/EmuMagicPageLib.h @@ -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.
+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 +#include +#include + +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 diff --git a/InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c b/InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c index b88bd009fe..b398b53e51 100644 --- a/InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c +++ b/InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c @@ -23,6 +23,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include // // Cache of UnixThunk protocol @@ -56,7 +57,7 @@ EmuPeCoffGetThunkStucture ( ); ASSERT_EFI_ERROR (Status); - mThunk = (EMU_THUNK_PROTOCOL *) ThunkPpi->Thunk (); + EMU_MAGIC_PAGE()->Thunk = (EMU_THUNK_PROTOCOL *) ThunkPpi->Thunk (); return EFI_SUCCESS; } @@ -76,10 +77,10 @@ PeCoffLoaderRelocateImageExtraAction ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext ) { - if (mThunk == NULL) { + if (EMU_MAGIC_PAGE()->Thunk == NULL) { EmuPeCoffGetThunkStucture (); } - mThunk->PeCoffRelocateImageExtraAction (ImageContext); + EMU_MAGIC_PAGE()->Thunk->PeCoffRelocateImageExtraAction (ImageContext); } @@ -99,8 +100,8 @@ PeCoffLoaderUnloadImageExtraAction ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext ) { - if (mThunk == NULL) { + if (EMU_MAGIC_PAGE()->Thunk == NULL) { EmuPeCoffGetThunkStucture (); } - mThunk->PeCoffUnloadImageExtraAction (ImageContext); + EMU_MAGIC_PAGE()->Thunk->PeCoffUnloadImageExtraAction (ImageContext); } diff --git a/InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf b/InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf index 3fd4a8aefe..e4a3fa7df6 100644 --- a/InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf +++ b/InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf @@ -44,3 +44,6 @@ [Ppis] gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED + +[Pcd] + gInOsEmuPkgTokenSpaceGuid.PcdPeiServicesTablePage diff --git a/InOsEmuPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointer.c b/InOsEmuPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointer.c new file mode 100644 index 0000000000..3f15403c72 --- /dev/null +++ b/InOsEmuPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointer.c @@ -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.
+ 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 +#include +#include +#include + + +/** + 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; +} + + + diff --git a/InOsEmuPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointerLibMagicPage.inf b/InOsEmuPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointerLibMagicPage.inf new file mode 100644 index 0000000000..d16b845a8b --- /dev/null +++ b/InOsEmuPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointerLibMagicPage.inf @@ -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.
+# 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 diff --git a/InOsEmuPkg/Library/SecPeiServicesLib/PeiServicesLib.c b/InOsEmuPkg/Library/SecPeiServicesLib/PeiServicesLib.c index cee715d876..bdbf6875c9 100644 --- a/InOsEmuPkg/Library/SecPeiServicesLib/PeiServicesLib.c +++ b/InOsEmuPkg/Library/SecPeiServicesLib/PeiServicesLib.c @@ -14,11 +14,10 @@ #include - +#include #include #include #include -#include @@ -116,8 +115,7 @@ PeiServicesLocatePpi ( return EFI_NOT_FOUND; } - - for (PpiList = (EFI_PEI_PPI_DESCRIPTOR *)gPpiList; ; PpiList++) { + for (PpiList = EMU_MAGIC_PAGE()->PpiList; ; PpiList++) { if (CompareGuid (PpiList->Guid, Guid)) { if (PpiDescriptor != NULL) { *PpiDescriptor = PpiList; diff --git a/InOsEmuPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf b/InOsEmuPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf index 6e9cf3a226..3fc6271b08 100644 --- a/InOsEmuPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf +++ b/InOsEmuPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf @@ -40,6 +40,10 @@ BaseMemoryLib PpiListLib +[Pcd] + gInOsEmuPkgTokenSpaceGuid.PcdPeiServicesTablePage + + diff --git a/InOsEmuPkg/Sec/Sec.c b/InOsEmuPkg/Sec/Sec.c index 4e350f1706..4468d6f07b 100644 --- a/InOsEmuPkg/Sec/Sec.c +++ b/InOsEmuPkg/Sec/Sec.c @@ -82,7 +82,7 @@ _ModuleEntryPoint ( UINTN SecReseveredMemorySize; UINTN Index; - gPpiList = PpiList; + EMU_MAGIC_PAGE()->PpiList = PpiList; ProcessLibraryConstructorList (); DEBUG ((EFI_D_ERROR, "SEC Has Started\n")); diff --git a/InOsEmuPkg/Sec/Sec.h b/InOsEmuPkg/Sec/Sec.h index d0bc9e176e..00760121b2 100644 --- a/InOsEmuPkg/Sec/Sec.h +++ b/InOsEmuPkg/Sec/Sec.h @@ -19,11 +19,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include +#include #include #include #include #include -#include #include diff --git a/InOsEmuPkg/Sec/Sec.inf b/InOsEmuPkg/Sec/Sec.inf index b09785af40..c263f9db2b 100644 --- a/InOsEmuPkg/Sec/Sec.inf +++ b/InOsEmuPkg/Sec/Sec.inf @@ -41,4 +41,6 @@ [Ppis] gEfiTemporaryRamSupportPpiGuid - \ No newline at end of file + +[Pcd] + gInOsEmuPkgTokenSpaceGuid.PcdPeiServicesTablePage diff --git a/InOsEmuPkg/Unix/Sec/SecMain.c b/InOsEmuPkg/Unix/Sec/SecMain.c index 1771f36132..5dcb44523e 100644 --- a/InOsEmuPkg/Unix/Sec/SecMain.c +++ b/InOsEmuPkg/Unix/Sec/SecMain.c @@ -57,7 +57,7 @@ EMU_SYSTEM_MEMORY *gSystemMemory; UINTN mImageContextModHandleArraySize = 0; IMAGE_CONTEXT_TO_MOD_HANDLE *mImageContextModHandleArray = NULL; - +EFI_PEI_PPI_DESCRIPTOR *gPpiList; /*++ @@ -127,7 +127,6 @@ main ( // EmuSecLibConstructor (); - gPpiList = GetThunkPpiList (); @@ -371,7 +370,7 @@ MapFile ( 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); @@ -394,9 +393,10 @@ MapFd0 ( ) { int fd; - VOID *res, *res2; + void *res, *res2, *res3; UINTN FileSize; UINTN FvSize; + void *EmuMagicPage; fd = open (FileName, O_RDWR); if (fd < 0) { @@ -410,15 +410,31 @@ MapFd0 ( res = mmap ( (void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase), FvSize, - PROT_READ | PROT_WRITE | PROT_EXEC, + PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0 ); if (res == MAP_FAILED) { - perror ("MapFile() Failed res ="); + 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 ( + (void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase), + FvSize, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE, + fd, + 0 + ); + if (res == MAP_FAILED) { + perror ("MapFd0() Failed res ="); + close (fd); + return EFI_DEVICE_ERROR; + } } // Map the rest of the FD as read/write @@ -432,10 +448,32 @@ MapFd0 ( ); close (fd); if (res2 == MAP_FAILED) { - perror ("MapFile() Failed res2 ="); + perror ("MapFd0() Failed res2 ="); 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; *BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) res; @@ -631,6 +669,7 @@ SecPeCoffGetEntryPoint ( return Status; } + if (ImageContext.ImageAddress != (UINTN)Pe32Data) { // // Relocate image to match the address where it resides // @@ -644,6 +683,17 @@ SecPeCoffGetEntryPoint ( if (EFI_ERROR (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 SecPeCoffRelocateImageExtraAction (&ImageContext); diff --git a/InOsEmuPkg/Unix/Sec/SecMain.h b/InOsEmuPkg/Unix/Sec/SecMain.h index af88d06837..cbe98de648 100644 --- a/InOsEmuPkg/Unix/Sec/SecMain.h +++ b/InOsEmuPkg/Unix/Sec/SecMain.h @@ -29,9 +29,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include -#include #include #include +#include #include #include diff --git a/InOsEmuPkg/Unix/Sec/SecMain.inf b/InOsEmuPkg/Unix/Sec/SecMain.inf index 0e494e76bb..da4714e2a6 100644 --- a/InOsEmuPkg/Unix/Sec/SecMain.inf +++ b/InOsEmuPkg/Unix/Sec/SecMain.inf @@ -101,7 +101,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwSpareBase gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize - + gInOsEmuPkgTokenSpaceGuid.PcdPeiServicesTablePage [BuildOptions] diff --git a/InOsEmuPkg/Unix/UnixX64.dsc b/InOsEmuPkg/Unix/UnixX64.dsc index 8bb1391af9..ce9b088f2a 100644 --- a/InOsEmuPkg/Unix/UnixX64.dsc +++ b/InOsEmuPkg/Unix/UnixX64.dsc @@ -109,7 +109,8 @@ DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.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] PeiServicesLib|InOsEmuPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf @@ -145,11 +146,9 @@ [LibraryClasses.common.PEI_CORE] PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf - PeiServicesTablePointerLib|InOsEmuPkg/Library/PeiCoreServicesTablePointerLib/PeiCoreServicesTablePointerLib.inf [LibraryClasses.common.PEIM] PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf - PeiServicesTablePointerLib|InOsEmuPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf [LibraryClasses.common.DXE_CORE] HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf -- 2.39.2