Add PeiCore module for enabling NT32Pkg, please attention this PeiCore does follows...
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 4 Jul 2007 07:51:48 +0000 (07:51 +0000)
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 4 Jul 2007 07:51:48 +0000 (07:51 +0000)
Also the old definition of MdeModulePkg/Include/Ppi/LoadFile.h and EFI_PEI_STARTUP_DESCRIPTOR in MdePkg/Include/PiPei.h will be removed when enabling PI.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3029 6f19259b-4bc3-4df7-8a09-765794883524

30 files changed:
IntelFrameworkPkg/Include/FrameworkPei.h
MdeModulePkg/Core/Pei/BootMode/BootMode.c [new file with mode: 0644]
MdeModulePkg/Core/Pei/CommonHeader.h [new file with mode: 0644]
MdeModulePkg/Core/Pei/Dependency/dependency.c [new file with mode: 0644]
MdeModulePkg/Core/Pei/Dependency/dependency.h [new file with mode: 0644]
MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c [new file with mode: 0644]
MdeModulePkg/Core/Pei/Dispatcher/Stack.c [new file with mode: 0644]
MdeModulePkg/Core/Pei/FwVol/FwVol.c [new file with mode: 0644]
MdeModulePkg/Core/Pei/Hob/Hob.c [new file with mode: 0644]
MdeModulePkg/Core/Pei/Image/Image.c [new file with mode: 0644]
MdeModulePkg/Core/Pei/Ipf/IpfCpuCore.i [new file with mode: 0644]
MdeModulePkg/Core/Pei/Ipf/IpfCpuCore.s [new file with mode: 0644]
MdeModulePkg/Core/Pei/Ipf/IpfPeiMain.h [new file with mode: 0644]
MdeModulePkg/Core/Pei/Ipf/Stack.c [new file with mode: 0644]
MdeModulePkg/Core/Pei/Ipf/SwitchToCacheMode.c [new file with mode: 0644]
MdeModulePkg/Core/Pei/Memory/MemoryServices.c [new file with mode: 0644]
MdeModulePkg/Core/Pei/PeiMain.h [new file with mode: 0644]
MdeModulePkg/Core/Pei/PeiMain.inf [new file with mode: 0644]
MdeModulePkg/Core/Pei/PeiMain.msa [new file with mode: 0644]
MdeModulePkg/Core/Pei/PeiMain/PeiMain.c [new file with mode: 0644]
MdeModulePkg/Core/Pei/Ppi/Ppi.c [new file with mode: 0644]
MdeModulePkg/Core/Pei/Reset/Reset.c [new file with mode: 0644]
MdeModulePkg/Core/Pei/Security/Security.c [new file with mode: 0644]
MdeModulePkg/Core/Pei/StatusCode/StatusCode.c [new file with mode: 0644]
MdeModulePkg/Include/Ppi/LoadFile.h [new file with mode: 0644]
MdeModulePkg/MdeModulePkg.dec
MdeModulePkg/MdeModulePkg.dsc
MdePkg/Include/PiPei.h
Nt32Pkg/Library/EdkNt32PeiPeCoffGetEntryPointLib/CommonHeader.h
Nt32Pkg/Nt32Pkg.dsc

index 7f61e81..43ce1ab 100644 (file)
 \r
 #include <PiPei.h>\r
 \r
-typedef struct {\r
-  UINTN                   BootFirmwareVolume;\r
-  UINTN                   SizeOfCacheAsRam;\r
-  EFI_PEI_PPI_DESCRIPTOR  *DispatchTable;\r
-} EFI_PEI_STARTUP_DESCRIPTOR;\r
-\r
 #include <Common/FrameworkFirmwareFileSystem.h>\r
 #include <Common/FrameworkHob.h>\r
 #include <Common/FrameworkLegacy16.h>\r
