]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
Add IntelFsp2Pkg and IntelFsp2WrapperPkg.
[mirror_edk2.git] / IntelFsp2Pkg / Library / BaseFspPlatformLib / FspPlatformNotify.c
diff --git a/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
new file mode 100644 (file)
index 0000000..66b6cdb
--- /dev/null
@@ -0,0 +1,279 @@
+/** @file\r
+\r
+  Copyright (c) 2014 - 2016, 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 <FspEas.h>\r
+#include <FspStatusCode.h>\r
+#include <Protocol/PciEnumerationComplete.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/PerformanceLib.h>\r
+extern EFI_GUID gFspPerformanceDataGuid;\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
+EFI_PEI_PPI_DESCRIPTOR      mPeiEndOfFirmwarePpi = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gFspEventEndOfFirmwareGuid,\r
+  NULL\r
+};\r
+\r
+UINT32  mFspNotifySequence[] = {\r
+  EnumInitPhaseAfterPciEnumeration,\r
+  EnumInitPhaseReadyToBoot,\r
+  EnumInitPhaseEndOfFirmware\r
+};\r
+\r
+/**\r
+  Install FSP notification.\r
+\r
+  @param[in] NotificationCode  FSP notification code\r
+\r
+  @retval EFI_SUCCESS            Notify FSP successfully\r
+  @retval EFI_INVALID_PARAMETER  NotificationCode is invalid\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FspNotificationHandler (\r
+  IN  UINT32     NotificationCode\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+\r
+  Status   = EFI_SUCCESS;\r
+\r
+  switch (NotificationCode) {\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
+  case EnumInitPhaseEndOfFirmware:\r
+    //\r
+    // End of Firmware\r
+    //\r
+    DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP End of Firmware ...\n"));\r
+    PeiServicesInstallPpi (&mPeiEndOfFirmwarePpi);\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 back to BootLoader after FspSiliconInit.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FspSiliconInitDone (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // This is the end of the FspSiliconInit API\r
+  // Give control back to the boot loader\r
+  //\r
+  SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_EXIT);\r
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - End\n"));\r
+\r
+  PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, 0x907F);\r
+\r
+  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
+  SetFspApiReturnStatus (EFI_SUCCESS);\r
+\r
+  Pei2LoaderSwitchStack();\r
+\r
+  PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, 0x6000);\r
+}\r
+\r
+/**\r
+  This function returns control to BootLoader after MemoryInitApi.\r
+\r
+  @param[in,out] HobListPtr The address of HobList pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+FspMemoryInitDone (\r
+  IN OUT VOID   **HobListPtr\r
+  )\r
+{\r
+  //\r
+  // Calling use FspMemoryInit API\r
+  // Update HOB and return the control directly\r
+  //\r
+  if (HobListPtr != NULL) {\r
+    *HobListPtr = (VOID *) GetHobList ();\r
+  }\r
+\r
+  //\r
+  // This is the end of the FspMemoryInit API\r
+  // Give control back to the boot loader\r
+  //\r
+  SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT);\r
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() - End\n"));\r
+  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
+  SetFspApiReturnStatus (EFI_SUCCESS);\r
+  Pei2LoaderSwitchStack ();\r
+\r
+  //\r
+  // The TempRamExitApi is called\r
+  //\r
+  if (GetFspApiCallingIndex () == TempRamExitApiIndex) {\r
+    SetPhaseStatusCode (FSP_STATUS_CODE_TEMP_RAM_EXIT);\r
+    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
+    SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY);\r
+    DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - Begin\n"));\r
+  } else {\r
+    SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);\r
+    DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - Begin\n"));\r
+    SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);\r
+    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
+  }\r
+}\r
+\r
+/**\r
+  This function returns control to BootLoader after TempRamExitApi.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FspTempRamExitDone (\r
+  VOID\r
+  )\r
+{\r
+\r
+  //\r
+  // This is the end of the TempRamExit API\r
+  // Give control back to the boot loader\r
+  //\r
+  SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT);\r
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - End\n"));\r
+  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
+  SetFspApiReturnStatus (EFI_SUCCESS);\r
+  Pei2LoaderSwitchStack ();\r
+\r
+  SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);\r
+  SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);\r
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "SiliconInitApi() - Begin\n"));\r
+  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\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                     NotificationValue;\r
+  UINT32                     NotificationCount;\r
+  UINT8                      Count;\r
+\r
+  NotificationCount = 0;\r
+  while (NotificationCount < sizeof(mFspNotifySequence) / sizeof(UINT32)) {\r
+\r
+    Count = (UINT8)((NotificationCount << 1) & 0x07);\r
+    SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY + Count);\r
+\r
+    if (NotificationCount == 0) {\r
+      SetPhaseStatusCode (FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION);\r
+      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
+    } else if (NotificationCount == 1) {\r
+      SetPhaseStatusCode (FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION);\r
+      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
+    } else if (NotificationCount == 2) {\r
+      SetPhaseStatusCode (FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION);\r
+      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
+    }\r
+\r
+    NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;\r
+    DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - Begin  [Phase: %08X]\n", NotificationValue));\r
+    if (mFspNotifySequence[NotificationCount] != NotificationValue) {\r
+      //\r
+      // Notify code does not follow the predefined order\r
+      //\r
+      DEBUG ((DEBUG_INFO, "Unsupported FSP Notification Value\n"));\r
+      Status = EFI_UNSUPPORTED;\r
+    } else {\r
+      //\r
+      // Process Notification and Give control back to the boot loader framework caller\r
+      //\r
+      Status = FspNotificationHandler (NotificationValue);\r
+      if (!EFI_ERROR(Status)) {\r
+        NotificationCount++;\r
+      }\r
+    }\r
+\r
+    SetFspApiReturnStatus(Status);\r
+    DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - End  [Status: 0x%08X]\n", Status));\r
+\r
+    SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_EXIT + Count);\r
+\r
+    if ((NotificationCount - 1) == 0) {\r
+      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
+    } else if ((NotificationCount - 1) == 1) {\r
+      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
+    } else if ((NotificationCount - 1) == 2) {\r
+      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
+    }\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