FspPlatformNotify.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /** @file
  2. Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. **/
  5. #include <PiPei.h>
  6. #include <Library/PeiServicesLib.h>
  7. #include <Library/PeiServicesTablePointerLib.h>
  8. #include <Library/BaseLib.h>
  9. #include <Library/BaseMemoryLib.h>
  10. #include <Library/PcdLib.h>
  11. #include <Library/DebugLib.h>
  12. #include <Library/HobLib.h>
  13. #include <Library/FspSwitchStackLib.h>
  14. #include <Library/FspCommonLib.h>
  15. #include <Guid/EventGroup.h>
  16. #include <FspApi.h>
  17. #include <Protocol/PciEnumerationComplete.h>
  18. EFI_PEI_PPI_DESCRIPTOR mPeiPostPciEnumerationPpi = {
  19. (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  20. &gEfiPciEnumerationCompleteProtocolGuid,
  21. NULL
  22. };
  23. EFI_PEI_PPI_DESCRIPTOR mPeiReadyToBootPpi = {
  24. (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  25. &gEfiEventReadyToBootGuid,
  26. NULL
  27. };
  28. UINT32 mFspNotifySequence[] = {
  29. EnumInitPhaseAfterPciEnumeration,
  30. EnumInitPhaseReadyToBoot
  31. };
  32. /**
  33. Install FSP notification.
  34. @param[in] NotificationCode FSP notification code
  35. @retval EFI_SUCCESS Notify FSP successfully
  36. @retval EFI_INVALID_PARAMETER NotificationCode is invalid
  37. **/
  38. EFI_STATUS
  39. EFIAPI
  40. FspNotificationHandler (
  41. IN UINT32 NotificationCode
  42. )
  43. {
  44. EFI_STATUS Status;
  45. Status = EFI_SUCCESS;
  46. switch (NotificationCode) {
  47. case EnumInitPhaseAfterPciEnumeration:
  48. //
  49. // Do POST PCI initialization if needed
  50. //
  51. DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Post PCI Enumeration ...\n"));
  52. PeiServicesInstallPpi (&mPeiPostPciEnumerationPpi);
  53. break;
  54. case EnumInitPhaseReadyToBoot:
  55. //
  56. // Ready To Boot
  57. //
  58. DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP Ready To Boot ...\n"));
  59. PeiServicesInstallPpi (&mPeiReadyToBootPpi);
  60. break;
  61. default:
  62. Status = EFI_INVALID_PARAMETER;
  63. break;
  64. }
  65. return Status;
  66. }
  67. /**
  68. This function transfer control to the ContinuationFunc passed in by the
  69. BootLoader.
  70. **/
  71. VOID
  72. EFIAPI
  73. FspInitDone (
  74. VOID
  75. )
  76. {
  77. FSP_INIT_PARAMS *FspInitParams;
  78. if (GetFspApiCallingMode() == 0) {
  79. //
  80. // FspInit API is used, so jump into the ContinuationFunc
  81. //
  82. FspInitParams = (FSP_INIT_PARAMS *)GetFspApiParameter ();
  83. //
  84. // Modify the parameters for ContinuationFunc
  85. //
  86. SetFspContinuationFuncParameter(EFI_SUCCESS, 0);
  87. SetFspContinuationFuncParameter((UINT32)GetHobList(), 1);
  88. //
  89. // Modify the return address to ContinuationFunc
  90. //
  91. SetFspApiReturnAddress((UINT32)FspInitParams->ContinuationFunc);
  92. //
  93. // Give control back to the boot loader framework caller after FspInit is done
  94. // It is done throught the continuation function
  95. //
  96. SetFspMeasurePoint (FSP_PERF_ID_API_FSPINIT_EXIT);
  97. } else {
  98. //
  99. // FspMemoryInit API is used, so return directly
  100. //
  101. //
  102. // This is the end of the FspSiliconInit API
  103. // Give control back to the boot loader
  104. //
  105. DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - End\n"));
  106. SetFspApiReturnStatus (EFI_SUCCESS);
  107. }
  108. Pei2LoaderSwitchStack();
  109. }
  110. /**
  111. This function handle NotifyPhase API call from the BootLoader.
  112. It gives control back to the BootLoader after it is handled. If the
  113. Notification code is a ReadyToBoot event, this function will return
  114. and FSP continues the remaining execution until it reaches the DxeIpl.
  115. **/
  116. VOID
  117. FspWaitForNotify (
  118. VOID
  119. )
  120. {
  121. EFI_STATUS Status;
  122. UINT32 NotificationValue;
  123. UINT32 NotificationCount;
  124. UINT8 Count;
  125. NotificationCount = 0;
  126. while (NotificationCount < sizeof(mFspNotifySequence) / sizeof(UINT32)) {
  127. Count = (UINT8)((NotificationCount << 1) & 0x07);
  128. SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_ENTRY + Count);
  129. NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;
  130. DEBUG ((DEBUG_INFO, "FSP Got Notification. Notification Value : 0x%08X\n", NotificationValue));
  131. if (mFspNotifySequence[NotificationCount] != NotificationValue) {
  132. //
  133. // Notify code does not follow the predefined order
  134. //
  135. DEBUG ((DEBUG_INFO, "Unsupported FSP Notification Value\n"));
  136. SetFspApiReturnStatus(EFI_UNSUPPORTED);
  137. } else {
  138. //
  139. // Process Notification and Give control back to the boot loader framework caller
  140. //
  141. Status = FspNotificationHandler (NotificationValue);
  142. DEBUG ((DEBUG_INFO, "FSP Notification Handler Returns : 0x%08X\n", Status));
  143. SetFspApiReturnStatus(Status);
  144. if (!EFI_ERROR(Status)) {
  145. NotificationCount++;
  146. SetFspApiReturnStatus(EFI_SUCCESS);
  147. if (NotificationValue == EnumInitPhaseReadyToBoot) {
  148. break;
  149. }
  150. }
  151. }
  152. SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_EXIT + Count);
  153. Pei2LoaderSwitchStack();
  154. }
  155. //
  156. // Control goes back to the PEI Core and it dispatches further PEIMs.
  157. // DXEIPL is the final one to transfer control back to the boot loader.
  158. //
  159. }