diff --git a/MdeModulePkg/Core/Pei/BootMode/BootMode.c b/MdeModulePkg/Core/Pei/BootMode/BootMode.c
new file mode 100644 (file)
index 0000000..0576ab0
--- /dev/null
@@ -0,0 +1,111 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  BootMode.c\r
+\r
+Abstract:\r
+\r
+  EFI PEI Core Boot Mode services\r
+\r
+\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <PeiMain.h>\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiGetBootMode (\r
+  IN EFI_PEI_SERVICES  **PeiServices,\r
+  OUT EFI_BOOT_MODE *BootMode\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This service enables PEIMs to ascertain the present value of the boot mode.  \r
+\r
+Arguments:\r
+\r
+  PeiServices    - The PEI core services table.\r
+  BootMode       - A pointer to contain the value of the boot mode. \r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The boot mode was returned successfully.\r
+  EFI_INVALID_PARAMETER - BootMode is NULL.\r
+\r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE                    *PrivateData;    \r
+  EFI_HOB_HANDOFF_INFO_TABLE    *HandOffHob;\r
+\r
+\r
+  if (BootMode == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
+  \r
+  HandOffHob  = (PrivateData->HobList.HandoffInformationTable);\r
+  \r
+  *BootMode   = HandOffHob->BootMode;\r
+  \r
+\r
+  return EFI_SUCCESS;   \r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiSetBootMode (\r
+  IN EFI_PEI_SERVICES  **PeiServices,\r
+  IN EFI_BOOT_MODE     BootMode\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This service enables PEIMs to update the boot mode variable.    \r
+\r
+Arguments:\r
+\r
+  PeiServices    - The PEI core services table.\r
+  BootMode       - The value of the boot mode to set.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS    - The value was successfully updated\r
+\r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE                    *PrivateData;    \r
+  EFI_HOB_HANDOFF_INFO_TABLE    *HandOffHob;\r
+\r
+\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
+  \r
+  HandOffHob  = (PrivateData->HobList.HandoffInformationTable);\r
+  \r
+  HandOffHob->BootMode = BootMode;\r
+\r
+\r
+  return EFI_SUCCESS;   \r
+}\r
diff --git a/MdeModulePkg/Core/Pei/CommonHeader.h b/MdeModulePkg/Core/Pei/CommonHeader.h
new file mode 100644 (file)
index 0000000..dc64dca
--- /dev/null
@@ -0,0 +1,44 @@
+/**@file\r
+  Common header file shared by all source files.\r
+\r
+  This file includes package header files, library classes and protocol, PPI & GUID definitions.\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
+   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
+#ifndef __COMMON_HEADER_H_\r
+#define __COMMON_HEADER_H_\r
+\r
+#include <PiPei.h>\r
+#include <FrameworkPei.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Ppi/DxeIpl.h>\r
+#include <Ppi/MemoryDiscovered.h>\r
+#include <Ppi/FindFv.h>\r
+#include <Ppi/StatusCode.h>\r
+#include <Ppi/Security.h>\r
+#include <Ppi/Reset.h>\r
+#include <Ppi/LoadFile.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/PeiCoreEntryPoint.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PerformanceLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/PeCoffGetEntryPointLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/TimerLib.h>\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Core/Pei/Dependency/dependency.c b/MdeModulePkg/Core/Pei/Dependency/dependency.c
new file mode 100644 (file)
index 0000000..ec3c68b
--- /dev/null
@@ -0,0 +1,267 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  dependency.c\r
+\r
+Abstract:\r
+\r
+  PEI Dispatcher Dependency Evaluator\r
+\r
+  This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine\r
+  if a driver can be scheduled for execution.  The criteria for\r
+  schedulability is that the dependency expression is satisfied.\r
+  \r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <PeiMain.h>\r
+#include "dependency.h"\r
+\r
+STATIC\r
+BOOLEAN\r
+IsPpiInstalled (\r
+  IN EFI_PEI_SERVICES  **PeiServices,\r
+  IN EVAL_STACK_ENTRY  *Stack\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine determines if a PPI has been installed.\r
+  The truth value of a GUID is determined by if the PPI has\r
+  been published and can be queried from the PPI database.\r
+\r
+Arguments:\r
+  PeiServices - The PEI core services table.\r
+  Stack       - Reference to EVAL_STACK_ENTRY that contains PPI GUID to check\r
+\r
+Returns:\r
+\r
+  True if the PPI is already installed.\r
+  False if the PPI has yet to be installed.\r
+\r
+--*/\r
+{\r
+  VOID        *PeiInstance;\r
+  EFI_STATUS  Status;\r
+  EFI_GUID    PpiGuid;\r
+  \r
+  //\r
+  // If there is no GUID to evaluate, just return current result on stack.\r
+  //\r
+  if (Stack->Operator == NULL) {\r
+    return Stack->Result;\r
+  }\r
+  \r
+  //\r
+  // Copy the Guid into a locale variable so that there are no\r
+  // possibilities of alignment faults for cross-compilation \r
+  // environments such as Intel?Itanium(TM).\r
+  //\r
+  CopyMem(&PpiGuid, Stack->Operator, sizeof(EFI_GUID));\r
+\r
+  //\r
+  // Check if the PPI is installed.\r
+  //\r
+  Status = PeiServicesLocatePpi(\r
+             &PpiGuid,        // GUID\r
+             0,               // INSTANCE\r
+             NULL,            // EFI_PEI_PPI_DESCRIPTOR\r
+             &PeiInstance     // PPI\r
+             );\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    return FALSE;\r
+  }\r
+   \r
+  return TRUE;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+PeimDispatchReadiness (\r
+  IN EFI_PEI_SERVICES   **PeiServices,\r
+  IN VOID               *DependencyExpression,\r
+  OUT BOOLEAN           *Runnable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This is the POSTFIX version of the dependency evaluator.  When a\r
+  PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on\r
+  the evaluation stack.  When that entry is poped from the evaluation\r
+  stack, the PPI is checked if it is installed.  This method allows\r
+  some time savings as not all PPIs must be checked for certain\r
+  operation types (AND, OR).\r
+\r
+Arguments:\r
+\r
+  PeiServices               - Calling context.\r
+\r
+  DependencyExpression      - Pointer to a dependency expression.  The Grammar adheres to \r
+                              the BNF described above and is stored in postfix notation.\r
+  Runnable                  - is True if the driver can be scheduled and False if the driver \r
+                              cannot be scheduled.  This is the value that the schedulers \r
+                              should use for deciding the state of the driver.\r
+\r
+Returns:\r
+\r
+  Status = EFI_SUCCESS            if it is a well-formed Grammar\r
+           EFI_INVALID_PARAMETER  if the dependency expression overflows\r
+                                  the evaluation stack\r
+           EFI_INVALID_PARAMETER  if the dependency expression underflows\r
+                                  the evaluation stack\r
+           EFI_INVALID_PARAMETER  if the dependency expression is not a\r
+                                  well-formed Grammar.\r
+--*/\r
+{\r
+  DEPENDENCY_EXPRESSION_OPERAND  *Iterator;\r
+  EVAL_STACK_ENTRY               *StackPtr;\r
+  EVAL_STACK_ENTRY               EvalStack[MAX_GRAMMAR_SIZE];\r
+\r
+  Iterator  = DependencyExpression;\r
+  *Runnable = FALSE;\r
+\r
+  StackPtr = &EvalStack[0];\r
+\r
+  while (TRUE) {\r
+\r
+    switch (*(Iterator++)) {\r
+      \r
+      //\r
+      // For performance reason we put the frequently used items in front of \r
+      // the rarely used  items\r
+      //\r
+      \r
+      case (EFI_DEP_PUSH):\r
+        //\r
+        // Check to make sure the dependency grammar doesn't overflow the\r
+        // EvalStack on the push\r
+        //\r
+        if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {\r
+          return EFI_INVALID_PARAMETER;\r
+        }\r
+\r
+        //\r
+        // Push the pointer to the PUSH opcode operator (pointer to PPI GUID)\r
+        // We will evaluate if the PPI is insalled on the POP operation.\r
+        //\r
+        StackPtr->Operator = (VOID *) Iterator;\r
+        Iterator = Iterator + sizeof (EFI_GUID);\r
+        StackPtr++;\r
+        break;\r
+\r
+      case (EFI_DEP_AND):    \r
+      case (EFI_DEP_OR):     \r
+        //\r
+        // Check to make sure the dependency grammar doesn't underflow the\r
+        // EvalStack on the two POPs for the AND operation.  Don't need to\r
+        // check for the overflow on PUSHing the result since we already\r
+        // did two POPs.\r
+        //\r
+        if (StackPtr < &EvalStack[2]) {\r
+          return EFI_INVALID_PARAMETER;\r
+        }\r
+\r
+        //\r
+        // Evaluate the first POPed operator only. If the operand is\r
+        // EFI_DEP_AND and the POPed operator evaluates to FALSE, or the\r
+        // operand is EFI_DEP_OR and the POPed operator evaluates to TRUE,\r
+        // we don't need to check the second operator, and the result will be\r
+        // evaluation of the POPed operator. Otherwise, don't POP the second\r
+        // operator since it will now evaluate to the final result on the\r
+        // next operand that causes a POP.\r
+        // \r
+        StackPtr--;\r
+        //\r
+        // Iterator has increased by 1 after we retrieve the operand, so here we \r
+        // should get the value pointed by (Iterator - 1), in order to obtain the \r
+        // same operand.\r
+        //\r
+        if (*(Iterator - 1) == EFI_DEP_AND) {\r
+          if (!(IsPpiInstalled (PeiServices, StackPtr))) {\r
+            (StackPtr-1)->Result = FALSE;\r
+            (StackPtr-1)->Operator = NULL;\r
+          }\r
+        } else {\r
+          if (IsPpiInstalled (PeiServices, StackPtr)) {\r
+            (StackPtr-1)->Result = TRUE;\r
+            (StackPtr-1)->Operator = NULL;\r
+          }\r
+        }\r
+        break;\r
+        \r
+      case (EFI_DEP_END):\r
+        StackPtr--;\r
+        //\r
+        // Check to make sure EvalStack is balanced.  If not, then there is\r
+        // an error in the dependency grammar, so return EFI_INVALID_PARAMETER.\r
+        //\r
+        if (StackPtr != &EvalStack[0]) {\r
+          return EFI_INVALID_PARAMETER;\r
+        }\r
+        *Runnable = IsPpiInstalled (PeiServices, StackPtr);\r
+        return EFI_SUCCESS;\r
+        break;\r
+\r
+      case (EFI_DEP_NOT):    \r
+        //\r
+        // Check to make sure the dependency grammar doesn't underflow the\r
+        // EvalStack on the POP for the NOT operation.  Don't need to\r
+        // check for the overflow on PUSHing the result since we already\r
+        // did a POP.\r
+        //\r
+        if (StackPtr < &EvalStack[1]) {\r
+          return EFI_INVALID_PARAMETER;\r
+        }\r
+        (StackPtr-1)->Result = (BOOLEAN) !IsPpiInstalled (PeiServices, (StackPtr-1));\r
+        (StackPtr-1)->Operator = NULL;\r
+        break;\r
+\r
+      case (EFI_DEP_TRUE):\r
+      case (EFI_DEP_FALSE):\r
+        //\r
+        // Check to make sure the dependency grammar doesn't overflow the\r
+        // EvalStack on the push\r
+        //\r
+        if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {\r
+          return EFI_INVALID_PARAMETER;\r
+        }\r
+        //\r
+        // Iterator has increased by 1 after we retrieve the operand, so here we \r
+        // should get the value pointed by (Iterator - 1), in order to obtain the \r
+        // same operand.\r
+        //\r
+        if (*(Iterator - 1) == EFI_DEP_TRUE) {\r
+          StackPtr->Result = TRUE;\r
+        } else {\r
+          StackPtr->Result = FALSE;\r
+        }\r
+        StackPtr->Operator = NULL;\r
+        StackPtr++;\r
+        break;\r
+\r
+      default:\r
+        //\r
+        // The grammar should never arrive here\r
+        //\r
+        return EFI_INVALID_PARAMETER;\r
+        break;\r
+    }\r
+  }\r
+}\r
diff --git a/MdeModulePkg/Core/Pei/Dependency/dependency.h b/MdeModulePkg/Core/Pei/Dependency/dependency.h
new file mode 100644 (file)
index 0000000..2ac2ddb
--- /dev/null
@@ -0,0 +1,43 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  dependency.h\r
+\r
+Abstract:\r
+   \r
+  This module contains data specific to dependency expressions\r
+  and local function prototypes.\r
+        \r
+--*/\r
+\r
+#ifndef _PEI_DEPENDENCY_H_\r
+#define _PEI_DEPENDENCY_H_\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#define MAX_GRAMMAR_SIZE  256\r
+\r
+//\r
+// type definitions\r
+//\r
+typedef UINT8 DEPENDENCY_EXPRESSION_OPERAND;\r
+\r
+typedef struct {\r
+  BOOLEAN                 Result;\r
+  VOID                    *Operator;\r
+} EVAL_STACK_ENTRY;\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
new file mode 100644 (file)
index 0000000..15b2360
--- /dev/null
@@ -0,0 +1,543 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  Dispatcher.c\r
+\r
+Abstract:\r
+\r
+  EFI PEI Core dispatch services\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <PeiMain.h>\r
+\r
+STATIC\r
+VOID *\r
+TransferOldDataToNewDataRange (\r
+  IN PEI_CORE_INSTANCE        *PrivateData\r
+  );\r
+\r
+EFI_STATUS\r
+PeiDispatcher (\r
+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,\r
+  IN PEI_CORE_INSTANCE           *PrivateData,\r
+  IN PEI_CORE_DISPATCH_DATA      *DispatchData\r
+  )\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Conduct PEIM dispatch.\r
+\r
+Arguments:\r
+\r
+  PeiStartupDescriptor - Pointer to IN EFI_PEI_STARTUP_DESCRIPTOR\r
+  PrivateData          - Pointer to the private data passed in from caller\r
+  DispatchData         - Pointer to PEI_CORE_DISPATCH_DATA data.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS   - Successfully dispatched PEIM.\r
+  EFI_NOT_FOUND - The dispatch failed.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                        Status;\r
+  PEI_CORE_TEMP_POINTERS            TempPtr;\r
+  UINTN                             PrivateDataInMem;\r
+  BOOLEAN                           NextFvFound;\r
+  EFI_FIRMWARE_VOLUME_HEADER        *NextFvAddress;\r
+  EFI_FIRMWARE_VOLUME_HEADER        *DefaultFvAddress;\r
+  VOID                              *TopOfStack;\r
+  //\r
+  // Debug data for uninstalled Peim list\r
+  //\r
+  EFI_GUID                          DebugFoundPeimList[32];\r
+  EFI_DEVICE_HANDLE_EXTENDED_DATA   ExtendedData;\r
+\r
+  //\r
+  // save the Current FV Address so that we will not process it again if FindFv returns it later\r
+  //\r
+  DefaultFvAddress = DispatchData->BootFvAddress;\r
+\r
+  //\r
+  // This is the main dispatch loop.  It will search known FVs for PEIMs and\r
+  // attempt to dispatch them.  If any PEIM gets dispatched through a single\r
+  // pass of the dispatcher, it will start over from the Bfv again to see\r
+  // if any new PEIMs dependencies got satisfied.  With a well ordered\r
+  // FV where PEIMs are found in the order their dependencies are also\r
+  // satisfied, this dipatcher should run only once.\r
+  //\r
+  for (;;) {\r
+    //\r
+    // This is the PEIM search loop. It will scan through all PEIMs it can find\r
+    // looking for PEIMs to dispatch, and will dipatch them if they have not\r
+    // already been dispatched and all of their dependencies are met.\r
+    // If no more PEIMs can be found in this pass through all known FVs,\r
+    // then it will break out of this loop.\r
+    //\r
+    for (;;) {\r
+\r
+      Status = FindNextPeim (\r
+                 &PrivateData->PS,\r
+                 DispatchData->CurrentFvAddress,\r
+                 &DispatchData->CurrentPeimAddress\r
+                 );\r
+\r
+      //\r
+      // If we found a PEIM, check if it is dispatched.  If so, go to the\r
+      // next PEIM.  If not, dispatch it if its dependencies are satisfied.\r
+      // If its dependencies are not satisfied, go to the next PEIM.\r
+      //\r
+      if (Status == EFI_SUCCESS) {\r
+\r
+        DEBUG_CODE_BEGIN ();\r
+\r
+          //\r
+          // Fill list of found Peims for later list of those not installed\r
+          //\r
+          CopyMem (\r
+            &DebugFoundPeimList[DispatchData->CurrentPeim],\r
+            &DispatchData->CurrentPeimAddress->Name,\r
+            sizeof (EFI_GUID)\r
+            );\r
+\r
+        DEBUG_CODE_END ();\r
+\r
+        if (!Dispatched (\r
+               DispatchData->CurrentPeim,\r
+               DispatchData->DispatchedPeimBitMap\r
+               )) {\r
+          if (DepexSatisfied (&PrivateData->PS, DispatchData->CurrentPeimAddress)) {\r
+            Status = PeiLoadImage (\r
+                       &PrivateData->PS,\r
+                       DispatchData->CurrentPeimAddress,\r
+                       &TempPtr.Raw\r
+                       );\r
+            if (Status == EFI_SUCCESS) {\r
+\r
+              //\r
+              // The PEIM has its dependencies satisfied, and its entry point\r
+              // has been found, so invoke it.\r
+              //\r
+              PERF_START (\r
+                (VOID *) (UINTN) (DispatchData->CurrentPeimAddress),\r
+                "PEIM",\r
+                NULL,\r
+                0\r
+                );\r
+\r
+              //\r
+              // BUGBUG: Used to be EFI_PEI_REPORT_STATUS_CODE_CODE\r
+              //\r
+              ExtendedData.Handle = (EFI_HANDLE)DispatchData->CurrentPeimAddress;\r
+\r
+              REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
+                EFI_PROGRESS_CODE,\r
+                EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN,\r
+                (VOID *)(&ExtendedData),\r
+                sizeof (ExtendedData)\r
+                );\r
+\r
+              //\r
+              // Is this a authentic image\r
+              //\r
+              Status = VerifyPeim (\r
+                        &PrivateData->PS,\r
+                        DispatchData->CurrentPeimAddress\r
+                        );\r
+\r
+              if (Status != EFI_SECURITY_VIOLATION) {\r
+\r
+                //\r
+                // BUGBUG: Before enable PI, we need cast EFI_FFS_FILE_HEADER* to EFI_PEI_FILE_HANDLE*\r
+                //         Because we use new MdePkg's definition, but they are binary compatible in fact.\r
+                //\r
+                Status =  TempPtr.PeimEntry (\r
+                                    (EFI_PEI_FILE_HANDLE*)DispatchData->CurrentPeimAddress,\r
+                                    &PrivateData->PS\r
+                                    );\r
+              }\r
+\r
+              REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
+                EFI_PROGRESS_CODE,\r
+                EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END,\r
+                (VOID *)(&ExtendedData),\r
+                sizeof (ExtendedData)\r
+                );\r
+\r
+              PERF_END ((VOID *) (UINTN) (DispatchData->CurrentPeimAddress), "PEIM", NULL, 0);\r
+\r
+              //\r
+              // Mark the PEIM as dispatched so we don't attempt to run it again\r
+              //\r
+              SetDispatched (\r
+                &PrivateData->PS,\r
+                DispatchData->CurrentPeim,\r
+                &DispatchData->DispatchedPeimBitMap\r
+                );\r
+\r
+              //\r
+              // Process the Notify list and dispatch any notifies for\r
+              // newly installed PPIs.\r
+              //\r
+              ProcessNotifyList (&PrivateData->PS);\r
+\r
+              //\r
+              // If real system memory was discovered and installed by this\r
+              // PEIM, switch the stacks to the new memory.  Since we are\r
+              // at dispatch level, only the Core's private data is preserved,\r
+              // nobody else should have any data on the stack.\r
+              //\r
+              if (PrivateData->SwitchStackSignal) {\r
+                TempPtr.PeiCore = (PEI_CORE_ENTRY_POINT)PeiCore;\r
+                PrivateDataInMem = (UINTN) TransferOldDataToNewDataRange (PrivateData);\r
+                ASSERT (PrivateDataInMem != 0);\r
+                //\r
+                // Adjust the top of stack to be aligned at CPU_STACK_ALIGNMENT\r
+                //\r
+                TopOfStack = (VOID *)((UINTN)PrivateData->StackBase + (UINTN)PrivateData->StackSize - CPU_STACK_ALIGNMENT);\r
+                TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);\r
+\r
+                PeiSwitchStacks (\r
+                  (SWITCH_STACK_ENTRY_POINT)(UINTN)TempPtr.Raw,\r
+                  PeiStartupDescriptor,\r
+                  (VOID*)PrivateDataInMem,\r
+                  TopOfStack,\r
+                  (VOID*)(UINTN)PrivateData->StackBase\r
+                  );\r
+              }\r
+            }\r
+          }\r
+        }\r
+        DispatchData->CurrentPeim++;\r
+        continue;\r
+\r
+      } else {\r
+\r
+        //\r
+        // If we could not find another PEIM in the current FV, go try\r
+        // the FindFv PPI to look in other FVs for more PEIMs.  If we can\r
+        // not locate the FindFv PPI, or if the FindFv PPI can not find\r
+        // anymore FVs, then exit the PEIM search loop.\r
+        //\r
+        if (DispatchData->FindFv == NULL) {\r
+          Status = PeiServicesLocatePpi (\r
+                     &gEfiFindFvPpiGuid,\r
+                     0,\r
+                     NULL,\r
+                     (VOID **)&DispatchData->FindFv\r
+                     );\r
+          if (Status != EFI_SUCCESS) {\r
+            break;\r
+          }\r
+        }\r
+        NextFvFound = FALSE;\r
+        while (!NextFvFound) {\r
+          Status = DispatchData->FindFv->FindFv (\r
+                                           DispatchData->FindFv,\r
+                                           &PrivateData->PS,\r
+                                           &DispatchData->CurrentFv,\r
+                                           &NextFvAddress\r
+                                           );\r
+          //\r
+          // if there is no next fv, get out of this loop of finding FVs\r
+          //\r
+          if (Status != EFI_SUCCESS) {\r
+            break;\r
+          }\r
+          //\r
+          // don't process the default Fv again. (we don't know the order in which the hobs were created)\r
+          //\r
+          if ((NextFvAddress != DefaultFvAddress) &&\r
+              (NextFvAddress != DispatchData->CurrentFvAddress)) {\r
+\r
+            //\r
+            // VerifyFv() is currently returns SUCCESS all the time, add code to it to\r
+            // actually verify the given FV\r
+            //\r
+            Status = VerifyFv (NextFvAddress);\r
+            if (Status == EFI_SUCCESS) {\r
+              NextFvFound = TRUE;\r
+              DispatchData->CurrentFvAddress = NextFvAddress;\r
+              DispatchData->CurrentPeimAddress = NULL;\r
+              //\r
+              // current PRIM number (CurrentPeim) must continue as is, don't reset it here\r
+              //\r
+            }\r
+          }\r
+        }\r
+        //\r
+        // if there is no next fv, get out of this loop of dispatching PEIMs\r
+        //\r
+        if (!NextFvFound) {\r
+          break;\r
+        }\r
+        //\r
+        // continue in the inner for(;;) loop with a new FV;\r
+        //\r
+      }\r
+    }\r
+\r
+    //\r
+    // If all the PEIMs that we have found have been dispatched, then\r
+    // there is nothing left to dispatch and we don't need to go search\r
+    // through all PEIMs again.\r
+    //\r
+    if ((~(DispatchData->DispatchedPeimBitMap) &\r
+         ((1 << DispatchData->CurrentPeim)-1)) == 0) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    // Check if no more PEIMs that depex was satisfied\r
+    //\r
+    if (DispatchData->DispatchedPeimBitMap == DispatchData->PreviousPeimBitMap) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    // Case when Depex is not satisfied and has to traverse the list again\r
+    //\r
+    DispatchData->CurrentPeim = 0;\r
+    DispatchData->CurrentPeimAddress = 0;\r
+    DispatchData->PreviousPeimBitMap = DispatchData->DispatchedPeimBitMap;\r
+\r
+    //\r
+    // don't go back to the loop without making sure that the CurrentFvAddress is the\r
+    // same as the 1st (or default) FV we started with. otherwise we will interpret the bimap wrongly and\r
+    // mess it up, always start processing the PEIMs from the default FV just like in the first time around.\r
+    //\r
+    DispatchData->CurrentFv = 0;\r
+    DispatchData->CurrentFvAddress = DefaultFvAddress;\r
+  }\r
+\r
+  DEBUG_CODE_BEGIN ();\r
+    //\r
+    // Debug data for uninstalled Peim list\r
+    //\r
+    UINT32        DebugNotDispatchedBitmap;\r
+    UINT8         DebugFoundPeimPoint;\r
+\r
+    DebugFoundPeimPoint = 0;\r
+    //\r
+    // Get bitmap of Peims that were not dispatched,\r
+    //\r
+\r
+    DebugNotDispatchedBitmap = ((DispatchData->DispatchedPeimBitMap) ^ ((1 << DispatchData->CurrentPeim)-1));\r
+    //\r
+    // Scan bitmap of Peims not installed and print GUIDS\r
+    //\r
+    while (DebugNotDispatchedBitmap != 0) {\r
+      if ((DebugNotDispatchedBitmap & 1) != 0) {\r
+        DEBUG ((EFI_D_INFO, "WARNING -> InstallPpi: Not Installed: %g\n",\r
+           &DebugFoundPeimList[DebugFoundPeimPoint]\r
+           ));\r
+      }\r
+      DebugFoundPeimPoint++;\r
+      DebugNotDispatchedBitmap >>= 1;\r
+    }\r
+\r
+  DEBUG_CODE_END ();\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+VOID\r
+InitializeDispatcherData (\r
+  IN EFI_PEI_SERVICES             **PeiServices,\r
+  IN PEI_CORE_INSTANCE            *OldCoreData,\r
+  IN EFI_PEI_STARTUP_DESCRIPTOR   *PeiStartupDescriptor\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize the Dispatcher's data members\r
+\r
+Arguments:\r
+\r
+  PeiServices          - The PEI core services table.\r
+  OldCoreData          - Pointer to old core data (before switching stack).\r
+                         NULL if being run in non-permament memory mode.\r
+  PeiStartupDescriptor - Information and services provided by SEC phase.\r
+\r
+Returns:\r
+\r
+  None.\r
+\r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE *PrivateData;\r
+\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
+\r
+  if (OldCoreData == NULL) {\r
+    PrivateData->DispatchData.CurrentFvAddress = (EFI_FIRMWARE_VOLUME_HEADER *) PeiStartupDescriptor->BootFirmwareVolume;\r
+    PrivateData->DispatchData.BootFvAddress = (EFI_FIRMWARE_VOLUME_HEADER *) PeiStartupDescriptor->BootFirmwareVolume;\r
+  } else {\r
+\r
+    //\r
+    // Current peim has been dispatched, but not count\r
+    //\r
+    PrivateData->DispatchData.CurrentPeim = (UINT8)(OldCoreData->DispatchData.CurrentPeim + 1);\r
+  }\r
+\r
+  return;\r
+}\r
+\r
+\r
+BOOLEAN\r
+Dispatched (\r
+  IN UINT8  CurrentPeim,\r
+  IN UINT32 DispatchedPeimBitMap\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine checks to see if a particular PEIM has been dispatched during\r
+  the PEI core dispatch.\r
+\r
+Arguments:\r
+  CurrentPeim          - The PEIM/FV in the bit array to check.\r
+  DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.\r
+\r
+Returns:\r
+  TRUE  - PEIM already dispatched\r
+  FALSE - Otherwise\r
+\r
+--*/\r
+{\r
+  return (BOOLEAN)((DispatchedPeimBitMap & (1 << CurrentPeim)) != 0);\r
+}\r
+\r
+VOID\r
+SetDispatched (\r
+  IN EFI_PEI_SERVICES   **PeiServices,\r
+  IN UINT8              CurrentPeim,\r
+  OUT UINT32            *DispatchedPeimBitMap\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine sets a PEIM as having been dispatched once its entry\r
+  point has been invoked.\r
+\r
+Arguments:\r
+\r
+  PeiServices          - The PEI core services table.\r
+  CurrentPeim          - The PEIM/FV in the bit array to check.\r
+  DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.\r
+\r
+Returns:\r
+  None\r
+\r
+--*/\r
+{\r
+  //\r
+  // Check if the total number of PEIMs exceed the bitmap.\r
+  // CurrentPeim is 0-based\r
+  //\r
+  ASSERT (CurrentPeim < (sizeof (*DispatchedPeimBitMap) * 8));\r
+  *DispatchedPeimBitMap |= (1 << CurrentPeim);\r
+  return;\r
+}\r
+\r
+BOOLEAN\r
+DepexSatisfied (\r
+  IN EFI_PEI_SERVICES  **PeiServices,\r
+  IN VOID              *CurrentPeimAddress\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine parses the Dependency Expression, if available, and\r
+  decides if the module can be executed.\r
+\r
+Arguments:\r
+  PeiServices - The PEI Service Table\r
+  CurrentPeimAddress - Address of the PEIM Firmware File under investigation\r
+\r
+Returns:\r
+  TRUE  - Can be dispatched\r
+  FALSE - Cannot be dispatched\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  INT8        *DepexData;\r
+  BOOLEAN     Runnable;\r
+\r
+  Status = PeiServicesFfsFindSectionData (\r
+             EFI_SECTION_PEI_DEPEX,\r
+             CurrentPeimAddress,\r
+             (VOID **)&DepexData\r
+             );\r
+  //\r
+  // If there is no DEPEX, assume the module can be executed\r
+  //\r
+  if (EFI_ERROR (Status)) {\r
+    return TRUE;\r
+  }\r
+\r
+  //\r
+  // Evaluate a given DEPEX\r
+  //\r
+  Status = PeimDispatchReadiness (\r
+            PeiServices,\r
+            DepexData,\r
+            &Runnable\r
+            );\r
+\r
+  return Runnable;\r
+}\r
+\r
+STATIC\r
+VOID *\r
+TransferOldDataToNewDataRange (\r
+  IN PEI_CORE_INSTANCE        *PrivateData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine transfers the contents of the pre-permanent memory\r
+  PEI Core private data to a post-permanent memory data location.\r
+\r
+Arguments:\r
+\r
+  PrivateData       - Pointer to the current PEI Core private data pre-permanent memory\r
+\r
+Returns:\r
+\r
+  Pointer to the PrivateData once the private data has been transferred to permanent memory\r
+\r
+--*/\r
+{\r
+  //\r
+  //Build private HOB to PEI core to transfer old NEM-range data to new NEM-range\r
+  //\r
+  return BuildGuidDataHob (&gEfiPeiCorePrivateGuid, PrivateData, sizeof (PEI_CORE_INSTANCE));\r
+}\r
+\r
diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Stack.c b/MdeModulePkg/Core/Pei/Dispatcher/Stack.c
new file mode 100644 (file)
index 0000000..8895cae
--- /dev/null
@@ -0,0 +1,55 @@
+/** @file\r
+  PeiSwitchStacks() function for PEI dispatcher.\r
+\r
+  Copyright (c) 2006, Intel Corporation<BR>\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:  String.c\r
+\r
+**/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+/**\r
+  Transfers control to a function starting with a new stack.\r
+\r
+  Transfers control to the function specified by EntryPoint using the new stack\r
+  specified by NewStack and passing in the parameters specified by Context1 and\r
+  Context2. Context1 and Context2 are optional and may be NULL. The function\r
+  EntryPoint must never return.\r
+\r
+  If EntryPoint is NULL, then ASSERT().\r
+  If NewStack is NULL, then ASSERT().\r
+\r
+  @param  EntryPoint  A pointer to function to call with the new stack.\r
+  @param  Context1    A pointer to the context to pass into the EntryPoint\r
+                      function.\r
+  @param  Context2    A pointer to the context to pass into the EntryPoint\r
+                      function.\r
+  @param  NewStack    A pointer to the new stack to use for the EntryPoint\r
+                      function.\r
+  @param  NewBsp      A pointer to the new BSP for the EntryPoint on IPF. It's\r
+                      Reserved on other architectures.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PeiSwitchStacks (\r
+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,\r
+  IN      VOID                      *Context1,  OPTIONAL\r
+  IN      VOID                      *Context2,  OPTIONAL\r
+  IN      VOID                      *NewStack,\r
+  IN      VOID                      *NewBsp\r
+  )\r
+{\r
+  SwitchStack (EntryPoint, Context1, Context2, NewStack);\r
+}\r
diff --git a/MdeModulePkg/Core/Pei/FwVol/FwVol.c b/MdeModulePkg/Core/Pei/FwVol/FwVol.c
new file mode 100644 (file)
index 0000000..679825c
--- /dev/null
@@ -0,0 +1,479 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  FwVol.c\r
+\r
+Abstract:\r
+\r
+  Pei Core Firmware File System service routines.\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <PeiMain.h>\r
+\r
+#define GETOCCUPIEDSIZE(ActualSize, Alignment) \\r
+  (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))\r
+\r
+STATIC\r
+EFI_FFS_FILE_STATE\r
+GetFileState(\r
+  IN UINT8                ErasePolarity,\r
+  IN EFI_FFS_FILE_HEADER  *FfsHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Returns the highest bit set of the State field\r
+\r
+Arguments:\r
+\r
+  ErasePolarity   - Erase Polarity  as defined by EFI_FVB2_ERASE_POLARITY\r
+                    in the Attributes field.\r
+  FfsHeader       - Pointer to FFS File Header.\r
+\r
+Returns:\r
+  Returns the highest bit in the State field\r
+\r
+--*/\r
+{\r
+  EFI_FFS_FILE_STATE  FileState;\r
+  EFI_FFS_FILE_STATE  HighestBit;\r
+\r
+  FileState = FfsHeader->State;\r
+\r
+  if (ErasePolarity != 0) {\r
+    FileState = (EFI_FFS_FILE_STATE)~FileState;\r
+  }\r
+\r
+  HighestBit = 0x80;\r
+  while (HighestBit != 0 && (HighestBit & FileState) == 0) {\r
+    HighestBit >>= 1;\r
+  }\r
+\r
+  return HighestBit;\r
+} \r
+\r
+STATIC\r
+UINT8\r
+CalculateHeaderChecksum (\r
+  IN EFI_FFS_FILE_HEADER  *FileHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Calculates the checksum of the header of a file.\r
+\r
+Arguments:\r
+\r
+  FileHeader       - Pointer to FFS File Header.\r
+\r
+Returns:\r
+  Checksum of the header.\r
+  \r
+  The header is zero byte checksum.\r
+    - Zero means the header is good.\r
+    - Non-zero means the header is bad.\r
+    \r
+  \r
+Bugbug: For PEI performance reason, we comments this code at this time.\r
+--*/\r
+{\r
+  UINT8   *ptr;\r
+  UINTN   Index;\r
+  UINT8   Sum;\r
+  \r
+  Sum = 0;\r
+  ptr = (UINT8 *)FileHeader;\r
+\r
+  for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER) - 3; Index += 4) {\r
+    Sum = (UINT8)(Sum + ptr[Index]);\r
+    Sum = (UINT8)(Sum + ptr[Index+1]);\r
+    Sum = (UINT8)(Sum + ptr[Index+2]);\r
+    Sum = (UINT8)(Sum + ptr[Index+3]);\r
+  }\r
+\r
+  for (; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {\r
+    Sum = (UINT8)(Sum + ptr[Index]);\r
+  }\r
+  \r
+  //\r
+  // State field (since this indicates the different state of file). \r
+  //\r
+  Sum = (UINT8)(Sum - FileHeader->State);\r
+  //\r
+  // Checksum field of the file is not part of the header checksum.\r
+  //\r
+  Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);\r
+\r
+  return Sum;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+PeiFfsFindNextFileEx (\r
+  IN     EFI_FV_FILETYPE             SearchType,\r
+  IN     EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,\r
+  IN OUT EFI_FFS_FILE_HEADER         **FileHeader,\r
+  IN     BOOLEAN                     Flag\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    Given the input file pointer, search for the next matching file in the\r
+    FFS volume as defined by SearchType. The search starts from FileHeader inside\r
+    the Firmware Volume defined by FwVolHeader.\r
+\r
+Arguments:\r
+    PeiServices - Pointer to the PEI Core Services Table.\r
+    SearchType - Filter to find only files of this type.\r
+      Type EFI_FV_FILETYPE_ALL causes no filtering to be done.\r
+    FwVolHeader - Pointer to the FV header of the volume to search.\r
+      This parameter must point to a valid FFS volume.\r
+    FileHeader  - Pointer to the current file from which to begin searching.\r
+      This pointer will be updated upon return to reflect the file found.\r
+    Flag        - Indicator for if this is for PEI Dispath search \r
+Returns:\r
+    EFI_NOT_FOUND - No files matching the search criteria were found\r
+    EFI_SUCCESS\r
+\r
+--*/\r
+{\r
+  EFI_FFS_FILE_HEADER  *FfsFileHeader;\r
+  UINT32               FileLength;\r
+  UINT32               FileOccupiedSize;\r
+  UINT32               FileOffset;\r
+  UINT64               FvLength;\r
+  UINT8                ErasePolarity;\r
+  UINT8                FileState;\r
+  \r
+\r
+  FvLength = FwVolHeader->FvLength;\r
+  if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {\r
+    ErasePolarity = 1;\r
+  } else {\r
+    ErasePolarity = 0;\r
+  }\r
+  \r
+  //\r
+  // If FileHeader is not specified (NULL) start with the first file in the\r
+  // firmware volume.  Otherwise, start from the FileHeader.\r
+  //\r
+  if (*FileHeader == NULL)  {\r
+    FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);\r
+  } else {\r
+    //\r
+    // Length is 24 bits wide so mask upper 8 bits\r
+    // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.\r
+    //\r
+    FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF;\r
+    FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);\r
+    FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);\r
+  }\r
+\r
+  FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);\r
+  ASSERT (FileOffset <= 0xFFFFFFFF);\r
+  \r
+  while (FileOffset < (FvLength - sizeof(EFI_FFS_FILE_HEADER))) {\r
+    //\r
+    // Get FileState which is the highest bit of the State \r
+    //\r
+    FileState = GetFileState (ErasePolarity, FfsFileHeader);\r
+\r
+    switch (FileState) {\r
+\r
+    case EFI_FILE_HEADER_INVALID:\r
+      FileOffset += sizeof(EFI_FFS_FILE_HEADER);\r
+      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));\r
+      break;\r
+        \r
+    case EFI_FILE_DATA_VALID:\r
+    case EFI_FILE_MARKED_FOR_UPDATE:\r
+       if (CalculateHeaderChecksum (FfsFileHeader) == 0) {\r
+        FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
+        FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);\r
+        if (Flag) {\r
+          if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) || \r
+              (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) { \r
+            \r
+            *FileHeader = FfsFileHeader;\r
+        \r
+        \r
+            return EFI_SUCCESS;\r
+          }\r
+        } else {        \r
+          if ((SearchType == FfsFileHeader->Type) || \r
+              (SearchType == EFI_FV_FILETYPE_ALL)) { \r
+          \r
+            *FileHeader = FfsFileHeader;\r
+        \r
+        \r
+            return EFI_SUCCESS;\r
+          }\r
+        }\r
+\r
+        FileOffset += FileOccupiedSize; \r
+        FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
+      } else {\r
+        ASSERT (FALSE);\r
+        return EFI_NOT_FOUND;\r
+      }\r
+      break;\r
+    \r
+    case EFI_FILE_DELETED:\r
+      FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
+      FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);\r
+      FileOffset += FileOccupiedSize;\r
+      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
+      break;\r
+\r
+    default:\r
+      return EFI_NOT_FOUND;\r
+\r
+    } \r
+  }\r
+\r
+  return EFI_NOT_FOUND;  \r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiFfsFindSectionData (\r
+  IN     EFI_PEI_SERVICES      **PeiServices,\r
+  IN     EFI_SECTION_TYPE      SectionType,\r
+  IN     EFI_FFS_FILE_HEADER   *FfsFileHeader,\r
+  IN OUT VOID                  **SectionData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    Given the input file pointer, search for the next matching section in the\r
+    FFS volume.\r
+\r
+Arguments:\r
+    PeiServices - Pointer to the PEI Core Services Table.\r
+    SearchType - Filter to find only sections of this type.\r
+    FfsFileHeader  - Pointer to the current file to search.\r
+    SectionData - Pointer to the Section matching SectionType in FfsFileHeader.\r
+                - NULL if section not found\r
+\r
+Returns:\r
+    EFI_NOT_FOUND - No files matching the search criteria were found\r
+    EFI_SUCCESS\r
+\r
+--*/\r
+{\r
+  UINT32                        FileSize;\r
+  EFI_COMMON_SECTION_HEADER     *Section;\r
+  UINT32                        SectionLength;\r
+  UINT32                        ParsedLength;\r
+  \r
+\r
+  //\r
+  // Size is 24 bits wide so mask upper 8 bits. \r
+  //    Does not include FfsFileHeader header size\r
+  // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.\r
+  //\r
+  Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);\r
+  FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
+  FileSize -= sizeof(EFI_FFS_FILE_HEADER);\r
+  \r
+  *SectionData = NULL;\r
+  ParsedLength = 0;\r
+  while (ParsedLength < FileSize) {\r
+    if (Section->Type == SectionType) {\r
+      *SectionData = (VOID *)(Section + 1);\r
+\r
+\r
+      return EFI_SUCCESS;\r
+    }\r
+    //\r
+    // Size is 24 bits wide so mask upper 8 bits. \r
+    // SectionLength is adjusted it is 4 byte aligned.\r
+    // Go to the next section\r
+    //\r
+    SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;\r
+    SectionLength = GETOCCUPIEDSIZE (SectionLength, 4);\r
+    ASSERT (SectionLength != 0);\r
+    ParsedLength += SectionLength;\r
+    Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);\r
+  }\r
+  \r
+  return EFI_NOT_FOUND;\r
+  \r
+}\r
+\r
+\r
+EFI_STATUS\r
+FindNextPeim (\r
+  IN     EFI_PEI_SERVICES            **PeiServices,\r
+  IN     EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,\r
+  IN OUT EFI_FFS_FILE_HEADER         **PeimFileHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    Given the input file pointer, search for the next matching file in the\r
+    FFS volume. The search starts from FileHeader inside\r
+    the Firmware Volume defined by FwVolHeader.\r
+\r
+Arguments:\r
+    PeiServices - Pointer to the PEI Core Services Table.\r
+\r
+    FwVolHeader - Pointer to the FV header of the volume to search.\r
+                     This parameter must point to a valid FFS volume.\r
+                     \r
+    PeimFileHeader  - Pointer to the current file from which to begin searching.\r
+                  This pointer will be updated upon return to reflect the file found.\r
+\r
+Returns:\r
+    EFI_NOT_FOUND - No files matching the search criteria were found\r
+    EFI_SUCCESS\r
+\r
+--*/\r
+{\r
+  return PeiFfsFindNextFileEx ( \r
+           0,\r
+           FwVolHeader,\r
+           PeimFileHeader,\r
+           TRUE\r
+           );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiFfsFindNextFile (\r
+  IN     EFI_PEI_SERVICES            **PeiServices,\r
+  IN     EFI_FV_FILETYPE             SearchType,\r
+  IN     EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,\r
+  IN OUT EFI_FFS_FILE_HEADER         **FileHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    Given the input file pointer, search for the next matching file in the\r
+    FFS volume as defined by SearchType. The search starts from FileHeader inside\r
+    the Firmware Volume defined by FwVolHeader.\r
+\r
+Arguments:\r
+    PeiServices - Pointer to the PEI Core Services Table.\r
+    \r
+    SearchType - Filter to find only files of this type.\r
+      Type EFI_FV_FILETYPE_ALL causes no filtering to be done.\r
+      \r
+    FwVolHeader - Pointer to the FV header of the volume to search.\r
+      This parameter must point to a valid FFS volume.\r
+      \r
+    FileHeader  - Pointer to the current file from which to begin searching.\r
+      This pointer will be updated upon return to reflect the file found.\r
+  \r
+Returns:\r
+    EFI_NOT_FOUND - No files matching the search criteria were found\r
+    EFI_SUCCESS\r
+\r
+--*/\r
+{\r
+  return PeiFfsFindNextFileEx ( \r
+           SearchType,\r
+           FwVolHeader,\r
+           FileHeader,\r
+           FALSE\r
+           );\r
+}\r
+\r
+EFI_STATUS \r
+EFIAPI\r
+PeiFvFindNextVolume (\r
+  IN     EFI_PEI_SERVICES           **PeiServices,\r
+  IN     UINTN                      Instance,\r
+  IN OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Return the BFV location\r
+\r
+  BugBug -- Move this to the location of this code to where the\r
+  other FV and FFS support code lives.\r
+  Also, update to use FindFV for instances #'s >= 1.\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+  Instance    - Instance of FV to find\r
+  FwVolHeader - Pointer to contain the data to return\r
+\r
+Returns:\r
+  Pointer to the Firmware Volume instance requested\r
+\r
+  EFI_INVALID_PARAMETER     - FwVolHeader is NULL\r
+  \r
+  EFI_SUCCESS               - Firmware volume instance successfully found.\r
+\r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE       *PrivateData;\r
+  EFI_STATUS              Status;\r
+  EFI_PEI_FIND_FV_PPI     *FindFvPpi;\r
+  UINT8                   LocalInstance;\r
+\r
+\r
+  LocalInstance = (UINT8) Instance;\r
+\r
+  Status = EFI_SUCCESS;\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
+\r
+  if (FwVolHeader == NULL) {\r
+\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Instance == 0) {\r
+    *FwVolHeader = PrivateData->DispatchData.BootFvAddress;\r
+\r
+\r
+    return Status;\r
+  } else {\r
+    //\r
+    // Locate all instances of FindFV\r
+    // Alternately, could use FV HOBs, but the PPI is cleaner\r
+    //\r
+    Status = PeiServicesLocatePpi (\r
+               &gEfiFindFvPpiGuid,\r
+               0,\r
+               NULL,\r
+               (VOID **)&FindFvPpi\r
+               );\r
+\r
+    if (Status != EFI_SUCCESS) {\r
+      Status = EFI_NOT_FOUND;\r
+    } else {\r
+      Status = FindFvPpi->FindFv (\r
+                            FindFvPpi,\r
+                            PeiServices,\r
+                            &LocalInstance,\r
+                            FwVolHeader\r
+                            );  \r
+\r
+    }\r
+  }\r
+  return Status;\r
+}\r
diff --git a/MdeModulePkg/Core/Pei/Hob/Hob.c b/MdeModulePkg/Core/Pei/Hob/Hob.c
new file mode 100644 (file)
index 0000000..9128b12
--- /dev/null
@@ -0,0 +1,197 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  Hob.c\r
+\r
+Abstract:\r
+\r
+  EFI PEI Core HOB services\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <PeiMain.h>\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiGetHobList (\r
+  IN EFI_PEI_SERVICES  **PeiServices,\r
+  IN OUT VOID          **HobList\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Gets the pointer to the HOB List.\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+  HobList     - Pointer to the HOB List.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS                 - Get the pointer of HOB List\r
+  EFI_NOT_AVAILABLE_YET       - the HOB List is not yet published\r
+  EFI_INVALID_PARAMETER       - HobList is NULL (in debug mode)\r
+            \r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE *PrivateData;\r
+\r
+  \r
+  //\r
+  // Only check this parameter in debug mode\r
+  //\r
+  \r
+  DEBUG_CODE_BEGIN ();  \r
+    if (HobList == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  DEBUG_CODE_END ();\r
+  \r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
+\r
+  *HobList    = PrivateData->HobList.Raw;\r
+\r
+\r
+  return EFI_SUCCESS;   \r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiCreateHob (\r
+  IN EFI_PEI_SERVICES  **PeiServices,\r
+  IN UINT16            Type,\r
+  IN UINT16            Length,\r
+  IN OUT VOID          **Hob\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Add a new HOB to the HOB List.\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+  Type        - Type of the new HOB.\r
+  Length      - Length of the new HOB to allocate.\r
+  Hob         - Pointer to the new HOB.\r
+\r
+Returns:\r
+\r
+  Status  - EFI_SUCCESS\r
+          - EFI_INVALID_PARAMETER if Hob is NULL\r
+          - EFI_NOT_AVAILABLE_YET if HobList is still not available.\r
+          - EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.\r
+            \r
+--*/\r
+{\r
+  EFI_STATUS                           Status;\r
+  EFI_HOB_HANDOFF_INFO_TABLE           *HandOffHob;\r
+  EFI_HOB_GENERIC_HEADER               *HobEnd;\r
+  EFI_PHYSICAL_ADDRESS                 FreeMemory;\r
+\r
+\r
+  Status = PeiGetHobList (PeiServices, Hob);\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  HandOffHob = *Hob;\r
+\r
+  Length     = (UINT16)((Length + 0x7) & (~0x7));\r
+\r
+  FreeMemory = HandOffHob->EfiFreeMemoryTop -\r
+               HandOffHob->EfiFreeMemoryBottom;\r
+\r
+  if (FreeMemory < Length) {\r
+    DEBUG ((EFI_D_ERROR, "PeiCreateHob fail: Length - 0x%08x\n", (UINTN)Length));\r
+    DEBUG ((EFI_D_ERROR, "  FreeMemoryTop    - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryTop));\r
+    DEBUG ((EFI_D_ERROR, "  FreeMemoryBottom - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryBottom));\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  \r
+  *Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;\r
+  ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobType   = Type;\r
+  ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobLength = Length;\r
+  ((EFI_HOB_GENERIC_HEADER*) *Hob)->Reserved  = 0;\r
+\r
+  HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN) *Hob + Length);\r
+  HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;\r
\r
+  HobEnd->HobType   = EFI_HOB_TYPE_END_OF_HOB_LIST;\r
+  HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);\r
+  HobEnd->Reserved  = 0;\r
+  HobEnd++;\r
+  HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;\r
+\r
+\r
+  return EFI_SUCCESS;   \r
+}\r
+\r
+\r
+EFI_STATUS\r
+PeiCoreBuildHobHandoffInfoTable (\r
+  IN EFI_BOOT_MODE         BootMode,\r
+  IN EFI_PHYSICAL_ADDRESS  MemoryBegin,\r
+  IN UINT64                MemoryLength\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Builds a Handoff Information Table HOB\r
+\r
+Arguments:\r
+\r
+  BootMode      - Current Bootmode\r
+  MemoryBegin   - Start Memory Address.\r
+  MemoryLength  - Length of Memory.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS\r
+\r
+--*/\r
+{\r
+  EFI_HOB_HANDOFF_INFO_TABLE   *Hob;\r
+  EFI_HOB_GENERIC_HEADER       *HobEnd;\r
+\r
+  Hob    = (VOID *)(UINTN)MemoryBegin;\r
+  HobEnd = (EFI_HOB_GENERIC_HEADER*) (Hob+1);\r
+  Hob->Header.HobType   = EFI_HOB_TYPE_HANDOFF;\r
+  Hob->Header.HobLength = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);\r
+  Hob->Header.Reserved  = 0;\r
+  \r
+  HobEnd->HobType     = EFI_HOB_TYPE_END_OF_HOB_LIST;\r
+  HobEnd->HobLength   = sizeof(EFI_HOB_GENERIC_HEADER);\r
+  HobEnd->Reserved    = 0;\r
+\r
+  Hob->Version             = EFI_HOB_HANDOFF_TABLE_VERSION;\r
+  Hob->BootMode            = BootMode;\r
+  \r
+  Hob->EfiMemoryTop        = MemoryBegin + MemoryLength;\r
+  Hob->EfiMemoryBottom     = MemoryBegin;\r
+  Hob->EfiFreeMemoryTop    = MemoryBegin + MemoryLength;\r
+  Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) (HobEnd+1);\r
+  Hob->EfiEndOfHobList     = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c
new file mode 100644 (file)
index 0000000..391290d
--- /dev/null
@@ -0,0 +1,272 @@
+/*++\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
+  Image.c\r
+\r
+Abstract:\r
+\r
+  Pei Core Load Image Support\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <PeiMain.h>\r
+\r
+\r
+\r
+EFI_STATUS\r
+PeiLoadImage (\r
+  IN EFI_PEI_SERVICES         **PeiServices,\r
+  IN EFI_FFS_FILE_HEADER      *PeimFileHeader,\r
+  OUT VOID                    **EntryPoint\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Routine for loading file image.\r
+\r
+Arguments:\r
+\r
+  PeiServices     - The PEI core services table.\r
+  PeimFileHeader  - Pointer to the FFS file header of the image.\r
+  EntryPoint      - Pointer to entry point of specified image file for output.\r
+\r
+Returns:\r
+\r
+  Status - EFI_SUCCESS    - Image is successfully loaded.\r
+           EFI_NOT_FOUND  - Fail to locate necessary PPI\r
+           Others         - Fail to load file.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                  Status;\r
+  VOID                        *Pe32Data;\r
+  EFI_PEI_FV_FILE_LOADER_PPI  *FvLoadFilePpi;\r
+  EFI_PHYSICAL_ADDRESS        ImageAddress;\r
+  UINT64                      ImageSize;\r
+  EFI_PHYSICAL_ADDRESS        ImageEntryPoint;\r
+  EFI_TE_IMAGE_HEADER         *TEImageHeader;\r
+  UINT16                      Machine;\r
+\r
+  *EntryPoint   = NULL;\r
+  TEImageHeader = NULL;\r
+\r
+  //\r
+  // Try to find a PE32 section.\r
+  //\r
+  Status = PeiServicesFfsFindSectionData (\r
+             EFI_SECTION_PE32,\r
+             PeimFileHeader,\r
+             &Pe32Data\r
+             );\r
+  //\r
+  // If we didn't find a PE32 section, try to find a TE section.\r
+  //\r
+  if (EFI_ERROR (Status)) {\r
+    Status = PeiServicesFfsFindSectionData (\r
+               EFI_SECTION_TE,\r
+               PeimFileHeader,\r
+               (VOID **) &TEImageHeader\r
+               );\r
+    if (EFI_ERROR (Status) || TEImageHeader == NULL) {\r
+      //\r
+      // There was not a PE32 or a TE section, so assume that it's a Compressed section\r
+      // and use the LoadFile\r
+      //\r
+      Status = PeiServicesLocatePpi (\r
+                &gEfiPeiFvFileLoaderPpiGuid,\r
+                0,\r
+                NULL,\r
+                (VOID **)&FvLoadFilePpi\r
+                );\r
+      if (EFI_ERROR (Status)) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      Status = FvLoadFilePpi->FvLoadFile (\r
+                                FvLoadFilePpi,\r
+                                PeimFileHeader,\r
+                                &ImageAddress,\r
+                                &ImageSize,\r
+                                &ImageEntryPoint\r
+                                );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      //\r
+      // Got the entry point from ImageEntryPoint and ImageStartAddress\r
+      //\r
+      Pe32Data    = (VOID *) ((UINTN) ImageAddress);\r
+      *EntryPoint = (VOID *) ((UINTN) ImageEntryPoint);\r
+    } else {\r
+      //\r
+      // Retrieve the entry point from the TE image header\r
+      //\r
+      ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) TEImageHeader;\r
+      *EntryPoint  = (VOID *)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +\r
+                    TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);\r
+    }\r
+  } else {\r
+    //\r
+    // Retrieve the entry point from the PE/COFF image header\r
+    //\r
+    ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data;\r
+    Status = PeCoffLoaderGetEntryPoint (Pe32Data, EntryPoint);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+\r
+  if (((EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress)->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
+    TEImageHeader = (EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress;\r
+    Machine = TEImageHeader->Machine;\r
+  } else {\r
+    Machine = PeCoffLoaderGetMachineType (Pe32Data);\r
+  } \r
+  \r
+  if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) {\r
+    return EFI_UNSUPPORTED;  \r
+  }\r
+\r
+  //\r
+  // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi\r
+  //\r
+  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", (UINTN) ImageAddress, *EntryPoint));\r
+  DEBUG_CODE_BEGIN ();\r
+    EFI_IMAGE_DATA_DIRECTORY            *DirectoryEntry;\r
+    EFI_IMAGE_DEBUG_DIRECTORY_ENTRY     *DebugEntry;\r
+    UINTN                               DirCount;\r
+    UINTN                               Index;\r
+    UINTN                               Index1;\r
+    BOOLEAN                             FileNameFound;\r
+    CHAR8                               *AsciiString;\r
+    CHAR8                               AsciiBuffer[512];\r
+    VOID                                *CodeViewEntryPointer;\r
+    INTN                                TEImageAdjust;\r
+    EFI_IMAGE_DOS_HEADER                *DosHeader;\r
+    EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
+    UINT32                              NumberOfRvaAndSizes;\r
+\r
+    Hdr.Pe32 = NULL;\r
+    if (TEImageHeader == NULL) {\r
+      DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\r
+      if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
+        //\r
+        // DOS image header is present, so read the PE header after the DOS image header\r
+        //\r
+        Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHeader->e_lfanew) & 0x0ffff));\r
+      } else {\r
+        //\r
+        // DOS image header is not present, so PE header is at the image base\r
+        //\r
+        Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Find the codeview info in the image and display the file name\r
+    // being loaded.\r
+    //\r
+    // Per the PE/COFF spec, you can't assume that a given data directory\r
+    // is present in the image. You have to check the NumberOfRvaAndSizes in\r
+    // the optional header to verify a desired directory entry is there.\r
+    //\r
+    DebugEntry          = NULL;\r
+    DirectoryEntry      = NULL;\r
+    NumberOfRvaAndSizes = 0;\r
+    TEImageAdjust       = 0;\r
+    \r
+    if (TEImageHeader == NULL) {\r
+      if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+        //     \r
+        // Use PE32 offset get Debug Directory Entry\r
+        //\r
+        NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
+        DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+        DebugEntry     = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
+      } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+        //     \r
+        // Use PE32+ offset get Debug Directory Entry\r
+        //\r
+        NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
+        DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+        DebugEntry     = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
+      }\r
+\r
+      if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
+        DirectoryEntry = NULL;\r
+        DebugEntry = NULL;\r
+      }\r
+    } else {\r
+      if (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {\r
+        DirectoryEntry  = &TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
+        TEImageAdjust   = sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize;\r
+        DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) TEImageHeader +\r
+                      TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +\r
+                      TEImageAdjust);\r
+      }\r
+    }\r
+\r
+    if (DebugEntry != NULL && DirectoryEntry != NULL) {\r
+      for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {\r
+        if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
+          if (DebugEntry->SizeOfData > 0) {\r
+            CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);\r
+            switch (* (UINT32 *) CodeViewEntryPointer) {\r
+              case CODEVIEW_SIGNATURE_NB10:\r
+                AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
+                break;\r
+\r
+              case CODEVIEW_SIGNATURE_RSDS:\r
+                AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
+                break;\r
+\r
+              default:\r
+                AsciiString = NULL;\r
+                break;\r
+            }\r
+            if (AsciiString != NULL) {\r
+              FileNameFound = FALSE;\r
+              for (Index = 0, Index1 = 0; AsciiString[Index] != '\0'; Index++) {\r
+                if (AsciiString[Index] == '\\') {\r
+                  Index1 = Index;\r
+                  FileNameFound = TRUE;\r
+                }\r
+              }\r
+\r
+              if (FileNameFound) {\r
+                for (Index = Index1 + 1; AsciiString[Index] != '.'; Index++) {\r
+                  AsciiBuffer[Index - (Index1 + 1)] = AsciiString[Index];\r
+                }\r
+                AsciiBuffer[Index - (Index1 + 1)] = 0;\r
+                DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));\r
+                break;\r
+              }\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  DEBUG_CODE_END ();\r
+\r
+  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/MdeModulePkg/Core/Pei/Ipf/IpfCpuCore.i b/MdeModulePkg/Core/Pei/Ipf/IpfCpuCore.i
new file mode 100644 (file)
index 0000000..548271a
--- /dev/null
@@ -0,0 +1,98 @@
+//++\r
+// Copyright (c) 2006, 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
+//   IpfCpuCore.i\r
+//\r
+// Abstract:\r
+//   IPF CPU definitions\r
+//\r
+//--\r
+\r
+#ifndef _IPF_CPU_CORE_\r
+#define _IPF_CPU_CORE_\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#define  PEI_BSP_STORE_SIZE                     0x4000\r
+#define  ResetFn                                0x00\r
+#define  MachineCheckFn                         0x01\r
+#define  InitFn                                 0x02\r
+#define  RecoveryFn                             0x03\r
+#define  GuardBand                              0x10 \r
+\r
+//\r
+// Define hardware RSE Configuration Register\r
+//\r
+\r
+//\r
+// RS Configuration (RSC) bit field positions\r
+//\r
+#define RSC_MODE       0\r
+#define RSC_PL         2\r
+#define RSC_BE         4\r
+//\r
+// RSC bits 5-15 reserved\r
+//\r
+#define RSC_MBZ0       5\r
+#define RSC_MBZ0_V     0x3ff\r
+#define RSC_LOADRS     16\r
+#define RSC_LOADRS_LEN 14\r
+//\r
+// RSC bits 30-63 reserved\r
+//\r
+#define RSC_MBZ1       30\r
+#define RSC_MBZ1_V     0x3ffffffffULL\r
+\r
+//\r
+// RSC modes\r
+//\r
+\r
+//\r
+// Lazy\r
+//\r
+#define RSC_MODE_LY (0x0)\r
+//\r
+// Store intensive\r
+//\r
+#define RSC_MODE_SI (0x1)\r
+//\r
+// Load intensive\r
+//\r
+#define RSC_MODE_LI (0x2)\r
+//\r
+// Eager\r
+//\r
+#define RSC_MODE_EA (0x3)\r
+\r
+//\r
+// RSC Endian bit values\r
+//\r
+#define RSC_BE_LITTLE 0\r
+#define RSC_BE_BIG    1\r
+\r
+//\r
+// RSC while in kernel: enabled, little endian, pl = 0, eager mode\r
+//\r
+#define RSC_KERNEL ((RSC_MODE_EA<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))\r
+//\r
+// Lazy RSC in kernel: enabled, little endian, pl = 0, lazy mode\r
+//\r
+#define RSC_KERNEL_LAZ ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))\r
+//\r
+// RSE disabled: disabled, pl = 0, little endian, eager mode\r
+//\r
+#define RSC_KERNEL_DISABLED ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Core/Pei/Ipf/IpfCpuCore.s b/MdeModulePkg/Core/Pei/Ipf/IpfCpuCore.s
new file mode 100644 (file)
index 0000000..b66192e
--- /dev/null
@@ -0,0 +1,197 @@
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+//++\r
+// Copyright (c) 2006, 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
+//    IpfCpuCore.s\r
+//\r
+//  Abstract:\r
+//    IPF Specific assembly routines\r
+//\r
+//--\r
+\r
+.file  "IpfCpuCore.s"\r
+\r
+#include  "IpfMacro.i"\r
+#include  "Ipf/IpfCpuCore.i"\r
+\r
+//----------------------------------------------------------------------------------\r
+// This module supports terminating CAR (Cache As RAM) stage. It copies all the\r
+// CAR data into real RAM and then makes a stack switch.\r
+\r
+// EFI_STATUS\r
+// SwitchCoreStacks (\r
+//   IN VOID  *EntryPoint,\r
+//   IN UINTN CopySize,\r
+//   IN VOID  *OldBase,\r
+//   IN VOID  *NewBase\r
+//   IN UINTN NewSP, OPTIONAL\r
+//   IN UINTN NewBSP OPTIONAL\r
+//   )\r
+// EFI_STATUS\r
+// SwitchCoreStacks (\r
+//   IN VOID  *EntryPointForContinuationFunction,\r
+//   IN UINTN StartupDescriptor,\r
+//   IN VOID  PEICorePointer,\r
+//   IN UINTN NewSP\r
+//   )\r
+//----------------------------------------------------------------------------------\r
+PROCEDURE_ENTRY (SwitchCoreStacks)\r
+\r
+        NESTED_SETUP (4,2,0,0)\r
+\r
+        // first save all stack registers in GPRs.\r
+        mov     r13 = in0;;             // this is a pointer to the PLABEL of the continuation function.\r
+        ld8     r16 = [r13],8;;         // r16 = address of continuation function from the PLABEL\r
+        ld8     gp = [r13];;            // gp  = gp of continuation function from the PLABEL\r
+        mov     b1 = r16;;\r
+\r
+        // save the parameters in r5, r6. these 2 seemed to be preserved across PAL calls\r
+        mov     r5 = in1;;              // this is the parameter1 to pass to the continuation function\r
+        mov     r6 = in2;;              // this is the parameter2 to pass to the continuation function\r
+        dep     r6=0,r6,63,1;;          // zero the bit 63.\r
+\r
+        mov     r8 = in3;;              // new stack pointer.\r
+\r
+        // r8 has the sp, this is 128K stack size, from this we will reserve 16K for the bspstore\r
+        movl    r15 = PEI_BSP_STORE_SIZE;;\r
+        sub     r8 = r8, r15;;\r
+        add     r15 = (GuardBand),r8;;  // some little buffer, now r15 will be our bspstore\r
+\r
+        // save the bspstore value to r4, save sp value to r7\r
+        mov     r4  = r15\r
+        mov     r7  = r8\r
+        mov     r16 = r8;;              // will be the new sp in uncache mode\r
+\r
+\r
+        alloc   r11=0,0,0,0;;           // Set 0-size frame\r
+        flushrs;;\r
+\r
+        mov     r21 = RSC_KERNEL_DISABLED;; // for rse disable\r
+        mov     ar.rsc = r21;;          // turn off RSE\r
+\r
+        add     sp = r0, r16            // transfer to the EFI stack\r
+        mov     ar.bspstore = r15       // switch to EFI BSP\r
+        invala                          // change of ar.bspstore needs invala.\r
+\r
+        mov     r19 = RSC_KERNEL_LAZ;;  // RSC enabled, Lazy mode\r
+        mov     ar.rsc = r19;;          // turn rse on, in kernel mode\r
+\r
+//-----------------------------------------------------------------------------------\r
+// Save here the meaningful stuff for next few lines and then make the PAL call.\r
+// Make PAL call to terminate the CAR status.\r
+        // AVL: do this only for recovery check call...\r
+\r
+        mov     r28=ar.k3;;\r
+        dep     r2 = r28,r0,0,8;;       // Extract Function bits from GR20.\r
+        cmp.eq  p6,p7 = RecoveryFn,r2;; // Is it Recovery check\r
+        (p7)  br.sptk.few DoneCARTermination; // if not, don't terminate car..\r
+\r
+TerminateCAR::\r
+\r
+        mov     r28 = ip;;\r
+        add     r28 = (DoneCARTerminationPALCall - TerminateCAR),r28;;\r
+        mov     b0 = r28\r
+\r
+        mov     r8 = ar.k5;;\r
+        mov     b6 = r8\r
+        mov     r28 = 0x208\r
+\r
+        mov     r29 = r0\r
+        mov     r30 = r0\r
+        mov     r31 = r0\r
+        mov     r8 = r0;;\r
+        br.sptk.few b6;;                // Call PAL-A call.\r
+\r
+DoneCARTerminationPALCall::\r
+\r
+// don't check error in soft sdv, it is always returning -1 for this call for some reason\r
+#if SOFT_SDV\r
+#else\r
+ReturnToPEIMain::\r
+        cmp.eq  p6,p7 = r8,r0;;\r
+        //\r
+        // dead loop if the PAL call failed, we have the CAR on but the stack is now pointing to memory\r
+        //\r
+        (p7) br.sptk.few ReturnToPEIMain;;\r
+        //\r
+        // PAL call successed,now the stack are in memory so come into cache mode\r
+        // instead of uncache mode\r
+        //\r
+\r
+        alloc   r11=0,0,0,0;;           // Set 0-size frame\r
+        flushrs;;\r
+\r
+        mov     r21 = RSC_KERNEL_DISABLED;; // for rse disable\r
+        mov     ar.rsc = r21;;          // turn off RSE\r
+\r
+        dep     r6 = 0,r6,63,1          // zero the bit 63\r
+        dep     r7 = 0,r7,63,1          // zero the bit 63\r
+        dep     r4 = 0,r4,63,1;;        // zero the bit 63\r
+        add     sp = r0, r7             // transfer to the EFI stack in cache mode\r
+        mov     ar.bspstore = r4        // switch to EFI BSP\r
+        invala                          // change of ar.bspstore needs invala.\r
+\r
+        mov     r19 = RSC_KERNEL_LAZ;;  // RSC enabled, Lazy mode\r
+        mov     ar.rsc = r19;;          // turn rse on, in kernel mode\r
+\r
+#endif\r
+\r
+DoneCARTermination::\r
+\r
+        // allocate a stack frame:\r
+        alloc   r11=0,2,2,0 ;;          // alloc  outs going to ensuing DXE IPL service\r
+                                                                                                // on the new stack\r
+        mov     out0 = r5;;\r
+        mov     out1 = r6;;\r
+\r
+        mov     r16 = b1;;\r
+        mov     b6 = r16;;\r
+        br.call.sptk.few b0=b6;;        // Call the continuation function\r
+\r
+        NESTED_RETURN\r
+\r
+PROCEDURE_EXIT(SwitchCoreStacks)\r
+//-----------------------------------------------------------------------------------\r
+\r
+//---------------------------------------------------------------------------------\r
+//++\r
+// GetHandOffStatus\r
+//\r
+// This routine is called by all processors simultaneously, to get some hand-off\r
+// status that has been captured by IPF dispatcher and recorded in kernel registers.\r
+//\r
+// Arguments :\r
+//\r
+// On Entry :  None.\r
+//\r
+// Return Value: Lid, R20Status.\r
+//\r
+//--\r
+//----------------------------------------------------------------------------------\r
+PROCEDURE_ENTRY (GetHandOffStatus)\r
+\r
+        NESTED_SETUP (0,2+0,0,0)\r
+\r
+        mov     r8 = ar.k6              // Health Status (Self test params)\r
+        mov     r9 = ar.k4              // LID bits\r
+        mov     r10 = ar.k3;;           // SAL_E entry state\r
+        mov     r11 = ar.k7             // Return address to PAL\r
+\r
+        NESTED_RETURN\r
+PROCEDURE_EXIT (GetHandOffStatus)\r
+//----------------------------------------------------------------------------------\r
+\r
+\r
diff --git a/MdeModulePkg/Core/Pei/Ipf/IpfPeiMain.h b/MdeModulePkg/Core/Pei/Ipf/IpfPeiMain.h
new file mode 100644 (file)
index 0000000..e5b160f
--- /dev/null
@@ -0,0 +1,57 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  IpfPeiMain.h\r
+\r
+Abstract:\r
+\r
+  Definition of IPF specific function\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _IPF_PEI_MAIN_H_\r
+#define _IPF_PEI_MAIN_H_\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <PeiMain.h>\r
+\r
+SAL_RETURN_REGS\r
+GetHandOffStatus (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+   This routine is called by all processors simultaneously, to get some hand-off\r
+   status that has been captured by IPF dispatcher and recorded in kernel registers.\r
+  \r
+Arguments :\r
+\r
+  On Entry :  None.\r
+\r
+Returns:\r
+\r
+   Lid, R20Status.\r
+\r
+--*/\r
+\r
+;\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Core/Pei/Ipf/Stack.c b/MdeModulePkg/Core/Pei/Ipf/Stack.c
new file mode 100644 (file)
index 0000000..600a41d
--- /dev/null
@@ -0,0 +1,63 @@
+/** @file\r
+  PeiSwitchStacks() function for PEI dispatcher.\r
+\r
+  Copyright (c) 2006 - 2007, Intel Corporation<BR>\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:  String.c\r
+\r
+**/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <PeiMain.h>\r
+\r
+/**\r
+  Transfers control to a function starting with a new stack.\r
+\r
+  Transfers control to the function specified by EntryPoint using the new stack\r
+  specified by NewStack and passing in the parameters specified by Context1 and\r
+  Context2. Context1 and Context2 are optional and may be NULL. The function\r
+  EntryPoint must never return.\r
+\r
+  If EntryPoint is NULL, then ASSERT().\r
+  If NewStack is NULL, then ASSERT().\r
+\r
+  @param  EntryPoint  A pointer to function to call with the new stack.\r
+  @param  Context1    A pointer to the context to pass into the EntryPoint\r
+                      function.\r
+  @param  Context2    A pointer to the context to pass into the EntryPoint\r
+                      function.\r
+  @param  NewStack    A pointer to the new stack to use for the EntryPoint\r
+                      function.\r
+  @param  NewBsp      A pointer to the new BSP for the EntryPoint on IPF. It's\r
+                      Reserved on other architectures.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PeiSwitchStacks (\r
+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,\r
+  IN      VOID                      *Context1,  OPTIONAL\r
+  IN      VOID                      *Context2,  OPTIONAL\r
+  IN      VOID                      *NewStack,\r
+  IN      VOID                      *NewBsp\r
+  )\r
+{\r
+  SwitchStack (\r
+    EntryPoint,\r
+    Context1,\r
+    Context2,\r
+    NewStack,\r
+    NewBsp\r
+    );\r
+}\r
diff --git a/MdeModulePkg/Core/Pei/Ipf/SwitchToCacheMode.c b/MdeModulePkg/Core/Pei/Ipf/SwitchToCacheMode.c
new file mode 100644 (file)
index 0000000..f4e90e1
--- /dev/null
@@ -0,0 +1,76 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  SwitchToCacheMode.c\r
+\r
+Abstract:\r
+\r
+  Ipf CAR specific function used to switch to cache mode for the later memory access\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "IpfPeiMain.h"\r
+#include "IpfCpuCore.i"\r
+\r
+VOID\r
+SwitchToCacheMode (\r
+  IN PEI_CORE_INSTANCE           *CoreData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Switch the PHIT pointers to cache mode after InstallPeiMemory in CAR.\r
+\r
+Arguments:\r
+\r
+  CoreData   - The PEI core Private Data\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  EFI_HOB_HANDOFF_INFO_TABLE    *Phit;\r
+\r
+  if (CoreData == NULL) {\r
+    //\r
+    // the first call with CoreData as NULL.\r
+    //\r
+    return;\r
+  }\r
+  \r
+  if ((GetHandOffStatus().r10 & 0xFF) == RecoveryFn) {\r
+    CoreData->StackBase = CoreData->StackBase &  CACHE_MODE_ADDRESS_MASK;\r
+    CoreData->HobList.Raw = (UINT8 *)((UINTN)CoreData->HobList.Raw & CACHE_MODE_ADDRESS_MASK);\r
+\r
+    //\r
+    // Change the PHIT pointer value to cache mode\r
+    //\r
+    Phit = CoreData->HobList.HandoffInformationTable;\r
+\r
+    Phit->EfiMemoryTop        = Phit->EfiMemoryTop & CACHE_MODE_ADDRESS_MASK;\r
+    Phit->EfiFreeMemoryTop    = Phit->EfiFreeMemoryTop & CACHE_MODE_ADDRESS_MASK;\r
+    Phit->EfiMemoryBottom     = Phit->EfiMemoryBottom  & CACHE_MODE_ADDRESS_MASK;\r
+    Phit->EfiFreeMemoryBottom = Phit->EfiFreeMemoryBottom & CACHE_MODE_ADDRESS_MASK;\r
+    Phit->EfiEndOfHobList     = Phit->EfiEndOfHobList & CACHE_MODE_ADDRESS_MASK;\r
+  }\r
+\r
+  return;\r
+}\r
diff --git a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
new file mode 100644 (file)
index 0000000..86f4487
--- /dev/null
@@ -0,0 +1,326 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  MemoryServices.c\r
+\r
+Abstract:\r
+\r
+  EFI PEI Core memory services\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <PeiMain.h>\r
+\r
+VOID\r
+InitializeMemoryServices (\r
+  IN EFI_PEI_SERVICES            **PeiServices,\r
+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,\r
+  IN PEI_CORE_INSTANCE           *OldCoreData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize the memory services.\r
+\r
+Arguments:\r
+\r
+  PeiServices          - The PEI core services table.\r
+  PeiStartupDescriptor - Information and services provided by SEC phase.\r
+  OldCoreData          - Pointer to the PEI Core data.\r
+                         NULL if being run in non-permament memory mode.\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE                    *PrivateData;\r
+  UINT64                               SizeOfCarHeap;\r
+\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
+  PrivateData->SwitchStackSignal = FALSE;\r
+\r
+  if (OldCoreData == NULL) {\r
+\r
+    PrivateData->PeiMemoryInstalled = FALSE;\r
+\r
+    PrivateData->BottomOfCarHeap = (VOID *) (((UINTN)(VOID *)(&PrivateData))\r
+                                   & (~((PeiStartupDescriptor->SizeOfCacheAsRam) - 1))); \r
+    PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + PeiStartupDescriptor->SizeOfCacheAsRam);\r
+    //\r
+    // SizeOfCarHeap is 1/2 (arbitrary) of CacheAsRam Size.\r
+    //\r
+    SizeOfCarHeap = (UINT64) PeiStartupDescriptor->SizeOfCacheAsRam;\r
+    SizeOfCarHeap = RShiftU64 (SizeOfCarHeap, 1);\r
\r
+    DEBUG_CODE_BEGIN ();\r
+      PrivateData->SizeOfCacheAsRam = PeiStartupDescriptor->SizeOfCacheAsRam;\r
+      PrivateData->MaxTopOfCarHeap  = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) SizeOfCarHeap);\r
+    DEBUG_CODE_END ();\r
+\r
+    PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;\r
+    \r
+    PeiCoreBuildHobHandoffInfoTable (\r
+      BOOT_WITH_FULL_CONFIGURATION,\r
+      (EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,\r
+      (UINTN) SizeOfCarHeap\r
+      );\r
+    //\r
+    // Copy PeiServices from ROM to Cache in PrivateData\r
+    //\r
+    CopyMem (&(PrivateData->ServiceTableShadow), *PeiServices, sizeof (EFI_PEI_SERVICES));\r
+\r
+    //\r
+    // Set PS to point to ServiceTableShadow in Cache\r
+    //\r
+    PrivateData->PS = &(PrivateData->ServiceTableShadow);\r
+  } else {\r
+  //                                                                    \r
+  // Set PS to point to ServiceTableShadow in Cache one time after the  \r
+  // stack switched to main memory                                      \r
+  //                                                                    \r
+  PrivateData->PS = &(PrivateData->ServiceTableShadow);                 \r
+}                                                                       \r
+\r
+  return;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiInstallPeiMemory (\r
+  IN EFI_PEI_SERVICES      **PeiServices,\r
+  IN EFI_PHYSICAL_ADDRESS  MemoryBegin,\r
+  IN UINT64                MemoryLength\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Install the permanent memory is now available.\r
+  Creates HOB (PHIT and Stack).\r
+\r
+Arguments:\r
+\r
+  PeiServices   - The PEI core services table.\r
+  MemoryBegin   - Start of memory address.\r
+  MemoryLength  - Length of memory.\r
+\r
+Returns:\r
+\r
+  Status  - EFI_SUCCESS\r
+            \r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE                     *PrivateData;\r
+  EFI_HOB_HANDOFF_INFO_TABLE            *OldHandOffHob;\r
+  EFI_HOB_HANDOFF_INFO_TABLE            *NewHandOffHob;\r
+  UINT64                                PeiStackSize;\r
+  UINT64                                EfiFreeMemorySize;\r
+  EFI_PHYSICAL_ADDRESS                  PhysicalAddressOfOldHob;\r
+  \r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
+\r
+  PrivateData->SwitchStackSignal = TRUE;\r
+  PrivateData->PeiMemoryInstalled = TRUE;\r
+\r
+  PrivateData->StackBase = MemoryBegin;\r
+  \r
+  PeiStackSize = RShiftU64 (MemoryLength, 1);\r
+  if (PEI_STACK_SIZE > PeiStackSize) {\r
+    PrivateData->StackSize = PeiStackSize;\r
+  } else {\r
+    PrivateData->StackSize = PEI_STACK_SIZE;\r
+  }\r
+\r
+  OldHandOffHob = PrivateData->HobList.HandoffInformationTable;\r
+\r
+  PrivateData->HobList.Raw = (VOID *)((UINTN)(MemoryBegin + PrivateData->StackSize));\r
+  NewHandOffHob = PrivateData->HobList.HandoffInformationTable;\r
+  PhysicalAddressOfOldHob = (EFI_PHYSICAL_ADDRESS) (UINTN) OldHandOffHob;\r
+\r
+  EfiFreeMemorySize = OldHandOffHob->EfiFreeMemoryBottom - PhysicalAddressOfOldHob;\r
+  \r
+  DEBUG ((EFI_D_INFO, "HOBLIST address before memory init = 0x%08x\n", OldHandOffHob));\r
+  DEBUG ((EFI_D_INFO, "HOBLIST address after memory init = 0x%08x\n", NewHandOffHob));\r
+\r
+  CopyMem (\r
+    NewHandOffHob,\r
+    OldHandOffHob,\r
+    (UINTN)EfiFreeMemorySize\r
+    );\r
+\r
+  NewHandOffHob->EfiMemoryTop     = MemoryBegin + MemoryLength;\r
+  NewHandOffHob->EfiFreeMemoryTop = NewHandOffHob->EfiMemoryTop;\r
+  NewHandOffHob->EfiMemoryBottom  = MemoryBegin;\r
+  \r
+  NewHandOffHob->EfiFreeMemoryBottom = (UINTN)NewHandOffHob + EfiFreeMemorySize;                                     \r
+                                       \r
+  NewHandOffHob->EfiEndOfHobList     = (UINTN)NewHandOffHob +\r
+                                       (OldHandOffHob->EfiEndOfHobList -\r
+                                        PhysicalAddressOfOldHob);\r
+\r
+  ConvertPpiPointers (PeiServices, OldHandOffHob, NewHandOffHob);\r
+\r
+  BuildStackHob (PrivateData->StackBase, PrivateData->StackSize);\r
+  \r
+\r
+  return EFI_SUCCESS;   \r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiAllocatePages (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_MEMORY_TYPE            MemoryType,\r
+  IN UINTN                      Pages,\r
+  OUT EFI_PHYSICAL_ADDRESS      *Memory\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Memory allocation service on permanent memory, \r
+  not usable prior to the memory installation.\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+  MemoryType  - Type of memory to allocate.\r
+  Pages       - Number of pages to allocate.\r
+  Memory      - Pointer of memory allocated.\r
+\r
+Returns:\r
+\r
+  Status - EFI_SUCCESS              The allocation was successful\r
+           EFI_INVALID_PARAMETER    Only AllocateAnyAddress is supported.\r
+           EFI_NOT_AVAILABLE_YET    Called with permanent memory not available\r
+           EFI_OUT_OF_RESOURCES     There is not enough HOB heap to satisfy the requirement\r
+                                    to allocate the number of pages.\r
+\r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE                       *PrivateData;\r
+  EFI_PEI_HOB_POINTERS                    Hob;\r
+  EFI_PHYSICAL_ADDRESS                    Offset;\r
+\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
+\r
+  //\r
+  // Check if Hob already available\r
+  //\r
+  if (!PrivateData->PeiMemoryInstalled) {\r
+    return EFI_NOT_AVAILABLE_YET;\r
+  }\r
+\r
+  Hob.Raw = PrivateData->HobList.Raw;\r
+\r
+  //\r
+  // Check to see if on 4k boundary\r
+  //\r
+  Offset = Hob.HandoffInformationTable->EfiFreeMemoryTop & 0xFFF;\r
+\r
+  //\r
+  // If not aligned, make the allocation aligned.\r
+  //\r
+  if (Offset != 0) {\r
+    Hob.HandoffInformationTable->EfiFreeMemoryTop -= Offset;\r
+  }\r
+\r
+  //\r
+  // Verify that there is sufficient memory to satisfy the allocation\r
+  //\r
+  if (Hob.HandoffInformationTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) < \r
+      Hob.HandoffInformationTable->EfiFreeMemoryBottom) {\r
+    DEBUG ((EFI_D_ERROR, "AllocatePages failed: No 0x%x Pages is available.\n", Pages));\r
+    DEBUG ((EFI_D_ERROR, "There is only left 0x%x pages memory resource to be allocated.\n", \\r
+    EFI_SIZE_TO_PAGES ((UINTN) (Hob.HandoffInformationTable->EfiFreeMemoryTop - Hob.HandoffInformationTable->EfiFreeMemoryBottom))));\r
+    return  EFI_OUT_OF_RESOURCES;\r
+  } else {\r
+    //\r
+    // Update the PHIT to reflect the memory usage\r
+    //\r
+    Hob.HandoffInformationTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;\r
+\r
+    //\r
+    // Update the value for the caller\r
+    //\r
+    *Memory = Hob.HandoffInformationTable->EfiFreeMemoryTop;\r
+\r
+    //\r
+    // Create a memory allocation HOB.\r
+    //\r
+    BuildMemoryAllocationHob (\r
+      Hob.HandoffInformationTable->EfiFreeMemoryTop,\r
+      Pages * EFI_PAGE_SIZE + Offset,\r
+      MemoryType\r
+      );\r
+\r
+    return EFI_SUCCESS;\r
+  }\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiAllocatePool (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN UINTN                      Size,\r
+  OUT VOID                      **Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Memory allocation service on the CAR.  \r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+\r
+  Size        - Amount of memory required\r
+\r
+  Buffer      - Address of pointer to the buffer\r
+\r
+Returns:\r
+\r
+  Status - EFI_SUCCESS              The allocation was successful\r
+           EFI_OUT_OF_RESOURCES     There is not enough heap to satisfy the requirement\r
+                                    to allocate the requested size.\r
+                                    \r
+--*/\r
+{\r
+  EFI_STATUS               Status;\r
+  EFI_HOB_MEMORY_POOL      *Hob;\r
+\r
+ //\r
+ // If some "post-memory" PEIM wishes to allocate larger pool,\r
+ // it should use AllocatePages service instead.\r
+ //\r
+ ASSERT (Size < 0x10000 - sizeof (EFI_HOB_MEMORY_POOL));\r
+ Status = PeiServicesCreateHob (\r
+             EFI_HOB_TYPE_MEMORY_POOL,\r
+             (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),\r
+             (VOID **)&Hob\r
+             );\r
+  *Buffer = Hob+1;  \r
+\r
+\r
+  return Status;\r
+}\r
diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h
new file mode 100644 (file)
index 0000000..e136041
--- /dev/null
@@ -0,0 +1,1147 @@
+/*++\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
+  PeiMain.h\r
+\r
+Abstract:\r
+\r
+  Definition of Pei Core Structures and Services\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _PEI_MAIN_H_\r
+#define _PEI_MAIN_H_\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+extern EFI_GUID gEfiPeiCorePrivateGuid;\r
+\r
+//\r
+// Pei Core private data structures\r
+//\r
+typedef union {\r
+  EFI_PEI_PPI_DESCRIPTOR      *Ppi;\r
+  EFI_PEI_NOTIFY_DESCRIPTOR   *Notify;\r
+  VOID                        *Raw;\r
+} PEI_PPI_LIST_POINTERS;\r
+\r
+#define PEI_STACK_SIZE 0x20000\r
+\r
+#define MAX_PPI_DESCRIPTORS 64\r
+\r
+typedef struct {\r
+  INTN                    PpiListEnd;\r
+  INTN                    NotifyListEnd;\r
+  INTN                    DispatchListEnd;\r
+  INTN                    LastDispatchedInstall;\r
+  INTN                    LastDispatchedNotify;\r
+  PEI_PPI_LIST_POINTERS   PpiListPtrs[MAX_PPI_DESCRIPTORS];\r
+} PEI_PPI_DATABASE;\r
+\r
+typedef struct {\r
+  UINT8                       CurrentPeim;\r
+  UINT8                       CurrentFv;\r
+  UINT32                      DispatchedPeimBitMap;\r
+  UINT32                      PreviousPeimBitMap;\r
+  EFI_FFS_FILE_HEADER         *CurrentPeimAddress;\r
+  EFI_FIRMWARE_VOLUME_HEADER  *CurrentFvAddress;\r
+  EFI_FIRMWARE_VOLUME_HEADER  *BootFvAddress;\r
+  EFI_PEI_FIND_FV_PPI         *FindFv;\r
+} PEI_CORE_DISPATCH_DATA;\r
+\r
+\r
+//\r
+// Pei Core private data structure instance\r
+//\r
+\r
+#define PEI_CORE_HANDLE_SIGNATURE  EFI_SIGNATURE_32('P','e','i','C')\r
+\r
+typedef struct{\r
+  UINTN                              Signature;\r
+  EFI_PEI_SERVICES                   *PS;     // Point to ServiceTableShadow\r
+  PEI_PPI_DATABASE                   PpiData;\r
+  PEI_CORE_DISPATCH_DATA             DispatchData;\r
+  EFI_PEI_HOB_POINTERS               HobList;\r
+  BOOLEAN                            SwitchStackSignal;\r
+  BOOLEAN                            PeiMemoryInstalled;\r
+  EFI_PHYSICAL_ADDRESS               StackBase;\r
+  UINT64                             StackSize;\r
+  VOID                               *BottomOfCarHeap;\r
+  VOID                               *TopOfCarHeap;\r
+  VOID                               *CpuIo;\r
+  EFI_PEI_SECURITY_PPI               *PrivateSecurityPpi;\r
+  EFI_PEI_SERVICES                   ServiceTableShadow;\r
+  UINTN                              SizeOfCacheAsRam;\r
+  VOID                               *MaxTopOfCarHeap;\r
+} PEI_CORE_INSTANCE;\r
+\r
+//\r
+// Pei Core Instance Data Macros\r
+//\r
+\r
+#define PEI_CORE_INSTANCE_FROM_PS_THIS(a) \\r
+  CR(a, PEI_CORE_INSTANCE, PS, PEI_CORE_HANDLE_SIGNATURE)\r
+\r
+//\r
+// BUGBUG: Where does this go really?\r
+//\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *PEI_CORE_ENTRY_POINT)(\r
+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,\r
+  IN PEI_CORE_INSTANCE           *OldCoreData\r
+  );\r
+\r
+//\r
+// Union of temporarily used function pointers (to save stack space)\r
+//\r
+typedef union {\r
+  PEI_CORE_ENTRY_POINT         PeiCore;\r
+  EFI_PEIM_ENTRY_POINT         PeimEntry;\r
+  EFI_PEIM_NOTIFY_ENTRY_POINT  PeimNotifyEntry;\r
+  EFI_DXE_IPL_PPI              *DxeIpl;\r
+  EFI_PEI_PPI_DESCRIPTOR       *PpiDescriptor;\r
+  EFI_PEI_NOTIFY_DESCRIPTOR    *NotifyDescriptor;\r
+  VOID                         *Raw;\r
+} PEI_CORE_TEMP_POINTERS;\r
+\r
+\r
+//\r
+// PeiCore function\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+PeiCore (\r
+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,\r
+  IN VOID                        *Data\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The entry routine to Pei Core, invoked by PeiMain during transition\r
+  from SEC to PEI. After switching stack in the PEI core, it will restart\r
+  with the old core data.\r
+\r
+Arguments:\r
+\r
+  PeiStartupDescriptor - Information and services provided by SEC phase.\r
+  OldCoreData          - Pointer to old core data that is used to initialize the\r
+                         core's data areas.\r
+\r
+Returns:\r
+\r
+  This function never returns\r
+  EFI_NOT_FOUND        - Never reach\r
+\r
+--*/\r
+;\r
+\r
+//\r
+// Dispatcher support functions\r
+//\r
+\r
+EFI_STATUS\r
+PeimDispatchReadiness (\r
+  IN EFI_PEI_SERVICES   **PeiServices,\r
+  IN VOID               *DependencyExpression,\r
+  IN OUT BOOLEAN        *Runnable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This is the POSTFIX version of the dependency evaluator.  When a\r
+  PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on\r
+  the evaluation stack.  When that entry is poped from the evaluation\r
+  stack, the PPI is checked if it is installed.  This method allows\r
+  some time savings as not all PPIs must be checked for certain\r
+  operation types (AND, OR).\r
+\r
+Arguments:\r
+\r
+  PeiServices               - Calling context.\r
+\r
+  DependencyExpression      - Pointer to a dependency expression.  The Grammar adheres to\r
+                              the BNF described above and is stored in postfix notation.\r
+  Runnable                  - is True if the driver can be scheduled and False if the driver\r
+                              cannot be scheduled.  This is the value that the schedulers\r
+                              should use for deciding the state of the driver.\r
+\r
+Returns:\r
+\r
+  Status = EFI_SUCCESS            if it is a well-formed Grammar\r
+           EFI_INVALID_PARAMETER  if the dependency expression overflows\r
+                                  the evaluation stack\r
+           EFI_INVALID_PARAMETER  if the dependency expression underflows\r
+                                  the evaluation stack\r
+           EFI_INVALID_PARAMETER  if the dependency expression is not a\r
+                                  well-formed Grammar.\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+PeiDispatcher (\r
+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,\r
+  IN PEI_CORE_INSTANCE           *PrivateData,\r
+  IN PEI_CORE_DISPATCH_DATA      *DispatchData\r
+  )\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Conduct PEIM dispatch.\r
+\r
+Arguments:\r
+\r
+  PeiStartupDescriptor - Pointer to IN EFI_PEI_STARTUP_DESCRIPTOR\r
+  PrivateData          - Pointer to the private data passed in from caller\r
+  DispatchData         - Pointer to PEI_CORE_DISPATCH_DATA data.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS   - Successfully dispatched PEIM.\r
+  EFI_NOT_FOUND - The dispatch failed.\r
+\r
+--*/\r
+;\r
+\r
+\r
+VOID\r
+InitializeDispatcherData (\r
+  IN EFI_PEI_SERVICES             **PeiServices,\r
+  IN PEI_CORE_INSTANCE            *OldCoreData,\r
+  IN EFI_PEI_STARTUP_DESCRIPTOR   *PeiStartupDescriptor\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize the Dispatcher's data members\r
+\r
+Arguments:\r
+\r
+  PeiServices          - The PEI core services table.\r
+  OldCoreData          - Pointer to old core data (before switching stack).\r
+                         NULL if being run in non-permament memory mode.\r
+  PeiStartupDescriptor - Information and services provided by SEC phase.\r
+\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+FindNextPeim (\r
+  IN EFI_PEI_SERVICES            **PeiServices,\r
+  IN EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,\r
+  IN OUT EFI_FFS_FILE_HEADER     **PeimFileHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    Given the input file pointer, search for the next matching file in the\r
+    FFS volume. The search starts from FileHeader inside\r
+    the Firmware Volume defined by FwVolHeader.\r
+\r
+Arguments:\r
+    PeiServices - Pointer to the PEI Core Services Table.\r
+\r
+    FwVolHeader - Pointer to the FV header of the volume to search.\r
+                     This parameter must point to a valid FFS volume.\r
+\r
+    PeimFileHeader  - Pointer to the current file from which to begin searching.\r
+                  This pointer will be updated upon return to reflect the file found.\r
+\r
+Returns:\r
+    EFI_NOT_FOUND - No files matching the search criteria were found\r
+    EFI_SUCCESS\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+Dispatched (\r
+  IN UINT8  CurrentPeim,\r
+  IN UINT32 DispatchedPeimBitMap\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine checks to see if a particular PEIM has been dispatched during\r
+  the PEI core dispatch.\r
+\r
+Arguments:\r
+  CurrentPeim - The PEIM/FV in the bit array to check.\r
+  DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.\r
+\r
+Returns:\r
+  TRUE if PEIM already dispatched\r
+  FALSE if not\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+SetDispatched (\r
+  IN EFI_PEI_SERVICES   **PeiServices,\r
+  IN UINT8              CurrentPeim,\r
+  OUT UINT32            *DispatchedPeimBitMap\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine sets a PEIM as having been dispatched once its entry\r
+  point has been invoked.\r
+\r
+Arguments:\r
+\r
+  PeiServices          - The PEI core services table.\r
+  CurrentPeim          - The PEIM/FV in the bit array to check.\r
+  DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.\r
+\r
+Returns:\r
+  None\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+DepexSatisfied (\r
+  IN EFI_PEI_SERVICES  **PeiServices,\r
+  IN  VOID             *CurrentPeimAddress\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine parses the Dependency Expression, if available, and\r
+  decides if the module can be executed.\r
+\r
+Arguments:\r
+  PeiServices - The PEI Service Table\r
+  CurrentPeimAddress - Address of the PEIM Firmware File under investigation\r
+\r
+Returns:\r
+  TRUE  - Can be dispatched\r
+  FALSE - Cannot be dispatched\r
+\r
+--*/\r
+;\r
+\r
+#if   defined (MDE_CPU_IPF)\r
+  //\r
+  // In Ipf we should make special changes for the PHIT pointers to support\r
+  // recovery boot in cache mode.\r
+  //\r
+#define  SWITCH_TO_CACHE_MODE(CoreData)  SwitchToCacheMode(CoreData)\r
+#define  CACHE_MODE_ADDRESS_MASK         0x7FFFFFFFFFFFFFFFULL\r
+VOID\r
+SwitchToCacheMode (\r
+  IN PEI_CORE_INSTANCE           *CoreData\r
+)\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Switch the PHIT pointers to cache mode after InstallPeiMemory in CAR.\r
+\r
+Arguments:\r
+\r
+  CoreData   - The PEI core Private Data\r
+\r
+Returns:\r
+\r
+--*/\r
+;\r
+\r
+#else\r
+\r
+#define  SWITCH_TO_CACHE_MODE(CoreData)\r
+\r
+#endif\r
+\r
+//\r
+// PPI support functions\r
+//\r
+VOID\r
+InitializePpiServices (\r
+  IN EFI_PEI_SERVICES    **PeiServices,\r
+  IN PEI_CORE_INSTANCE   *OldCoreData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize PPI services.\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+  OldCoreData - Pointer to the PEI Core data.\r
+                NULL if being run in non-permament memory mode.\r
+\r
+Returns:\r
+  Nothing\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+ConvertPpiPointers (\r
+  IN EFI_PEI_SERVICES              **PeiServices,\r
+  IN EFI_HOB_HANDOFF_INFO_TABLE    *OldHandOffHob,\r
+  IN EFI_HOB_HANDOFF_INFO_TABLE    *NewHandOffHob\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Migrate the Hob list from the CAR stack to PEI installed memory.\r
+\r
+Arguments:\r
+\r
+  PeiServices   - The PEI core services table.\r
+  OldHandOffHob - The old handoff HOB list.\r
+  NewHandOffHob - The new handoff HOB list.\r
+\r
+Returns:\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiInstallPpi (\r
+  IN EFI_PEI_SERVICES        **PeiServices,\r
+  IN EFI_PEI_PPI_DESCRIPTOR  *PpiList\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Install PPI services.\r
+\r
+Arguments:\r
+\r
+  PeiServices - Pointer to the PEI Service Table\r
+  PpiList     - Pointer to a list of PEI PPI Descriptors.\r
+\r
+Returns:\r
+\r
+    EFI_SUCCESS             - if all PPIs in PpiList are successfully installed.\r
+    EFI_INVALID_PARAMETER   - if PpiList is NULL pointer\r
+    EFI_INVALID_PARAMETER   - if any PPI in PpiList is not valid\r
+    EFI_OUT_OF_RESOURCES    - if there is no more memory resource to install PPI\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiReInstallPpi (\r
+  IN EFI_PEI_SERVICES        **PeiServices,\r
+  IN EFI_PEI_PPI_DESCRIPTOR  *OldPpi,\r
+  IN EFI_PEI_PPI_DESCRIPTOR  *NewPpi\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Re-Install PPI services.\r
+\r
+Arguments:\r
+\r
+  PeiServices - Pointer to the PEI Service Table\r
+  OldPpi      - Pointer to the old PEI PPI Descriptors.\r
+  NewPpi      - Pointer to the new PEI PPI Descriptors.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - if the operation was successful\r
+  EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL\r
+  EFI_INVALID_PARAMETER - if NewPpi is not valid\r
+  EFI_NOT_FOUND         - if the PPI was not in the database\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiLocatePpi (\r
+  IN EFI_PEI_SERVICES            **PeiServices,\r
+  IN EFI_GUID                    *Guid,\r
+  IN UINTN                       Instance,\r
+  IN OUT EFI_PEI_PPI_DESCRIPTOR  **PpiDescriptor,\r
+  IN OUT VOID                    **Ppi\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Locate a given named PPI.\r
+\r
+Arguments:\r
+\r
+  PeiServices   - Pointer to the PEI Service Table\r
+  Guid          - Pointer to GUID of the PPI.\r
+  Instance      - Instance Number to discover.\r
+  PpiDescriptor - Pointer to reference the found descriptor. If not NULL,\r
+                returns a pointer to the descriptor (includes flags, etc)\r
+  Ppi           - Pointer to reference the found PPI\r
+\r
+Returns:\r
+\r
+  Status -  EFI_SUCCESS   if the PPI is in the database\r
+            EFI_NOT_FOUND if the PPI is not in the database\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiNotifyPpi (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyList\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Install a notification for a given PPI.\r
+\r
+Arguments:\r
+\r
+  PeiServices - Pointer to the PEI Service Table\r
+  NotifyList  - Pointer to list of Descriptors to notify upon.\r
+\r
+Returns:\r
+\r
+  Status - EFI_SUCCESS          if successful\r
+           EFI_OUT_OF_RESOURCES if no space in the database\r
+           EFI_INVALID_PARAMETER if not a good decriptor\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+ProcessNotifyList (\r
+  IN EFI_PEI_SERVICES    **PeiServices\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Process the Notify List at dispatch level.\r
+\r
+Arguments:\r
+\r
+  PeiServices - Pointer to the PEI Service Table\r
+\r
+Returns:\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+DispatchNotify (\r
+  IN EFI_PEI_SERVICES    **PeiServices,\r
+  IN UINTN               NotifyType,\r
+  IN INTN                InstallStartIndex,\r
+  IN INTN                InstallStopIndex,\r
+  IN INTN                NotifyStartIndex,\r
+  IN INTN                NotifyStopIndex\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Dispatch notifications.\r
+\r
+Arguments:\r
+\r
+  PeiServices         - Pointer to the PEI Service Table\r
+  NotifyType          - Type of notify to fire.\r
+  InstallStartIndex   - Install Beginning index.\r
+  InstallStopIndex    - Install Ending index.\r
+  NotifyStartIndex    - Notify Beginning index.\r
+  NotifyStopIndex    - Notify Ending index.\r
+\r
+Returns:  None\r
+\r
+--*/\r
+;\r
+\r
+//\r
+// Boot mode support functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+PeiGetBootMode (\r
+  IN EFI_PEI_SERVICES  **PeiServices,\r
+  IN OUT EFI_BOOT_MODE *BootMode\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This service enables PEIMs to ascertain the present value of the boot mode.\r
+\r
+Arguments:\r
+\r
+  PeiServices    - The PEI core services table.\r
+  BootMode       - A pointer to contain the value of the boot mode.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The boot mode was returned successfully.\r
+  EFI_INVALID_PARAMETER - BootMode is NULL.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiSetBootMode (\r
+  IN EFI_PEI_SERVICES  **PeiServices,\r
+  IN EFI_BOOT_MODE     BootMode\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This service enables PEIMs to update the boot mode variable.\r
+\r
+Arguments:\r
+\r
+  PeiServices    - The PEI core services table.\r
+  BootMode       - The value of the boot mode to set.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS    - The value was successfully updated\r
+\r
+--*/\r
+;\r
+\r
+//\r
+// Security support functions\r
+//\r
+VOID\r
+InitializeSecurityServices (\r
+  IN EFI_PEI_SERVICES  **PeiServices,\r
+  IN PEI_CORE_INSTANCE *OldCoreData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize the security services.\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+  OldCoreData - Pointer to the old core data.\r
+                NULL if being run in non-permament memory mode.\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+VerifyFv (\r
+  IN EFI_FIRMWARE_VOLUME_HEADER  *CurrentFvAddress\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Provide a callout to the OEM FV verification service.\r
+\r
+Arguments:\r
+\r
+  CurrentFvAddress       - Pointer to the FV under investigation.\r
+\r
+Returns:\r
+\r
+  Status - EFI_SUCCESS\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+VerifyPeim (\r
+  IN EFI_PEI_SERVICES     **PeiServices,\r
+  IN EFI_FFS_FILE_HEADER  *CurrentPeimAddress\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Provide a callout to the security verification service.\r
+\r
+Arguments:\r
+\r
+  PeiServices          - The PEI core services table.\r
+  CurrentPeimAddress   - Pointer to the Firmware File under investigation.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             - Image is OK\r
+  EFI_SECURITY_VIOLATION  - Image is illegal\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiGetHobList (\r
+  IN EFI_PEI_SERVICES  **PeiServices,\r
+  IN OUT VOID          **HobList\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Gets the pointer to the HOB List.\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+  HobList     - Pointer to the HOB List.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS                 - Get the pointer of HOB List\r
+  EFI_NOT_AVAILABLE_YET       - the HOB List is not yet published\r
+  EFI_INVALID_PARAMETER       - HobList is NULL (in debug mode)\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiCreateHob (\r
+  IN EFI_PEI_SERVICES  **PeiServices,\r
+  IN UINT16            Type,\r
+  IN UINT16            Length,\r
+  IN OUT VOID          **Hob\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Add a new HOB to the HOB List.\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+  Type        - Type of the new HOB.\r
+  Length      - Length of the new HOB to allocate.\r
+  Hob         - Pointer to the new HOB.\r
+\r
+Returns:\r
+\r
+  Status  - EFI_SUCCESS\r
+          - EFI_INVALID_PARAMETER if Hob is NULL\r
+          - EFI_NOT_AVAILABLE_YET if HobList is still not available.\r
+          - EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PeiCoreBuildHobHandoffInfoTable (\r
+  IN EFI_BOOT_MODE         BootMode,\r
+  IN EFI_PHYSICAL_ADDRESS  MemoryBegin,\r
+  IN UINT64                MemoryLength\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Builds a Handoff Information Table HOB\r
+\r
+Arguments:\r
+\r
+  BootMode      - Current Bootmode\r
+  MemoryBegin   - Start Memory Address.\r
+  MemoryLength  - Length of Memory.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS\r
+\r
+--*/\r
+;\r
+\r
+\r
+//\r
+// FFS Fw Volume support functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+PeiFfsFindNextFile (\r
+  IN EFI_PEI_SERVICES            **PeiServices,\r
+  IN UINT8                       SearchType,\r
+  IN EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,\r
+  IN OUT EFI_FFS_FILE_HEADER     **FileHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    Given the input file pointer, search for the next matching file in the\r
+    FFS volume as defined by SearchType. The search starts from FileHeader inside\r
+    the Firmware Volume defined by FwVolHeader.\r
+\r
+Arguments:\r
+    PeiServices - Pointer to the PEI Core Services Table.\r
+\r
+    SearchType - Filter to find only files of this type.\r
+      Type EFI_FV_FILETYPE_ALL causes no filtering to be done.\r
+\r
+    FwVolHeader - Pointer to the FV header of the volume to search.\r
+      This parameter must point to a valid FFS volume.\r
+\r
+    FileHeader  - Pointer to the current file from which to begin searching.\r
+      This pointer will be updated upon return to reflect the file found.\r
+\r
+Returns:\r
+    EFI_NOT_FOUND - No files matching the search criteria were found\r
+    EFI_SUCCESS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiFfsFindSectionData (\r
+  IN EFI_PEI_SERVICES            **PeiServices,\r
+  IN EFI_SECTION_TYPE            SectionType,\r
+  IN EFI_FFS_FILE_HEADER         *FfsFileHeader,\r
+  IN OUT VOID                    **SectionData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    Given the input file pointer, search for the next matching section in the\r
+    FFS volume.\r
+\r
+Arguments:\r
+    PeiServices - Pointer to the PEI Core Services Table.\r
+    SearchType - Filter to find only sections of this type.\r
+    FfsFileHeader  - Pointer to the current file to search.\r
+    SectionData - Pointer to the Section matching SectionType in FfsFileHeader.\r
+                - NULL if section not found\r
+\r
+Returns:\r
+    EFI_NOT_FOUND - No files matching the search criteria were found\r
+    EFI_SUCCESS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiFvFindNextVolume (\r
+  IN EFI_PEI_SERVICES                **PeiServices,\r
+  IN UINTN                           Instance,\r
+  IN OUT EFI_FIRMWARE_VOLUME_HEADER  **FwVolHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Return the BFV location\r
+\r
+  BugBug -- Move this to the location of this code to where the\r
+  other FV and FFS support code lives.\r
+  Also, update to use FindFV for instances #'s >= 1.\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+  Instance    - Instance of FV to find\r
+  FwVolHeader - Pointer to contain the data to return\r
+\r
+Returns:\r
+  Pointer to the Firmware Volume instance requested\r
+\r
+  EFI_INVALID_PARAMETER     - FwVolHeader is NULL\r
+\r
+  EFI_SUCCESS               - Firmware volume instance successfully found.\r
+\r
+--*/\r
+;\r
+\r
+//\r
+// Memory support functions\r
+//\r
+VOID\r
+InitializeMemoryServices (\r
+  IN EFI_PEI_SERVICES            **PeiServices,\r
+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,\r
+  IN PEI_CORE_INSTANCE           *OldCoreData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize the memory services.\r
+\r
+Arguments:\r
+\r
+  PeiServices          - The PEI core services table.\r
+  PeiStartupDescriptor - Information and services provided by SEC phase.\r
+  OldCoreData          - Pointer to the PEI Core data.\r
+                         NULL if being run in non-permament memory mode.\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiInstallPeiMemory (\r
+  IN EFI_PEI_SERVICES      **PeiServices,\r
+  IN EFI_PHYSICAL_ADDRESS  MemoryBegin,\r
+  IN UINT64                MemoryLength\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Install the permanent memory is now available.\r
+  Creates HOB (PHIT and Stack).\r
+\r
+Arguments:\r
+\r
+  PeiServices   - The PEI core services table.\r
+  MemoryBegin   - Start of memory address.\r
+  MemoryLength  - Length of memory.\r
+\r
+Returns:\r
+\r
+  Status  - EFI_SUCCESS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiAllocatePages (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_MEMORY_TYPE            MemoryType,\r
+  IN UINTN                      Pages,\r
+  OUT EFI_PHYSICAL_ADDRESS      *Memory\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Memory allocation service on permanent memory,\r
+  not usable prior to the memory installation.\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+  Type        - Type of allocation.\r
+  MemoryType  - Type of memory to allocate.\r
+  Pages       - Number of pages to allocate.\r
+  Memory      - Pointer of memory allocated.\r
+\r
+Returns:\r
+\r
+  Status - EFI_SUCCESS              The allocation was successful\r
+           EFI_INVALID_PARAMETER    Only AllocateAnyAddress is supported.\r
+           EFI_NOT_AVAILABLE_YET    Called with permanent memory not available\r
+           EFI_OUT_OF_RESOURCES     There is not enough HOB heap to satisfy the requirement\r
+                                    to allocate the number of pages.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiAllocatePool (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN UINTN                      Size,\r
+  OUT VOID                      **Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Memory allocation service on the CAR.\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+\r
+  Size        - Amount of memory required\r
+\r
+  Buffer      - Address of pointer to the buffer\r
+\r
+Returns:\r
+\r
+  Status - EFI_SUCCESS              The allocation was successful\r
+           EFI_OUT_OF_RESOURCES     There is not enough heap to satisfy the requirement\r
+                                    to allocate the requested size.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PeiLoadImage (\r
+  IN  EFI_PEI_SERVICES            **PeiServices,\r
+  IN  EFI_FFS_FILE_HEADER         *PeimFileHeader,\r
+  OUT VOID                        **EntryPoint\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get entry point of a Peim file.\r
+\r
+Arguments:\r
+\r
+  PeiServices                 - Calling context.\r
+\r
+  PeimFileHeader              - Peim file's header.\r
+\r
+  EntryPoint                  - Entry point of that Peim file.\r
+\r
+Returns:\r
+\r
+  Status code.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiReportStatusCode (\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
+  Core version of the Status Code reporter\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+\r
+  CodeType    - Type of Status Code.\r
+\r
+  Value       - Value to output for Status Code.\r
+\r
+  Instance    - Instance Number of this status code.\r
+\r
+  CallerId    - ID of the caller of this status code.\r
+\r
+  Data        - Optional data associated with this status code.\r
+\r
+Returns:\r
+\r
+  Status  - EFI_SUCCESS             if status code is successfully reported\r
+          - EFI_NOT_AVAILABLE_YET   if StatusCodePpi has not been installed\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiResetSystem (\r
+  IN EFI_PEI_SERVICES   **PeiServices\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Core version of the Reset System\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+\r
+Returns:\r
+\r
+  Status  - EFI_NOT_AVAILABLE_YET. PPI not available yet.\r
+          - EFI_DEVICE_ERROR.   Did not reset system.\r
+\r
+  Otherwise, resets the system.\r
+\r
+--*/\r
+;\r
+\r
+/**\r
+  Transfers control to a function starting with a new stack.\r
+\r
+  Transfers control to the function specified by EntryPoint using the new stack\r
+  specified by NewStack and passing in the parameters specified by Context1 and\r
+  Context2. Context1 and Context2 are optional and may be NULL. The function\r
+  EntryPoint must never return.\r
+\r
+  If EntryPoint is NULL, then ASSERT().\r
+  If NewStack is NULL, then ASSERT().\r
+\r
+  @param  EntryPoint  A pointer to function to call with the new stack.\r
+  @param  Context1    A pointer to the context to pass into the EntryPoint\r
+                      function.\r
+  @param  Context2    A pointer to the context to pass into the EntryPoint\r
+                      function.\r
+  @param  NewStack    A pointer to the new stack to use for the EntryPoint\r
+                      function.\r
+  @param  NewBsp      A pointer to the new BSP for the EntryPoint on IPF. It's\r
+                      Reserved on other architectures.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PeiSwitchStacks (\r
+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,\r
+  IN      VOID                      *Context1,  OPTIONAL\r
+  IN      VOID                      *Context2,  OPTIONAL\r
+  IN      VOID                      *NewStack,\r
+  IN      VOID                      *NewBsp\r
+  );\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf
new file mode 100644 (file)
index 0000000..61641e3
--- /dev/null
@@ -0,0 +1,146 @@
+#/** @file\r
+# Component description file for PeiMain module\r
+#\r
+# This module provide an DXE CIS compliant implementation.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\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
+#  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
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PeiMain\r
+  FILE_GUID                      = 52C05B14-0B98-496c-BC3B-04B50211D680\r
+  MODULE_TYPE                    = PEI_CORE\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = PeiCore\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  StatusCode/StatusCode.c\r
+  Security/Security.c\r
+  Reset/Reset.c\r
+  Ppi/Ppi.c\r
+  PeiMain/PeiMain.c\r
+  Memory/MemoryServices.c\r
+  Image/Image.c\r
+  Hob/Hob.c\r
+  FwVol/FwVol.c\r
+  Dispatcher/Dispatcher.c\r
+  Dependency/dependency.c\r
+  Dependency/dependency.h\r
+  BootMode/BootMode.c\r
+  PeiMain.h\r
+  CommonHeader.h\r
+\r
+[Sources.Ia32]\r
+  Dispatcher/Stack.c\r
+\r
+[Sources.X64]\r
+  Dispatcher/Stack.c\r
+\r
+[Sources.IPF]\r
+  Ipf/Stack.c\r
+  Ipf/IpfPeiMain.h\r
+  Ipf/IpfCpuCore.s\r
+  Ipf/IpfCpuCore.i\r
+  Ipf/SwitchToCacheMode.c\r
+\r
+[Sources.EBC]\r
+  Dispatcher/Stack.c\r
+\r
+\r
+################################################################################\r
+#\r
+# Includes Section - list of Include locations that are required for\r
+#                    this module.\r
+#\r
+################################################################################\r
+\r
+[Includes]\r
+  $(WORKSPACE)/MdePkg\Include/Library\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  MdePkg/MdePkg.dec\r
+  IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  TimerLib\r
+  BaseMemoryLib\r
+  PeCoffGetEntryPointLib\r
+  ReportStatusCodeLib\r
+  PeiServicesLib\r
+  PerformanceLib\r
+  HobLib\r
+  BaseLib\r
+  PeiCoreEntryPoint\r
+  DebugLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Guid C Name Section - list of Guids that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Guids]\r
+  gEfiPeiCorePrivateGuid                        # PRIVATE\r
+\r
+\r
+################################################################################\r
+#\r
+# PPI C Name Section - list of PPI and PPI Notify C Names that this module\r
+#                      uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Ppis]\r
+  gEfiPeiSecurityPpiGuid                        # PPI_NOTIFY SOMETIMES_CONSUMED\r
+  gEfiPeiStatusCodePpiGuid                      # PPI SOMETIMES_CONSUMED\r
+  gEfiPeiResetPpiGuid                           # PPI SOMETIMES_CONSUMED\r
+  gEfiDxeIplPpiGuid                             # PPI ALWAYS_CONSUMED\r
+  gEfiPeiFvFileLoaderPpiGuid                    # PPI ALWAYS_CONSUMED\r
+  gEfiFindFvPpiGuid                             # PPI ALWAYS_CONSUMED\r
+  gEfiPeiMemoryDiscoveredPpiGuid                # PPI ALWAYS_PRODUCED\r
+\r
diff --git a/MdeModulePkg/Core/Pei/PeiMain.msa b/MdeModulePkg/Core/Pei/PeiMain.msa
new file mode 100644 (file)
index 0000000..b8873a8
--- /dev/null
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+  <MsaHeader>\r
+    <ModuleName>PeiMain</ModuleName>\r
+    <ModuleType>PEI_CORE</ModuleType>\r
+    <GuidValue>52C05B14-0B98-496c-BC3B-04B50211D680</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component description file for PeiMain module</Abstract>\r
+    <Description>This module provide an DXE CIS compliant implementation.</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+    <License>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
+      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.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>PeiMain</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DebugLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>PeiCoreEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>HobLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>PerformanceLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>PeiServicesLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>ReportStatusCodeLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>PeCoffGetEntryPointLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>TimerLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>PeiMain.h</Filename>\r
+    <Filename>BootMode/BootMode.c</Filename>\r
+    <Filename>Dependency/dependency.h</Filename>\r
+    <Filename>Dependency/dependency.c</Filename>\r
+    <Filename>Dispatcher/Dispatcher.c</Filename>\r
+    <Filename>FwVol/FwVol.c</Filename>\r
+    <Filename>Hob/Hob.c</Filename>\r
+    <Filename>Image/Image.c</Filename>\r
+    <Filename>Memory/MemoryServices.c</Filename>\r
+    <Filename>PeiMain/PeiMain.c</Filename>\r
+    <Filename>Ppi/Ppi.c</Filename>\r
+    <Filename>Reset/Reset.c</Filename>\r
+    <Filename>Security/Security.c</Filename>\r
+    <Filename>StatusCode/StatusCode.c</Filename>\r
+    <Filename SupArchList="IPF">Ipf/SwitchToCacheMode.c</Filename>\r
+    <Filename SupArchList="IPF">Ipf/IpfCpuCore.i</Filename>\r
+    <Filename SupArchList="IPF">Ipf/IpfCpuCore.s</Filename>\r
+    <Filename SupArchList="IPF">Ipf/IpfPeiMain.h</Filename>\r
+    <Filename SupArchList="IPF">Ipf/Stack.c</Filename>\r
+    <Filename SupArchList="IA32 X64 EBC">Dispatcher/Stack.c</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+  </PackageDependencies>\r
+  <PPIs>\r
+    <Ppi Usage="ALWAYS_PRODUCED">\r
+      <PpiCName>gEfiPeiMemoryDiscoveredPpiGuid</PpiCName>\r
+    </Ppi>\r
+    <Ppi Usage="ALWAYS_CONSUMED">\r
+      <PpiCName>gEfiFindFvPpiGuid</PpiCName>\r
+    </Ppi>\r
+    <Ppi Usage="ALWAYS_CONSUMED">\r
+      <PpiCName>gEfiPeiFvFileLoaderPpiGuid</PpiCName>\r
+    </Ppi>\r
+    <Ppi Usage="ALWAYS_CONSUMED">\r
+      <PpiCName>gEfiDxeIplPpiGuid</PpiCName>\r
+    </Ppi>\r
+    <Ppi Usage="SOMETIMES_CONSUMED">\r
+      <PpiCName>gEfiPeiResetPpiGuid</PpiCName>\r
+    </Ppi>\r
+    <Ppi Usage="SOMETIMES_CONSUMED">\r
+      <PpiCName>gEfiPeiStatusCodePpiGuid</PpiCName>\r
+    </Ppi>\r
+    <PpiNotify Usage="SOMETIMES_CONSUMED">\r
+      <PpiNotifyCName>gEfiPeiSecurityPpiGuid</PpiNotifyCName>\r
+    </PpiNotify>\r
+  </PPIs>\r
+  <Guids>\r
+    <GuidCNames Usage="PRIVATE">\r
+      <GuidCName>gEfiPeiCorePrivateGuid</GuidCName>\r
+    </GuidCNames>\r
+  </Guids>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <ModuleEntryPoint>PeiCore</ModuleEntryPoint>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>\r
diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
new file mode 100644 (file)
index 0000000..db4a69f
--- /dev/null
@@ -0,0 +1,251 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  PeiMain.c\r
+\r
+Abstract:\r
+\r
+  Pei Core Main Entry Point\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <PeiMain.h>\r
+\r
+//\r
+//CAR is filled with this initial value during SEC phase\r
+//\r
+#define INIT_CAR_VALUE 0x5AA55AA5\r
+\r
+static EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEfiPeiMemoryDiscoveredPpiGuid,\r
+  NULL\r
+};\r
+\r
+//\r
+// Pei Core Module Variables\r
+//\r
+//\r
+static EFI_PEI_SERVICES  mPS = {\r
+  {\r
+    PEI_SERVICES_SIGNATURE,\r
+    PEI_SERVICES_REVISION,\r
+    sizeof (EFI_PEI_SERVICES),\r
+    0,\r
+    0\r
+  },\r
+  PeiInstallPpi,\r
+  PeiReInstallPpi,\r
+  PeiLocatePpi,\r
+  PeiNotifyPpi,\r
+\r
+  PeiGetBootMode,\r
+  PeiSetBootMode,\r
+\r
+  PeiGetHobList,\r
+  PeiCreateHob,\r
+\r
+  PeiFvFindNextVolume,\r
+  PeiFfsFindNextFile,\r
+  PeiFfsFindSectionData,\r
+\r
+  PeiInstallPeiMemory,\r
+  PeiAllocatePages,\r
+  PeiAllocatePool,\r
+  (EFI_PEI_COPY_MEM)CopyMem,\r
+  (EFI_PEI_SET_MEM)SetMem,\r
+\r
+  PeiReportStatusCode,\r
+\r
+  PeiResetSystem\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiCore (\r
+  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,\r
+  IN VOID                        *Data\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The entry routine to Pei Core, invoked by PeiMain during transition\r
+  from SEC to PEI. After switching stack in the PEI core, it will restart\r
+  with the old core data.\r
+\r
+Arguments:\r
+\r
+  PeiStartupDescriptor - Information and services provided by SEC phase.\r
+  OldCoreData          - Pointer to old core data that is used to initialize the\r
+                         core's data areas.\r
+\r
+Returns:\r
+\r
+  This function never returns\r
+  EFI_NOT_FOUND        - Never reach\r
+\r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE                                     PrivateData;\r
+  EFI_STATUS                                            Status;\r
+  PEI_CORE_TEMP_POINTERS                                TempPtr;\r
+  PEI_CORE_DISPATCH_DATA                                *DispatchData;\r
+  UINT64                                                mTick;\r
+  PEI_CORE_INSTANCE                                     *OldCoreData;\r
+\r
+  mTick = 0;\r
+  OldCoreData = (PEI_CORE_INSTANCE *) Data;\r
+\r
+  if (PerformanceMeasurementEnabled()) {\r
+    if (OldCoreData == NULL) {\r
+      mTick = GetPerformanceCounter ();\r
+    }\r
+  }\r
+\r
+  //\r
+  // For IPF in CAR mode the real memory access is uncached,in InstallPeiMemory()\r
+  //  the 63-bit of address is set to 1.\r
+  //\r
+  SWITCH_TO_CACHE_MODE (OldCoreData);\r
+\r
+  if (OldCoreData != NULL) {\r
+    CopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));\r
+  } else {\r
+    ZeroMem (&PrivateData, sizeof (PEI_CORE_INSTANCE));\r
+  }\r
+\r
+  PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;\r
+  PrivateData.PS = &mPS;\r
+\r
+  //\r
+  // Initialize libraries that the PeiCore is linked against\r
+  // BUGBUG: The FfsHeader is passed in as NULL.  Do we look it up or remove it from the lib init?\r
+  //\r
+  ProcessLibraryConstructorList (NULL, &PrivateData.PS);\r
+\r
+  InitializeMemoryServices (&PrivateData.PS, PeiStartupDescriptor, OldCoreData);\r
+\r
+  InitializePpiServices (&PrivateData.PS, OldCoreData);\r
+\r
+  InitializeSecurityServices (&PrivateData.PS, OldCoreData);\r
+\r
+  InitializeDispatcherData (&PrivateData.PS, OldCoreData, PeiStartupDescriptor);\r
+\r
+  if (OldCoreData != NULL) {\r
+\r
+    PERF_END (NULL,"PreMem", NULL, 0);\r
+    PERF_START (NULL,"PostMem", NULL, 0);\r
+\r
+    //\r
+    // The following code dumps out interesting cache as RAM usage information\r
+    // so we can keep tabs on how the cache as RAM is being utilized.  The\r
+    // DEBUG_CODE_BEGIN macro is used to prevent this code from being compiled\r
+    // on a debug build.\r
+    //\r
+    DEBUG_CODE_BEGIN ();\r
+      UINTN  *StackPointer;\r
+      UINTN  StackValue;\r
+\r
+      StackValue = INIT_CAR_VALUE;\r
+      for (StackPointer = (UINTN *) OldCoreData->MaxTopOfCarHeap;\r
+           ((UINTN) StackPointer < ((UINTN) OldCoreData->BottomOfCarHeap + OldCoreData->SizeOfCacheAsRam))\r
+           && StackValue == INIT_CAR_VALUE;\r
+           StackPointer++) {\r
+        StackValue = *StackPointer;\r
+      }\r
+\r
+      DEBUG ((EFI_D_INFO, "Total Cache as RAM:    %d bytes.\n", OldCoreData->SizeOfCacheAsRam));\r
+      DEBUG ((EFI_D_INFO, "  CAR stack ever used: %d bytes.\n",\r
+        ((UINTN) OldCoreData->TopOfCarHeap - (UINTN) StackPointer)\r
+        ));\r
+      DEBUG ((EFI_D_INFO, "  CAR heap used:       %d bytes.\n",\r
+        ((UINTN) OldCoreData->HobList.HandoffInformationTable->EfiFreeMemoryBottom -\r
+        (UINTN) OldCoreData->HobList.Raw)\r
+        ));\r
+    DEBUG_CODE_END ();\r
+\r
+    //\r
+    // Alert any listeners that there is permanent memory available\r
+    //\r
+    \r
+    PERF_START (NULL,"DisMem", NULL, 0);\r
+    Status = PeiServicesInstallPpi (&mMemoryDiscoveredPpi);\r
+    PERF_END (NULL,"DisMem", NULL, 0);\r
+\r
+  } else {\r
+\r
+    //\r
+    // Report Status Code EFI_SW_PC_INIT\r
+    //\r
+    REPORT_STATUS_CODE (\r
+      EFI_PROGRESS_CODE,\r
+      EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT\r
+      );\r
+\r
+    PERF_START (NULL,"PEI", NULL, mTick);\r
+    //\r
+    // If first pass, start performance measurement.\r
+    //\r
+    PERF_START (NULL,"PreMem", NULL, mTick);\r
+\r
+    //\r
+    // If SEC provided any PPI services to PEI, install them.\r
+    //\r
+    if (PeiStartupDescriptor->DispatchTable != NULL) {\r
+      Status = PeiServicesInstallPpi (PeiStartupDescriptor->DispatchTable);\r
+      ASSERT_EFI_ERROR (Status);\r
+    }\r
+  }\r
+\r
+  DispatchData = &PrivateData.DispatchData;\r
+\r
+  //\r
+  // Call PEIM dispatcher\r
+  //\r
+  PeiDispatcher (PeiStartupDescriptor, &PrivateData, DispatchData);\r
+\r
+  //\r
+  // Check if InstallPeiMemory service was called.\r
+  //\r
+  ASSERT(PrivateData.PeiMemoryInstalled == TRUE);\r
+\r
+  PERF_END (NULL, "PostMem", NULL, 0);\r
+\r
+  Status = PeiServicesLocatePpi (\r
+             &gEfiDxeIplPpiGuid,\r
+             0,\r
+             NULL,\r
+             (VOID **)&TempPtr.DxeIpl\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  DEBUG ((EFI_D_INFO, "DXE IPL Entry\n"));\r
+  Status = TempPtr.DxeIpl->Entry (\r
+                             TempPtr.DxeIpl,\r
+                             &PrivateData.PS,\r
+                             PrivateData.HobList\r
+                             );\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c b/MdeModulePkg/Core/Pei/Ppi/Ppi.c
new file mode 100644 (file)
index 0000000..0f119c7
--- /dev/null
@@ -0,0 +1,663 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  Ppi.c\r
+\r
+Abstract:\r
+\r
+  EFI PEI Core PPI services\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <PeiMain.h>\r
+\r
+VOID\r
+InitializePpiServices (\r
+  IN EFI_PEI_SERVICES  **PeiServices,\r
+  IN PEI_CORE_INSTANCE *OldCoreData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize PPI services.\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+  OldCoreData - Pointer to the PEI Core data.\r
+                NULL if being run in non-permament memory mode.\r
+\r
+Returns:\r
+  Nothing\r
+\r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE                    *PrivateData;\r
+  \r
+  if (OldCoreData == NULL) {\r
+    PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
+\r
+    PrivateData->PpiData.NotifyListEnd = MAX_PPI_DESCRIPTORS-1;\r
+    PrivateData->PpiData.DispatchListEnd = MAX_PPI_DESCRIPTORS-1;\r
+    PrivateData->PpiData.LastDispatchedNotify = MAX_PPI_DESCRIPTORS-1;\r
+  }\r
\r
+  return;   \r
+}\r
+\r
+VOID\r
+ConvertPpiPointers (\r
+  IN EFI_PEI_SERVICES                     **PeiServices,\r
+  IN EFI_HOB_HANDOFF_INFO_TABLE    *OldHandOffHob,\r
+  IN EFI_HOB_HANDOFF_INFO_TABLE    *NewHandOffHob\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Migrate the Hob list from the CAR stack to PEI installed memory.\r
+\r
+Arguments:\r
+\r
+  PeiServices   - The PEI core services table.\r
+  OldHandOffHob - The old handoff HOB list.\r
+  NewHandOffHob - The new handoff HOB list.\r
+\r
+Returns:\r
+            \r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE     *PrivateData;\r
+  UINT8                 Index;\r
+  PEI_PPI_LIST_POINTERS *PpiPointer;\r
+  UINTN                 Fixup;\r
+\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
+\r
+  Fixup = (UINTN)NewHandOffHob - (UINTN)OldHandOffHob;\r
+  \r
+  for (Index = 0; Index < MAX_PPI_DESCRIPTORS; Index++) {\r
+    if (Index < PrivateData->PpiData.PpiListEnd ||\r
+        Index > PrivateData->PpiData.NotifyListEnd) {\r
+      PpiPointer = &PrivateData->PpiData.PpiListPtrs[Index];\r
+      \r
+      if (((UINTN)PpiPointer->Raw < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) && \r
+          ((UINTN)PpiPointer->Raw >= (UINTN)OldHandOffHob)) {\r
+        //\r
+        // Convert the pointer to the PEIM descriptor from the old HOB heap\r
+        // to the relocated HOB heap.\r
+        //\r
+        PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Fixup);\r
+\r
+        //\r
+        // Only when the PEIM descriptor is in the old HOB should it be necessary\r
+        // to try to convert the pointers in the PEIM descriptor\r
+        //\r
+        \r
+        if (((UINTN)PpiPointer->Ppi->Guid < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) && \r
+            ((UINTN)PpiPointer->Ppi->Guid >= (UINTN)OldHandOffHob)) {\r
+          //\r
+          // Convert the pointer to the GUID in the PPI or NOTIFY descriptor\r
+          // from the old HOB heap to the relocated HOB heap.\r
+          //\r
+          PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Fixup);\r
+        }\r
+\r
+        //\r
+        // Assume that no code is located in the temporary memory, so the pointer to\r
+        // the notification function in the NOTIFY descriptor needs not be converted.\r
+        //\r
+        if (Index < PrivateData->PpiData.PpiListEnd &&\r
+            (UINTN)PpiPointer->Ppi->Ppi < (UINTN)OldHandOffHob->EfiFreeMemoryBottom &&\r
+            (UINTN)PpiPointer->Ppi->Ppi >= (UINTN)OldHandOffHob) {\r
+            //\r
+            // Convert the pointer to the PPI interface structure in the PPI descriptor\r
+            // from the old HOB heap to the relocated HOB heap.\r
+            //\r
+            PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi+ Fixup);   \r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiInstallPpi (\r
+  IN EFI_PEI_SERVICES        **PeiServices,\r
+  IN EFI_PEI_PPI_DESCRIPTOR  *PpiList\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Install PPI services.\r
+\r
+Arguments:\r
+\r
+  PeiServices - Pointer to the PEI Service Table\r
+  PpiList     - Pointer to a list of PEI PPI Descriptors.\r
+\r
+Returns:\r
+\r
+    EFI_SUCCESS             - if all PPIs in PpiList are successfully installed.\r
+    EFI_INVALID_PARAMETER   - if PpiList is NULL pointer\r
+    EFI_INVALID_PARAMETER   - if any PPI in PpiList is not valid\r
+    EFI_OUT_OF_RESOURCES    - if there is no more memory resource to install PPI\r
+\r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE *PrivateData;\r
+  INTN              Index;\r
+  INTN              LastCallbackInstall;\r
+\r
+\r
+  if (PpiList == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
+\r
+  Index = PrivateData->PpiData.PpiListEnd;\r
+  LastCallbackInstall = Index;\r
+\r
+  //\r
+  // This is loop installs all PPI descriptors in the PpiList.  It is terminated\r
+  // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last\r
+  // EFI_PEI_PPI_DESCRIPTOR in the list.\r
+  //\r
+    \r
+  for (;;) {\r
+    //\r
+    // Since PpiData is used for NotifyList and InstallList, max resource\r
+    // is reached if the Install reaches the NotifyList\r
+    //\r
+    if (Index == PrivateData->PpiData.NotifyListEnd + 1) {\r
+      return  EFI_OUT_OF_RESOURCES;\r
+    }\r
+    //\r
+    // Check if it is a valid PPI. \r
+    // If not, rollback list to exclude all in this list.\r
+    // Try to indicate which item failed.\r
+    //\r
+    if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {\r
+      PrivateData->PpiData.PpiListEnd = LastCallbackInstall;\r
+      DEBUG((EFI_D_ERROR, "ERROR -> InstallPpi: %g %x\n", PpiList->Guid, PpiList->Ppi));\r
+      return  EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    DEBUG((EFI_D_INFO, "Install PPI: %g\n", PpiList->Guid)); \r
+    PrivateData->PpiData.PpiListPtrs[Index].Ppi = PpiList;    \r
+    PrivateData->PpiData.PpiListEnd++;\r
+    \r
+    //\r
+    // Continue until the end of the PPI List.\r
+    //\r
+    if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==  \r
+        EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {\r
+      break;\r
+    }\r
+    PpiList++;\r
+    Index++;\r
+  }\r
+\r
+  //\r
+  // Dispatch any callback level notifies for newly installed PPIs.\r
+  //\r
+  DispatchNotify (\r
+    PeiServices,\r
+    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
+    LastCallbackInstall,\r
+    PrivateData->PpiData.PpiListEnd,\r
+    PrivateData->PpiData.DispatchListEnd,                 \r
+    PrivateData->PpiData.NotifyListEnd\r
+    );\r
+\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiReInstallPpi (\r
+  IN EFI_PEI_SERVICES        **PeiServices,\r
+  IN EFI_PEI_PPI_DESCRIPTOR  *OldPpi,\r
+  IN EFI_PEI_PPI_DESCRIPTOR  *NewPpi\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Re-Install PPI services.\r
+\r
+Arguments:\r
+\r
+  PeiServices - Pointer to the PEI Service Table\r
+  OldPpi      - Pointer to the old PEI PPI Descriptors.\r
+  NewPpi      - Pointer to the new PEI PPI Descriptors.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - if the operation was successful\r
+  EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL\r
+  EFI_INVALID_PARAMETER - if NewPpi is not valid\r
+  EFI_NOT_FOUND         - if the PPI was not in the database\r
+\r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE   *PrivateData;\r
+  INTN                Index;\r
+\r
+\r
+  if ((OldPpi == NULL) || (NewPpi == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {\r
+    return  EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
+\r
+  //\r
+  // Find the old PPI instance in the database.  If we can not find it,\r
+  // return the EFI_NOT_FOUND error.\r
+  //\r
+  for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {\r
+    if (OldPpi == PrivateData->PpiData.PpiListPtrs[Index].Ppi) {\r
+      break;\r
+    }\r
+  }\r
+  if (Index == PrivateData->PpiData.PpiListEnd) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Remove the old PPI from the database, add the new one.\r
+  // \r
+  DEBUG((EFI_D_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));\r
+  PrivateData->PpiData.PpiListPtrs[Index].Ppi = NewPpi;\r
+\r
+  //\r
+  // Dispatch any callback level notifies for the newly installed PPI.\r
+  //\r
+  DispatchNotify (\r
+    PeiServices,\r
+    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
+    Index,\r
+    Index+1,\r
+    PrivateData->PpiData.DispatchListEnd,                 \r
+    PrivateData->PpiData.NotifyListEnd\r
+    );\r
+\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiLocatePpi (\r
+  IN EFI_PEI_SERVICES        **PeiServices,\r
+  IN EFI_GUID                *Guid,\r
+  IN UINTN                   Instance,\r
+  IN OUT EFI_PEI_PPI_DESCRIPTOR  **PpiDescriptor,\r
+  IN OUT VOID                **Ppi\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Locate a given named PPI.\r
+\r
+Arguments:\r
+\r
+  PeiServices   - Pointer to the PEI Service Table\r
+  Guid          - Pointer to GUID of the PPI.\r
+  Instance      - Instance Number to discover.\r
+  PpiDescriptor - Pointer to reference the found descriptor. If not NULL,\r
+                returns a pointer to the descriptor (includes flags, etc)\r
+  Ppi           - Pointer to reference the found PPI\r
+\r
+Returns:\r
+\r
+  Status -  EFI_SUCCESS   if the PPI is in the database           \r
+            EFI_NOT_FOUND if the PPI is not in the database\r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE   *PrivateData;\r
+  INTN                Index;\r
+  EFI_GUID            *CheckGuid;\r
+  EFI_PEI_PPI_DESCRIPTOR  *TempPtr;\r
+\r
+  \r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
+\r
+  //\r
+  // Search the data base for the matching instance of the GUIDed PPI.\r
+  //\r
+  for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {\r
+    TempPtr = PrivateData->PpiData.PpiListPtrs[Index].Ppi;\r
+    CheckGuid = TempPtr->Guid;\r
+\r
+    //\r
+    // Don't use CompareGuid function here for performance reasons.\r
+    // Instead we compare the GUID as INT32 at a time and branch\r
+    // on the first failed comparison.\r
+    //\r
+    if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) &&\r
+        (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) &&\r
+        (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) &&\r
+        (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3])) {\r
+      if (Instance == 0) {\r
+\r
+        if (PpiDescriptor != NULL) {\r
+          *PpiDescriptor = TempPtr;\r
+        }\r
+\r
+        if (Ppi != NULL) {\r
+          *Ppi = TempPtr->Ppi;\r
+        }\r
+\r
+\r
+        return EFI_SUCCESS;\r
+      }\r
+      Instance--;\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiNotifyPpi (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyList\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Install a notification for a given PPI.\r
+\r
+Arguments:\r
+\r
+  PeiServices - Pointer to the PEI Service Table\r
+  NotifyList  - Pointer to list of Descriptors to notify upon.\r
+\r
+Returns:\r
+\r
+  Status - EFI_SUCCESS           if successful\r
+           EFI_OUT_OF_RESOURCES  if no space in the database\r
+           EFI_INVALID_PARAMETER if not a good decriptor\r
+\r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE                *PrivateData;\r
+  INTN                             Index;\r
+  INTN                             NotifyIndex;\r
+  INTN                             LastCallbackNotify;\r
+  EFI_PEI_NOTIFY_DESCRIPTOR        *NotifyPtr;\r
+  UINTN                            NotifyDispatchCount;\r
+\r
+\r
+  NotifyDispatchCount = 0;\r
+\r
+  if (NotifyList == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
+\r
+  Index = PrivateData->PpiData.NotifyListEnd;\r
+  LastCallbackNotify = Index;\r
+\r
+  //\r
+  // This is loop installs all Notify descriptors in the NotifyList.  It is\r
+  // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last\r
+  // EFI_PEI_NOTIFY_DESCRIPTOR in the list.\r
+  //\r
+\r
+  for (;;) {\r
+    //\r
+    // Since PpiData is used for NotifyList and InstallList, max resource\r
+    // is reached if the Install reaches the PpiList\r
+    //\r
+    if (Index == PrivateData->PpiData.PpiListEnd - 1) {\r
+      return  EFI_OUT_OF_RESOURCES;\r
+    }\r
+    \r
+    //\r
+    // If some of the PPI data is invalid restore original Notify PPI database value\r
+    //\r
+    if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) {\r
+        PrivateData->PpiData.NotifyListEnd = LastCallbackNotify;\r
+        DEBUG((EFI_D_ERROR, "ERROR -> InstallNotify: %g %x\n", NotifyList->Guid, NotifyList->Notify));\r
+      return  EFI_INVALID_PARAMETER;\r
+    }\r
+     \r
+    if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {\r
+      NotifyDispatchCount ++; \r
+    }        \r
+    \r
+    PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyList;      \r
+   \r
+    PrivateData->PpiData.NotifyListEnd--;\r
+    DEBUG((EFI_D_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));\r
+    if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==\r
+        EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {\r
+      break;\r
+    }\r
+    //\r
+    // Go the next descriptor. Remember the NotifyList moves down.\r
+    //\r
+    NotifyList++;\r
+    Index--;\r
+  }\r
\r
+  //\r
+  // If there is Dispatch Notify PPI installed put them on the bottom \r
+  //\r
+  if (NotifyDispatchCount > 0) {\r
+    for (NotifyIndex = LastCallbackNotify; NotifyIndex > PrivateData->PpiData.NotifyListEnd; NotifyIndex--) {             \r
+      if ((PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {\r
+        NotifyPtr = PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify;\r
+        \r
+        for (Index = NotifyIndex; Index < PrivateData->PpiData.DispatchListEnd; Index++){\r
+          PrivateData->PpiData.PpiListPtrs[Index].Notify = PrivateData->PpiData.PpiListPtrs[Index + 1].Notify;\r
+        }\r
+        PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyPtr;\r
+        PrivateData->PpiData.DispatchListEnd--;                \r
+      }\r
+    }\r
+    \r
+    LastCallbackNotify -= NotifyDispatchCount;        \r
+  }\r
+  \r
+  //\r
+  // Dispatch any callback level notifies for all previously installed PPIs.\r
+  //\r
+  DispatchNotify (\r
+    PeiServices,\r
+    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
+    0,\r
+    PrivateData->PpiData.PpiListEnd,\r
+    LastCallbackNotify,\r
+    PrivateData->PpiData.NotifyListEnd\r
+    );\r
+  \r
+  \r
+  return  EFI_SUCCESS;\r
+}\r
+\r
+\r
+VOID\r
+ProcessNotifyList (\r
+  IN EFI_PEI_SERVICES    **PeiServices\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Process the Notify List at dispatch level.\r
+\r
+Arguments:\r
+\r
+  PeiServices - Pointer to the PEI Service Table\r
+\r
+Returns:\r
+\r
+--*/\r
+\r
+{\r
+  PEI_CORE_INSTANCE       *PrivateData;\r
+  INTN                    TempValue;\r
+\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
+\r
\r
+  while (TRUE) {\r
+    //\r
+    // Check if the PEIM that was just dispatched resulted in any\r
+    // Notifies getting installed.  If so, go process any dispatch\r
+    // level Notifies that match the previouly installed PPIs.\r
+    // Use "while" instead of "if" since DispatchNotify can modify \r
+    // DispatchListEnd (with NotifyPpi) so we have to iterate until the same.\r
+    //\r
+    while (PrivateData->PpiData.LastDispatchedNotify != PrivateData->PpiData.DispatchListEnd) {\r
+      TempValue = PrivateData->PpiData.DispatchListEnd;\r
+      DispatchNotify (\r
+        PeiServices,\r
+        EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,\r
+        0,\r
+        PrivateData->PpiData.LastDispatchedInstall,\r
+        PrivateData->PpiData.LastDispatchedNotify,\r
+        PrivateData->PpiData.DispatchListEnd\r
+        );\r
+      PrivateData->PpiData.LastDispatchedNotify = TempValue;\r
+    }\r
+    \r
+    \r
+    //\r
+    // Check if the PEIM that was just dispatched resulted in any\r
+    // PPIs getting installed.  If so, go process any dispatch\r
+    // level Notifies that match the installed PPIs.\r
+    // Use "while" instead of "if" since DispatchNotify can modify \r
+    // PpiListEnd (with InstallPpi) so we have to iterate until the same.\r
+    //\r
+    while (PrivateData->PpiData.LastDispatchedInstall != PrivateData->PpiData.PpiListEnd) {\r
+      TempValue = PrivateData->PpiData.PpiListEnd;\r
+      DispatchNotify (\r
+        PeiServices,\r
+        EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,\r
+        PrivateData->PpiData.LastDispatchedInstall,\r
+        PrivateData->PpiData.PpiListEnd,\r
+        MAX_PPI_DESCRIPTORS-1,\r
+        PrivateData->PpiData.DispatchListEnd\r
+        );\r
+      PrivateData->PpiData.LastDispatchedInstall = TempValue;\r
+    }\r
+    \r
+    if (PrivateData->PpiData.LastDispatchedNotify == PrivateData->PpiData.DispatchListEnd) {\r
+      break;\r
+    }\r
+  } \r
+  return;\r
+}\r
+\r
+VOID\r
+DispatchNotify (\r
+  IN EFI_PEI_SERVICES    **PeiServices,\r
+  IN UINTN               NotifyType,\r
+  IN INTN                InstallStartIndex,\r
+  IN INTN                InstallStopIndex,\r
+  IN INTN                NotifyStartIndex,\r
+  IN INTN                NotifyStopIndex\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Dispatch notifications.\r
+\r
+Arguments:\r
+\r
+  PeiServices         - Pointer to the PEI Service Table\r
+  NotifyType          - Type of notify to fire.\r
+  InstallStartIndex   - Install Beginning index.\r
+  InstallStopIndex    - Install Ending index.\r
+  NotifyStartIndex    - Notify Beginning index.\r
+  NotifyStopIndex    - Notify Ending index.\r
+\r
+Returns:  None\r
+\r
+--*/\r
+\r
+{\r
+  PEI_CORE_INSTANCE       *PrivateData;\r
+  INTN                   Index1;\r
+  INTN                   Index2;\r
+  EFI_GUID                *SearchGuid;\r
+  EFI_GUID                *CheckGuid;\r
+  EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor;\r
+\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
+\r
+  //\r
+  // Remember that Installs moves up and Notifies moves down.\r
+  //\r
+  for (Index1 = NotifyStartIndex; Index1 > NotifyStopIndex; Index1--) {\r
+    NotifyDescriptor = PrivateData->PpiData.PpiListPtrs[Index1].Notify;\r
+\r
+    CheckGuid = NotifyDescriptor->Guid;\r
+\r
+    for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) {\r
+      SearchGuid = PrivateData->PpiData.PpiListPtrs[Index2].Ppi->Guid;\r
+      //\r
+      // Don't use CompareGuid function here for performance reasons.\r
+      // Instead we compare the GUID as INT32 at a time and branch\r
+      // on the first failed comparison.\r
+      //\r
+      if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) &&\r
+          (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) &&\r
+          (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) &&\r
+          (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3])) {\r
+        DEBUG ((EFI_D_INFO, "Notify: PPI Guid: %g, Peim notify entry point: %x\n", \r
+          SearchGuid, \r
+          NotifyDescriptor->Notify\r
+          ));\r
+        NotifyDescriptor->Notify (\r
+                            PeiServices,\r
+                            NotifyDescriptor,\r
+                            (PrivateData->PpiData.PpiListPtrs[Index2].Ppi)->Ppi\r
+                            );\r
+      }\r
+    }\r
+  }\r
+\r
+  return;\r
+}\r
+\r
diff --git a/MdeModulePkg/Core/Pei/Reset/Reset.c b/MdeModulePkg/Core/Pei/Reset/Reset.c
new file mode 100644 (file)
index 0000000..b0c4b24
--- /dev/null
@@ -0,0 +1,73 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  Reset.c\r
+\r
+Abstract:\r
+\r
+  Pei Core Reset System Support\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <PeiMain.h>\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiResetSystem (\r
+  IN EFI_PEI_SERVICES         **PeiServices\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Core version of the Reset System\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+\r
+Returns:\r
+\r
+  Status  - EFI_NOT_AVAILABLE_YET. PPI not available yet.\r
+          - EFI_DEVICE_ERROR.   Did not reset system.\r
+          \r
+  Otherwise, resets the system. \r
+\r
+--*/\r
+{\r
+  EFI_STATUS        Status;\r
+  EFI_PEI_RESET_PPI *ResetPpi;\r
+\r
+  Status = PeiServicesLocatePpi (\r
+             &gEfiPeiResetPpiGuid,         \r
+             0,                         \r
+             NULL,                      \r
+             (VOID **)&ResetPpi                  \r
+             );\r
+\r
+  //\r
+  // LocatePpi returns EFI_NOT_FOUND on error\r
+  //\r
+  if (!EFI_ERROR (Status)) {\r
+    return ResetPpi->ResetSystem (PeiServices);\r
+  } \r
+  return  EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
diff --git a/MdeModulePkg/Core/Pei/Security/Security.c b/MdeModulePkg/Core/Pei/Security/Security.c
new file mode 100644 (file)
index 0000000..e7c2fbd
--- /dev/null
@@ -0,0 +1,199 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  Security.c\r
+\r
+Abstract:\r
+\r
+  EFI PEI Core Security services\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <PeiMain.h>\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+SecurityPpiNotifyCallback (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
+  );\r
+\r
+static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {\r
+   EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+   &gEfiPeiSecurityPpiGuid,\r
+   SecurityPpiNotifyCallback\r
+};\r
+\r
+VOID\r
+InitializeSecurityServices (\r
+  IN EFI_PEI_SERVICES  **PeiServices,\r
+  IN PEI_CORE_INSTANCE *OldCoreData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize the security services.\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+  OldCoreData - Pointer to the old core data.\r
+                NULL if being run in non-permament memory mode.\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  if (OldCoreData == NULL) {\r
+    PeiServicesNotifyPpi (&mNotifyList);\r
+  }\r
+  return;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+SecurityPpiNotifyCallback (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Provide a callback for when the security PPI is installed.\r
+\r
+Arguments:\r
+\r
+  PeiServices       - The PEI core services table.\r
+  NotifyDescriptor  - The descriptor for the notification event.\r
+  Ppi               - Pointer to the PPI in question.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - The function is successfully processed.\r
+\r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE                       *PrivateData;\r
+\r
+  //\r
+  // Get PEI Core private data\r
+  //\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
+  \r
+  //\r
+  // If there isn't a security PPI installed, use the one from notification\r
+  //\r
+  if (PrivateData->PrivateSecurityPpi == NULL) {\r
+    PrivateData->PrivateSecurityPpi = (EFI_PEI_SECURITY_PPI *)Ppi;\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+VerifyPeim (\r
+  IN EFI_PEI_SERVICES     **PeiServices,\r
+  IN EFI_FFS_FILE_HEADER  *CurrentPeimAddress\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Provide a callout to the security verification service.\r
+\r
+Arguments:\r
+\r
+  PeiServices          - The PEI core services table.\r
+  CurrentPeimAddress   - Pointer to the Firmware File under investigation.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             - Image is OK\r
+  EFI_SECURITY_VIOLATION  - Image is illegal\r
+\r
+--*/\r
+{\r
+  PEI_CORE_INSTANCE               *PrivateData;\r
+  EFI_STATUS                      Status;\r
+  UINT32                          AuthenticationStatus;\r
+  BOOLEAN                         StartCrisisRecovery;\r
+\r
+  //\r
+  // Set a default authentication state\r
+  //\r
+  AuthenticationStatus = 0;\r
+\r
+  //\r
+  // get security PPI instance from PEI private data\r
+  //\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
+\r
+  if (PrivateData->PrivateSecurityPpi == NULL) {\r
+    Status = EFI_NOT_FOUND;\r
+  } else {\r
+    //\r
+    // Check to see if the image is OK\r
+    //\r
+    Status = PrivateData->PrivateSecurityPpi->AuthenticationState (\r
+                                                PeiServices,\r
+                                                PrivateData->PrivateSecurityPpi,\r
+                                                AuthenticationStatus,\r
+                                                CurrentPeimAddress,\r
+                                                &StartCrisisRecovery\r
+                                                );\r
+    if (StartCrisisRecovery) {\r
+      Status = EFI_SECURITY_VIOLATION;\r
+    }\r
+  }\r
+  return Status;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+VerifyFv (\r
+  IN EFI_FIRMWARE_VOLUME_HEADER  *CurrentFvAddress\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Verify a Firmware volume\r
+\r
+Arguments:\r
+\r
+  CurrentFvAddress - Pointer to the current Firmware Volume under consideration\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             - Firmware Volume is legal\r
+  EFI_SECURITY_VIOLATION  - Firmware Volume fails integrity test\r
+\r
+--*/\r
+{\r
+  //\r
+  // Right now just pass the test.  Future can authenticate and/or check the\r
+  // FV-header or other metric for goodness of binary.\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/MdeModulePkg/Core/Pei/StatusCode/StatusCode.c b/MdeModulePkg/Core/Pei/StatusCode/StatusCode.c
new file mode 100644 (file)
index 0000000..9112c45
--- /dev/null
@@ -0,0 +1,100 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  StatusCode.c\r
+\r
+Abstract:\r
+\r
+  Pei Core Status Code Support\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <PeiMain.h>\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiReportStatusCode (\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
+  Core version of the Status Code reporter\r
+\r
+Arguments:\r
+\r
+  PeiServices - The PEI core services table.\r
+  \r
+  CodeType    - Type of Status Code.\r
+  \r
+  Value       - Value to output for Status Code.\r
+  \r
+  Instance    - Instance Number of this status code.\r
+  \r
+  CallerId    - ID of the caller of this status code.\r
+  \r
+  Data        - Optional data associated with this status code.\r
+\r
+Returns:\r
+\r
+  Status  - EFI_SUCCESS             if status code is successfully reported\r
+          - EFI_NOT_AVAILABLE_YET   if StatusCodePpi has not been installed\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_PEI_PROGRESS_CODE_PPI *StatusCodePpi;\r
+  \r
+\r
+  //\r
+  //Locate StatusCode Ppi.\r
+  //\r
+  Status = PeiServicesLocatePpi (\r
+             &gEfiPeiStatusCodePpiGuid,         \r
+             0,                         \r
+             NULL,                      \r
+             (VOID **)&StatusCodePpi                  \r
+             );\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = StatusCodePpi->ReportStatusCode (\r
+                            PeiServices,\r
+                            CodeType,\r
+                            Value,\r
+                            Instance,\r
+                            CallerId,\r
+                            Data\r
+                            );\r
\r
+   return Status;   \r
+  } \r
+  \r
+  \r
+  return  EFI_NOT_AVAILABLE_YET; \r
+}\r
+\r
+\r
+\r
diff --git a/MdeModulePkg/Include/Ppi/LoadFile.h b/MdeModulePkg/Include/Ppi/LoadFile.h
new file mode 100644 (file)
index 0000000..f6d8a70
--- /dev/null
@@ -0,0 +1,72 @@
+/** @file\r
+  Load image file from fv to memory. \r
+\r
+  Copyright (c) 2006, 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:  LoadFile.h\r
+\r
+  @par Revision Reference:\r
+  This PPI is defined in PEI CIS spec Version 0.91.\r
+\r
+**/\r
+\r
+#ifndef __FV_FILE_LOADER_PPI_H__\r
+#define __FV_FILE_LOADER_PPI_H__\r
+\r
+#define EFI_PEI_FV_FILE_LOADER_GUID \\r
+  { \\r
+    0x7e1f0d85, 0x4ff, 0x4bb2, {0x86, 0x6a, 0x31, 0xa2, 0x99, 0x6a, 0x48, 0xa8 } \\r
+  }\r
+\r
+typedef struct _EFI_PEI_FV_FILE_LOADER_PPI  EFI_PEI_FV_FILE_LOADER_PPI;\r
+\r
+/**\r
+  Loads a PEIM into memory for subsequent execution.\r
+\r
+  @param  This           Interface pointer that implements the Load File PPI instance.\r
+  @param  FfsHeader      Pointer to the FFS header of the file to load.\r
+  @param  ImageAddress   Pointer to the address of the loaded Image\r
+  @param  ImageSize      Pointer to the size of the loaded image.\r
+  @param  EntryPoint     Pointer to the entry point of the image.\r
+\r
+  @retval EFI_SUCCESS           The image was loaded successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  There was not enough memory.\r
+  @retval EFI_INVALID_PARAMETER The contents of the FFS file did not\r
+                                contain a valid PE/COFF image that could be loaded.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_PEI_FV_LOAD_FILE) (\r
+  IN EFI_PEI_FV_FILE_LOADER_PPI                 *This,\r
+  IN  EFI_FFS_FILE_HEADER                       *FfsHeader,\r
+  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,\r
+  OUT UINT64                                    *ImageSize,\r
+  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint\r
+  );\r
+\r
+/**\r
+  @par Ppi Description:\r
+  This PPI is a pointer to the Load File service. This service will be \r
+  published by a PEIM.The PEI Foundation will use this service to \r
+  launch the known non-XIP PE/COFF PEIM images.  This service may \r
+  depend upon the presence of the EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI.\r
+\r
+  @param FvLoadFile\r
+  Loads a PEIM into memory for subsequent execution\r
+\r
+**/\r
+struct _EFI_PEI_FV_FILE_LOADER_PPI {\r
+  EFI_PEI_FV_LOAD_FILE  FvLoadFile;\r
+};\r
+\r
+extern EFI_GUID gEfiPeiFvFileLoaderPpiGuid;\r
+\r
+#endif\r
index 6d46905..b8a09d1 100644 (file)
@@ -66,7 +66,8 @@
   gEfiMdePkgTokenSpaceGuid       = { 0xA1AFF049, 0xFDEB, 0x442a, { 0xB3, 0x20, 0x13, 0xAB, 0x4C, 0xB7, 0x2B, 0xBC }}\r
   ##gEfiPeiPeCoffLoaderGuid will be removed in future\r
   gEfiPeiPeCoffLoaderGuid        = { 0xd8117cff, 0x94a6, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }\r
-\r
+  gEfiPeiCorePrivateGuid         = { 0xd641a0f5, 0xcb7c, 0x4846, { 0xa3, 0x80, 0x1d, 0x01, 0xb4, 0xd9, 0xe3, 0xb9 }}\r
+  \r
 ################################################################################\r
 #\r
 # Global Protocols Definition section - list of Global Protocols C Name Data\r
 ################################################################################\r
 [Ppis.common]\r
   gPeiBaseMemoryTestPpiGuid      = { 0xB6EC423C, 0x21D2, 0x490D, { 0x85, 0xC6, 0xDD, 0x58, 0x64, 0xEA, 0xA6, 0x74 }}\r
-\r
-\r
+  gEfiPeiFvFileLoaderPpiGuid     = { 0x7e1f0d85, 0x04ff, 0x4bb2, { 0x86, 0x6a, 0x31, 0xa2, 0x99, 0x6a, 0x48, 0xa8 }} \r
 \r
 \r
 ################################################################################\r
index 7379728..837612a 100644 (file)
   PcdLib|${WORKSPACE}/MdePkg/Library/PeiPcdLib/PeiPcdLib.inf\r
   PeiServiceLib|${WORKSPACE}/MdePkg/Library/PeiServicesLib/PeiServicesLib.inf\r
   PeiServicesTablePointerLib|${WORKSPACE}/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf\r
-\r
+  ReportStatusCodeLib|${WORKSPACE}/IntelFrameworkPkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf\r
+  PeiServicesLib|$(WORKSPACE)/MdePkg/Library/PeiServicesLib/PeiServicesLib.inf\r
+  PeCoffGetEntryPointLib|$(WORKSPACE)/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf\r
+  \r
 [LibraryClasses.common.PEIM]\r
   HobLib|${WORKSPACE}/MdePkg/Library/PeiHobLib/PeiHobLib.inf\r
   MemoryAllocationLib|${WORKSPACE}/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf\r
   ${WORKSPACE}/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.inf\r
   $(WORKSPACE)/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf\r
   $(WORKSPACE)/MdeModulePkg/Universal/PCD/Pei/Pcd.inf\r
+  $(WORKSPACE)/MdeModulePkg/Core/Pei/PeiMain.inf\r
 \r
 [Components.X64]\r
   ${WORKSPACE}/MdeModulePkg/Application/HelloWorld/HelloWorld.inf\r
index 043922d..72fa2a9 100644 (file)
@@ -25,6 +25,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Pi/PiPeiCis.h>\r
 #include <Uefi/UefiMultiPhase.h>\r
 \r
+//\r
+// BUGBUG: The EFI_PEI_STARTUP_DESCRIPTOR definition does not follows PI specification.\r
+//         After enabling PI for Nt32Pkg and tools generate correct autogen for PEI_CORE,\r
+//         the following structure should be removed at once.\r
+//\r
+typedef struct {\r
+  UINTN                   BootFirmwareVolume;\r
+  UINTN                   SizeOfCacheAsRam;\r
+  EFI_PEI_PPI_DESCRIPTOR  *DispatchTable;\r
+} EFI_PEI_STARTUP_DESCRIPTOR;\r
 \r
 #endif\r
 \r
index 1c7fc5b..16f6375 100644 (file)
@@ -19,7 +19,8 @@
 //\r
 // The package level header files this module uses\r
 //\r
-#include <Peim.h>\r
+#include <PiPei.h>\r
+#include <IndustryStandard/PeImage.h>\r
 #include <WinNtPeim.h>\r
 //\r
 // The protocols, PPI and GUID defintions for this module\r
index d2e4dc5..e6ebbe1 100644 (file)
   $(WORKSPACE)/IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.inf\r
   $(WORKSPACE)/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.inf     ##This driver follows UEFI specification definition\r
   $(WORKSPACE)/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.inf    ##This driver follows UEFI specification definition\r
-  $(WORKSPACE)/Nt32Pkg/Sec/SecMain.inf
\ No newline at end of file
+  $(WORKSPACE)/Nt32Pkg/Sec/SecMain.inf\r
+  $(WORKSPACE)/MdeModulePkg/Core/Pei/PeiMain.inf\r
+  
\ No newline at end of file