]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
Add IntelFspPkg to support create FSP bin based on EDKII.
[mirror_edk2.git] / IntelFspPkg / Library / BaseFspPlatformLib / FspPlatformNotify.c
diff --git a/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c b/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
new file mode 100644 (file)
index 0000000..3488fbc
--- /dev/null
@@ -0,0 +1,178 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/PeiServicesTablePointerLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/FspSwitchStackLib.h>\r
+#include <Library/FspCommonLib.h>\r
+#include <Guid/EventGroup.h>\r
+#include <FspApi.h>\r
+#include <Protocol/PciEnumerationComplete.h>\r
+\r
+EFI_PEI_PPI_DESCRIPTOR      mPeiPostPciEnumerationPpi = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEfiPciEnumerationCompleteProtocolGuid,\r
+  NULL\r
+};\r
+\r
+EFI_PEI_PPI_DESCRIPTOR      mPeiReadyToBootPpi = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEfiEventReadyToBootGuid,\r
+  NULL\r
+};\r
+\r
+\r
+UINT32  mFspNotfifySequence[] = {\r
+  EnumInitPhaseAfterPciEnumeration,\r
+  EnumInitPhaseReadyToBoot\r
+};\r
+\r
+/**\r
+  Install FSP notification.\r
+\r
+  @param[in] NotificatonCode  FSP notification code\r
+\r
+  @retval EFI_SUCCESS            Notify FSP successfully\r
+  @retval EFI_INVALID_PARAMETER  NotificatonCode is invalid\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FspNotificationHandler (\r
+  IN  UINT32     NotificatonCode\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+\r
+  Status   = EFI_SUCCESS;\r
+\r
+  switch (NotificatonCode) {\r
+  case EnumInitPhaseAfterPciEnumeration:\r
+    //\r
+    // Do POST PCI initialization if needed\r
+    //\r
+    DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Post PCI Enumeration ...\n"));\r
+    PeiServicesInstallPpi (&mPeiPostPciEnumerationPpi);\r
+    break;\r
+\r
+  case EnumInitPhaseReadyToBoot:\r
+    //\r
+    // Ready To Boot\r
+    //\r
+    DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP Ready To Boot ...\n"));\r
+    PeiServicesInstallPpi (&mPeiReadyToBootPpi);\r
+    break;\r
+\r
+  default:\r
+    Status = EFI_INVALID_PARAMETER;\r
+    break;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function transfer control to the ContinuationFunc passed in by the\r
+  bootloader.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FspInitDone (\r
+  VOID\r
+  )\r
+{\r
+  FSP_INIT_PARAMS           *FspInitParams;\r
+\r
+  FspInitParams   = (FSP_INIT_PARAMS *)GetFspApiParameter ();\r
+\r
+  //\r
+  // Modify the parameters for ContinuationFunc\r
+  //\r
+  SetFspContinuationFuncParameter(EFI_SUCCESS, 0);\r
+  SetFspContinuationFuncParameter((UINT32)GetHobList(), 1);\r
+\r
+  //\r
+  // Modify the return address to ContinuationFunc\r
+  //\r
+  SetFspApiReturnAddress((UINT32)FspInitParams->ContinuationFunc);\r
+\r
+  //\r
+  // Give control back to the boot loader framework caller after FspInit is done\r
+  // It is done throught the continuation function\r
+  //\r
+  SetFspMeasurePoint (FSP_PERF_ID_API_FSPINIT_EXIT);\r
+  Pei2LoaderSwitchStack();\r
+}\r
+\r
+/**\r
+  This function handle NotifyPhase API call from the bootloader.\r
+  It gives control back to the bootloader after it is handled. If the\r
+  Notification code is a ReadyToBoot event, this function will return\r
+  and FSP continues the remaining execution until it reaches the DxeIpl.\r
+\r
+**/\r
+VOID\r
+FspWaitForNotify (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                 Status;\r
+  UINT32                     NotificatonValue;\r
+  UINT32                     NotificatonCount;\r
+  UINT8                      Count;\r
+\r
+  NotificatonCount = 0;\r
+  while (NotificatonCount < sizeof(mFspNotfifySequence) / sizeof(UINT32)) {\r
+\r
+    Count = (NotificatonCount << 1) & 0x07;\r
+    SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_ENTRY + Count);\r
+\r
+    NotificatonValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;\r
+    DEBUG ((DEBUG_INFO, "FSP Got Notification. Notification Value : 0x%08X\n", NotificatonValue));\r
+\r
+    if (mFspNotfifySequence[NotificatonCount] != NotificatonValue) {\r
+      //\r
+      // Notify code does not follow the predefined order\r
+      //\r
+      SetFspApiReturnStatus(EFI_UNSUPPORTED);\r
+    } else {\r
+      //\r
+      // Process Notification and Give control back to the boot loader framework caller\r
+      //\r
+      Status = FspNotificationHandler (NotificatonValue);\r
+      SetFspApiReturnStatus(Status);\r
+      if (!EFI_ERROR(Status)) {\r
+        NotificatonCount++;\r
+        SetFspApiReturnStatus(EFI_SUCCESS);\r
+        if (NotificatonValue == EnumInitPhaseReadyToBoot) {\r
+          break;\r
+        }\r
+      }\r
+    }\r
+    SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_EXIT + Count);\r
+    Pei2LoaderSwitchStack();\r
+  }\r
+\r
+  //\r
+  // Control goes back to the PEI Core and it dispatches further PEIMs.\r
+  // DXEIPL is the final one to transfer control back to the boot loader.\r
+  //\r
+}\r
+\r