Beispiel #1
0
/**
  This function handle NotifyPhase API call from the BootLoader.
  It gives control back to the BootLoader after it is handled. If the
  Notification code is a ReadyToBoot event, this function will return
  and FSP continues the remaining execution until it reaches the DxeIpl.

**/
VOID
FspWaitForNotify (
  VOID
  )
{
  EFI_STATUS                 Status;
  UINT32                     NotificationValue;
  UINT32                     NotificationCount;
  UINT8                      Count;

  NotificationCount = 0;
  while (NotificationCount < sizeof(mFspNotifySequence) / sizeof(UINT32)) {

    Count = (UINT8)((NotificationCount << 1) & 0x07);
    SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_ENTRY + Count);

    NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;
    DEBUG ((DEBUG_INFO, "FSP Got Notification. Notification Value : 0x%08X\n", NotificationValue));

    if (mFspNotifySequence[NotificationCount] != NotificationValue) {
      //
      // Notify code does not follow the predefined order
      //
      DEBUG ((DEBUG_INFO, "Unsupported FSP Notification Value\n"));
      SetFspApiReturnStatus(EFI_UNSUPPORTED);
    } else {
      //
      // Process Notification and Give control back to the boot loader framework caller
      //
      Status = FspNotificationHandler (NotificationValue);
      DEBUG ((DEBUG_INFO, "FSP Notification Handler Returns : 0x%08X\n", Status));
      SetFspApiReturnStatus(Status);
      if (!EFI_ERROR(Status)) {
        NotificationCount++;
        SetFspApiReturnStatus(EFI_SUCCESS);
        if (NotificationValue == EnumInitPhaseReadyToBoot) {
          break;
        }
      }
    }
    SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_EXIT + Count);
    Pei2LoaderSwitchStack();
  }

  //
  // Control goes back to the PEI Core and it dispatches further PEIMs.
  // DXEIPL is the final one to transfer control back to the boot loader.
  //
}
Beispiel #2
0
/**
  This function transfer control to the ContinuationFunc passed in by the
  BootLoader.

**/
VOID
EFIAPI
FspInitDone (
  VOID
  )
{
  FSP_INIT_PARAMS        *FspInitParams;

  if (GetFspApiCallingMode() == 0) {
    //
    // FspInit API is used, so jump into the ContinuationFunc
    //
    FspInitParams   = (FSP_INIT_PARAMS *)GetFspApiParameter ();
  
    //
    // Modify the parameters for ContinuationFunc
    //
    SetFspContinuationFuncParameter(EFI_SUCCESS, 0);
    SetFspContinuationFuncParameter((UINT32)GetHobList(), 1);
  
    //
    // Modify the return address to ContinuationFunc
    //
    SetFspApiReturnAddress((UINT32)FspInitParams->ContinuationFunc);
  
    //
    // Give control back to the boot loader framework caller after FspInit is done
    // It is done throught the continuation function
    //
    SetFspMeasurePoint (FSP_PERF_ID_API_FSPINIT_EXIT);
  } else {
    //
    // FspMemoryInit API is used, so return directly
    //

    //
    // This is the end of the FspSiliconInit API
    // Give control back to the boot loader
    //
    DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - End\n"));
    SetFspApiReturnStatus (EFI_SUCCESS);
  }

  Pei2LoaderSwitchStack();
}
Beispiel #3
0
/**
  This function handle NotifyPhase API call from the BootLoader.
  It gives control back to the BootLoader after it is handled. If the
  Notification code is a ReadyToBoot event, this function will return
  and FSP continues the remaining execution until it reaches the DxeIpl.

**/
VOID
FspWaitForNotify (
  VOID
  )
{
  EFI_STATUS                 Status;
  UINT32                     NotificationValue;
  UINT32                     NotificationCount;
  UINT8                      Count;

  NotificationCount = 0;
  while (NotificationCount < sizeof(mFspNotifySequence) / sizeof(UINT32)) {

    Count = (UINT8)((NotificationCount << 1) & 0x07);
    SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY + Count);

    if (NotificationCount == 0) {
      SetPhaseStatusCode (FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION);
      PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
    } else if (NotificationCount == 1) {
      SetPhaseStatusCode (FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION);
      PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
    } else if (NotificationCount == 2) {
      SetPhaseStatusCode (FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION);
      PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
    }

    NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;
    DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - Begin  [Phase: %08X]\n", NotificationValue));
    if (mFspNotifySequence[NotificationCount] != NotificationValue) {
      //
      // Notify code does not follow the predefined order
      //
      DEBUG ((DEBUG_INFO, "Unsupported FSP Notification Value\n"));
      Status = EFI_UNSUPPORTED;
    } else {
      //
      // Process Notification and Give control back to the boot loader framework caller
      //
      Status = FspNotificationHandler (NotificationValue);
      if (!EFI_ERROR(Status)) {
        NotificationCount++;
      }
    }

    DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - End  [Status: 0x%08X]\n", Status));
    SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_EXIT + Count);

    if ((NotificationCount - 1) == 0) {
      PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
    } else if ((NotificationCount - 1) == 1) {
      PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
    } else if ((NotificationCount - 1) == 2) {
      PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
    }
    do {
      SetFspApiReturnStatus(Status);
      Pei2LoaderSwitchStack();
      if (Status != EFI_SUCCESS) {
        DEBUG ((DEBUG_ERROR, "!!!ERROR: NotifyPhaseApi() [Phase: %08X] - Failed - [Status: 0x%08X]\n", NotificationValue, Status));
      }
    } while (Status != EFI_SUCCESS);
  }

  //
  // Control goes back to the PEI Core and it dispatches further PEIMs.
  // DXEIPL is the final one to transfer control back to the boot loader.
  //
}
Beispiel #4
0
/**
  Migrate BootLoader data before destroying CAR.

**/
VOID
EFIAPI
FspMigrateTemporaryMemory (
  VOID
 )
{
  FSP_INIT_RT_COMMON_BUFFER *FspInitRtBuffer;
  UINT32                    BootLoaderTempRamStart;
  UINT32                    BootLoaderTempRamEnd;
  UINT32                    BootLoaderTempRamSize;
  UINT32                    OffsetGap;
  UINT32                    FspParamPtr;
  FSP_INIT_PARAMS           *FspInitParams;
  UINT32                    *NewStackTop;
  VOID                      *BootLoaderTempRamHob;
  UINT32                    UpdDataRgnPtr;
  UINT32                    MemoryInitUpdPtr;
  UINT32                    SiliconInitUpdPtr;
  VOID                      *PlatformDataPtr;
  UINT8                      ApiMode;
    
  ApiMode = GetFspApiCallingMode ();

  //
  // Get the temporary memory range used by the BootLoader
  //
  BootLoaderTempRamStart = PcdGet32(PcdTemporaryRamBase);
  BootLoaderTempRamSize  = PcdGet32(PcdTemporaryRamSize) - PcdGet32(PcdFspTemporaryRamSize);
  BootLoaderTempRamEnd   = BootLoaderTempRamStart +  BootLoaderTempRamSize;

  //
  // Build a Boot Loader Temporary Memory GUID HOB
  //
  if (ApiMode == 0) {
    BootLoaderTempRamHob = BuildGuidHob (&gFspBootLoaderTemporaryMemoryGuid, BootLoaderTempRamSize);
  } else {
    BootLoaderTempRamHob = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES (BootLoaderTempRamSize));
  }
  ASSERT(BootLoaderTempRamHob != NULL);

  CopyMem (BootLoaderTempRamHob, (VOID *)BootLoaderTempRamStart, BootLoaderTempRamSize);
  OffsetGap = (UINT32)BootLoaderTempRamHob - BootLoaderTempRamStart;

  //
  // Set a new stack frame for the continuation function
  //
  if (ApiMode == 0) {
    FspInitParams   = (FSP_INIT_PARAMS *)GetFspApiParameter ();
    FspInitRtBuffer = (FSP_INIT_RT_COMMON_BUFFER *)FspInitParams->RtBufferPtr;
    NewStackTop     = (UINT32 *)FspInitRtBuffer->StackTop - 1;
    SetFspCoreStackPointer (NewStackTop);
  }

  //
  // Fix the FspInit Parameter Pointers to the new location.
  //
  FspParamPtr = GetFspApiParameter ();
  if (FspParamPtr >= BootLoaderTempRamStart && FspParamPtr < BootLoaderTempRamEnd) {
    SetFspApiParameter(FspParamPtr + OffsetGap);
  }

  FspInitParams = (FSP_INIT_PARAMS *)GetFspApiParameter ();
  if ((UINT32)(FspInitParams->RtBufferPtr) >= BootLoaderTempRamStart &&
      (UINT32)(FspInitParams->RtBufferPtr) <  BootLoaderTempRamEnd) {
    FspInitParams->RtBufferPtr = (VOID *)((UINT32)(FspInitParams->RtBufferPtr) + OffsetGap);
  }

  if ((UINT32)(FspInitParams->NvsBufferPtr) >= BootLoaderTempRamStart &&
      (UINT32)(FspInitParams->NvsBufferPtr) <  BootLoaderTempRamEnd) {
    FspInitParams->NvsBufferPtr = (VOID *)((UINT32)(FspInitParams->NvsBufferPtr) + OffsetGap);
  }

  if ((UINT32)(((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr) >= BootLoaderTempRamStart &&
      (UINT32)(((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr) <  BootLoaderTempRamEnd) {
    ((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr = \
           (VOID *)((UINT32)(((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr) + OffsetGap);
  }

  //
  // Update UPD pointer in FSP Global Data
  //
  if (ApiMode == 0) {
    UpdDataRgnPtr = (UINT32)((UINT32 *)GetFspUpdDataPointer ());
    if (UpdDataRgnPtr >= BootLoaderTempRamStart && UpdDataRgnPtr < BootLoaderTempRamEnd) {
      MemoryInitUpdPtr = (UINT32)((UINT32 *)GetFspMemoryInitUpdDataPointer ());
      SiliconInitUpdPtr = (UINT32)((UINT32 *)GetFspSiliconInitUpdDataPointer ());
      SetFspUpdDataPointer ((VOID *)(UpdDataRgnPtr + OffsetGap));
      SetFspMemoryInitUpdDataPointer ((VOID *)(MemoryInitUpdPtr + OffsetGap));
      SetFspSiliconInitUpdDataPointer ((VOID *)(SiliconInitUpdPtr + OffsetGap));
    }
  } else {
    MemoryInitUpdPtr = (UINT32)((UINT32 *)GetFspMemoryInitUpdDataPointer ());
    if (MemoryInitUpdPtr >= BootLoaderTempRamStart && MemoryInitUpdPtr < BootLoaderTempRamEnd) {
      SetFspMemoryInitUpdDataPointer ((VOID *)(MemoryInitUpdPtr + OffsetGap));
    }
  }

  //
  // Update Platform data pointer in FSP Global Data
  //
  PlatformDataPtr = GetFspPlatformDataPointer ();
  if (((UINT32)PlatformDataPtr >= BootLoaderTempRamStart) &&
      ((UINT32)PlatformDataPtr <  BootLoaderTempRamEnd)) {
    SetFspPlatformDataPointer ((UINT8 *)PlatformDataPtr + OffsetGap);
  }
}