+++ /dev/null
-/** @file\r
-\r
- Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\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 mFspNotifySequence[] = {\r
- EnumInitPhaseAfterPciEnumeration,\r
- EnumInitPhaseReadyToBoot\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
- 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
- if (GetFspApiCallingMode() == 0) {\r
- //\r
- // FspInit API is used, so jump into the ContinuationFunc\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
- } else {\r
- //\r
- // FspMemoryInit API is used, so return directly\r
- //\r
-\r
- //\r
- // This is the end of the FspSiliconInit API\r
- // Give control back to the boot loader\r
- //\r
- DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - End\n"));\r
- SetFspApiReturnStatus (EFI_SUCCESS);\r
- }\r
-\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 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_POSTPCI_ENTRY + Count);\r
-\r
- NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;\r
- DEBUG ((DEBUG_INFO, "FSP Got Notification. Notification Value : 0x%08X\n", NotificationValue));\r
-\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
- SetFspApiReturnStatus(EFI_UNSUPPORTED);\r
- } else {\r
- //\r
- // Process Notification and Give control back to the boot loader framework caller\r
- //\r
- Status = FspNotificationHandler (NotificationValue);\r
- DEBUG ((DEBUG_INFO, "FSP Notification Handler Returns : 0x%08X\n", Status));\r
- SetFspApiReturnStatus(Status);\r
- if (!EFI_ERROR(Status)) {\r
- NotificationCount++;\r
- SetFspApiReturnStatus(EFI_SUCCESS);\r
- if (NotificationValue == 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