--- /dev/null
+/** @file\r
+ PEI Services Table Pointer Library.\r
+ \r
+ This library is used for PEIM which does executed from flash device directly but\r
+ executed in memory.\r
+\r
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+ Portiions copyrigth (c) 2011, Apple Inc. All rights reserved. \r
+ 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
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Library/PeiServicesTablePointerLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+#include <Ppi/EmuPeiServicesTableUpdate.h>\r
+\r
+\r
+CONST EFI_PEI_SERVICES **gPeiServices = NULL;\r
+\r
+/**\r
+ Caches a pointer PEI Services Table. \r
+ \r
+ Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer \r
+ in a CPU specific manner as specified in the CPU binding section of the Platform Initialization \r
+ Pre-EFI Initialization Core Interface Specification. \r
+ \r
+ If PeiServicesTablePointer is NULL, then ASSERT().\r
+ \r
+ @param PeiServicesTablePointer The address of PeiServices pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetPeiServicesTablePointer (\r
+ IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer\r
+ )\r
+{\r
+ ASSERT (PeiServicesTablePointer != NULL);\r
+ ASSERT (*PeiServicesTablePointer != NULL);\r
+ gPeiServices = PeiServicesTablePointer;\r
+}\r
+\r
+/**\r
+ Retrieves the cached value of the PEI Services Table pointer.\r
+\r
+ Returns the cached value of the PEI Services Table pointer in a CPU specific manner \r
+ as specified in the CPU binding section of the Platform Initialization Pre-EFI \r
+ Initialization Core Interface Specification.\r
+ \r
+ If the cached PEI Services Table pointer is NULL, then ASSERT().\r
+\r
+ @return The pointer to PeiServices.\r
+\r
+**/\r
+CONST EFI_PEI_SERVICES **\r
+EFIAPI\r
+GetPeiServicesTablePointer (\r
+ VOID\r
+ )\r
+{\r
+ ASSERT (gPeiServices != NULL);\r
+ ASSERT (*gPeiServices != NULL);\r
+ return gPeiServices;\r
+}\r
+\r
+\r
+\r
+/**\r
+ Notification service to be called when gEmuThunkPpiGuid is installed.\r
+\r
+ @param PeiServices Indirect reference to the PEI Services Table.\r
+ @param NotifyDescriptor Address of the notification descriptor data structure. Type\r
+ EFI_PEI_NOTIFY_DESCRIPTOR is defined above.\r
+ @param Ppi Address of the PPI that was installed.\r
+\r
+ @retval EFI_STATUS This function will install a PPI to PPI database. The status\r
+ code will be the code for (*PeiServices)->InstallPpi.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeiServicesTablePointerNotifyCallback (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
+ IN VOID *Ppi\r
+ )\r
+{\r
+ gPeiServices = (CONST EFI_PEI_SERVICES **)PeiServices;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnThunkList = {\r
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+ &gEmuPeiServicesTableUpdatePpiGuid,\r
+ PeiServicesTablePointerNotifyCallback \r
+};\r
+\r
+\r
+/**\r
+ Constructor register notification on when PPI updates. If PPI is \r
+ alreay installed registering the notify will cause the handle to \r
+ run.\r
+\r
+ @param FileHandle The handle of FFS header the loaded driver.\r
+ @param PeiServices The pointer to the PEI services.\r
+\r
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeiServicesTablePointerLibConstructor (\r
+ IN EFI_PEI_FILE_HANDLE FileHandle,\r
+ IN CONST EFI_PEI_SERVICES **PeiServices\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ // register to be told when PeiServices pointer is updated\r
+ Status = (*PeiServices)->NotifyPpi (PeiServices, &mNotifyOnThunkList);\r
+ ASSERT_EFI_ERROR (Status);\r
+ return Status;\r
+}\r
+\r
+\r