/** Main entry for the FSP DXE module. This routine registers two callbacks to call fsp's notifies. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI FspDxeEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_EVENT ReadyToBootEvent; VOID *Registration; EFI_EVENT ProtocolNotifyEvent; // // Load this driver's image to memory // Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable); if (EFI_ERROR (Status)) { return EFI_SUCCESS; } if (PcdGet32 (PcdFlashFvSecondFspBase) == 0) { mFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase)); } else { mFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvSecondFspBase)); } DEBUG ((DEBUG_INFO, "FspHeader - 0x%x\n", mFspHeader)); if (mFspHeader == NULL) { return EFI_DEVICE_ERROR; } ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent ( &gEfiPciEnumerationCompleteProtocolGuid, TPL_CALLBACK, OnPciEnumerationComplete, NULL, &Registration ); ASSERT (ProtocolNotifyEvent != NULL); Status = EfiCreateEventReadyToBootEx ( TPL_CALLBACK, OnReadyToBoot, NULL, &ReadyToBootEvent ); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }
/** This function handles S3 resume task at the end of PEI @param[in] PeiServices Pointer to PEI Services Table. @param[in] NotifyDesc Pointer to the descriptor for the Notification event that caused this function to execute. @param[in] Ppi Pointer to the PPI data associated with this function. @retval EFI_STATUS Always return EFI_SUCCESS **/ EFI_STATUS EFIAPI S3EndOfPeiNotify ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, IN VOID *Ppi ) { NOTIFY_PHASE_PARAMS NotifyPhaseParams; EFI_STATUS Status; FSP_INFO_HEADER *FspHeader; FspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase)); if (FspHeader == NULL) { return EFI_DEVICE_ERROR; } DEBUG ((DEBUG_INFO, "S3EndOfPeiNotify enter\n")); NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration; Status = CallFspNotifyPhase (FspHeader, &NotifyPhaseParams); DEBUG((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration status: 0x%x\n", Status)); NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot; Status = CallFspNotifyPhase (FspHeader, &NotifyPhaseParams); DEBUG((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot status: 0x%x\n", Status)); return EFI_SUCCESS; }
/** This function handles S3 resume task at the end of PEI @param[in] PeiServices Pointer to PEI Services Table. @param[in] NotifyDesc Pointer to the descriptor for the Notification event that caused this function to execute. @param[in] Ppi Pointer to the PPI data associated with this function. @retval EFI_STATUS Always return EFI_SUCCESS **/ EFI_STATUS EFIAPI S3EndOfPeiNotify ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, IN VOID *Ppi ) { NOTIFY_PHASE_PARAMS NotifyPhaseParams; FSP_STATUS FspStatus; FSP_INFO_HEADER *FspHeader; FspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase)); if (FspHeader == NULL) { return EFI_DEVICE_ERROR; } NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration; FspStatus = CallFspNotifyPhase (FspHeader, &NotifyPhaseParams); if (FspStatus != FSP_SUCCESS) { DEBUG((DEBUG_ERROR, "FSP S3NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", FspStatus)); } else { DEBUG((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration Success.\n")); } NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot; FspStatus = CallFspNotifyPhase (FspHeader, &NotifyPhaseParams); if (FspStatus != FSP_SUCCESS) { DEBUG((DEBUG_ERROR, "FSP S3NotifyPhase ReadyToBoot failed, status: 0x%x\n", FspStatus)); } else { DEBUG((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot Success.\n")); } return EFI_SUCCESS; }
/** This is the entrypoint of PEIM @param[in] FileHandle Handle of the file being invoked. @param[in] PeiServices Describes the list of possible PEI Services. @retval EFI_SUCCESS if it completed successfully. **/ EFI_STATUS EFIAPI FspPeiEntryPoint ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { FSP_INFO_HEADER *FspHeader; EFI_STATUS Status; FSP_INIT_DONE_PPI *FspInitDone; VOID *FspHobList; EFI_BOOT_MODE BootMode; DEBUG ((DEBUG_INFO, "FspPeiEntryPoint\n")); Status = PeiServicesLocatePpi ( &gFspInitDonePpiGuid, 0, NULL, (VOID **) &FspInitDone ); if (EFI_ERROR (Status)) { // // 1st entry // DEBUG ((DEBUG_INFO, "1st entry\n")); FspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase)); DEBUG ((DEBUG_INFO, "FspHeader - 0x%x\n", FspHeader)); if (FspHeader == NULL) { return EFI_DEVICE_ERROR; } SecFspInit (FspHeader); // // Never return here // CpuDeadLoop (); } else { // // 2nd entry // DEBUG ((DEBUG_INFO, "2nd entry\n")); Status = FspInitDone->GetFspHobList (PeiServices, FspInitDone, &FspHobList); DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList)); FspHobProcess (FspHobList); PeiServicesGetBootMode (&BootMode); if (BootMode == BOOT_ON_S3_RESUME) { Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc); ASSERT_EFI_ERROR (Status); } } return EFI_SUCCESS; }
/** This is the entrypoint of PEIM @param[in] FileHandle Handle of the file being invoked. @param[in] PeiServices Describes the list of possible PEI Services. @retval EFI_SUCCESS if it completed successfully. **/ EFI_STATUS EFIAPI FspPeiEntryPoint ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { FSP_INFO_HEADER *FspHeader; UINT8 PcdFspApiVersion; DEBUG ((DEBUG_INFO, "FspPeiEntryPoint\n")); PcdFspApiVersion = 1; FspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase)); DEBUG ((DEBUG_INFO, "FspHeader - 0x%x\n", FspHeader)); if (FspHeader == NULL) { return EFI_DEVICE_ERROR; } ASSERT (FspHeader->TempRamInitEntryOffset != 0); ASSERT (FspHeader->FspInitEntryOffset != 0); ASSERT (FspHeader->NotifyPhaseEntryOffset != 0); if ((PcdGet8 (PcdFspApiVersion) >= 2) && (FspHeader->HeaderRevision >= FSP_HEADER_REVISION_2) && (FspHeader->ApiEntryNum >= 6) ) { ASSERT (FspHeader->FspMemoryInitEntryOffset != 0); ASSERT (FspHeader->TempRamExitEntryOffset != 0); ASSERT (FspHeader->FspSiliconInitEntryOffset != 0); PcdFspApiVersion = PcdGet8 (PcdFspApiVersion); } DEBUG ((DEBUG_INFO, "PcdFspApiVersion - 0x%x\n", PcdFspApiVersion)); if (PcdFspApiVersion == 1) { PeiFspInitV1 (FspHeader); } else { PeiFspInitV2 (FspHeader); } return EFI_SUCCESS; }
/** This interface disables temporary memory in SEC Phase. **/ VOID EFIAPI SecPlatformDisableTemporaryMemory ( VOID ) { EFI_STATUS Status; VOID *TempRamExitParam; FSP_INFO_HEADER *FspHeader; FspHeader = FspFindFspHeader (PcdGet32(PcdFspmBaseAddress)); if (FspHeader == NULL) { return ; } DEBUG((DEBUG_INFO, "SecPlatformDisableTemporaryMemory enter\n")); TempRamExitParam = UpdateTempRamExitParam (); Status = CallTempRamExit (TempRamExitParam); DEBUG((DEBUG_INFO, "TempRamExit status: 0x%x\n", Status)); ASSERT_EFI_ERROR(Status); return ; }
/** This function is called after PEI core discover memory and finish migration. @param[in] PeiServices Pointer to PEI Services Table. @param[in] NotifyDesc Pointer to the descriptor for the Notification event that caused this function to execute. @param[in] Ppi Pointer to the PPI data associated with this function. @retval EFI_STATUS Always return EFI_SUCCESS **/ EFI_STATUS EFIAPI PeiMemoryDiscoveredNotify ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, IN VOID *Ppi ) { FSP_INFO_HEADER *FspsHeaderPtr; UINT64 TimeStampCounterStart; EFI_STATUS Status; VOID *FspHobListPtr; EFI_HOB_GUID_TYPE *GuidHob; FSPS_UPD_COMMON *FspsUpdDataPtr; UINTN *SourceData; DEBUG ((DEBUG_INFO, "PeiMemoryDiscoveredNotify enter\n")); // // Copy default FSP-S UPD data from Flash // FspsHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress)); DEBUG ((DEBUG_INFO, "FspsHeaderPtr - 0x%x\n", FspsHeaderPtr)); if (FspsHeaderPtr == NULL) { return EFI_DEVICE_ERROR; } FspsUpdDataPtr = (FSPS_UPD_COMMON *)AllocateZeroPool ((UINTN)FspsHeaderPtr->CfgRegionSize); ASSERT (FspsUpdDataPtr != NULL); SourceData = (UINTN *)((UINTN)FspsHeaderPtr->ImageBase + (UINTN)FspsHeaderPtr->CfgRegionOffset); CopyMem (FspsUpdDataPtr, SourceData, (UINTN)FspsHeaderPtr->CfgRegionSize); UpdateFspsUpdData ((VOID *)FspsUpdDataPtr); TimeStampCounterStart = AsmReadTsc (); PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x9000); Status = CallFspSiliconInit ((VOID *)FspsUpdDataPtr); PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x907F); DEBUG ((DEBUG_INFO, "Total time spent executing FspSiliconInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000))); // // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status // if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) { DEBUG((DEBUG_INFO, "FspSiliconInitApi requested reset 0x%x\n", Status)); CallFspWrapperResetSystem ((UINT32)Status); } if (EFI_ERROR(Status)) { DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspSiliconInitApi(), Status = %r\n", Status)); } DEBUG((DEBUG_INFO, "FspSiliconInit status: 0x%x\n", Status)); ASSERT_EFI_ERROR (Status); Status = TestFspSiliconInitApiOutput ((VOID *)NULL); if (RETURN_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "ERROR - TestFspSiliconInitApiOutput () fail, Status = %r\n", Status)); } // // Now FspHobList complete, process it // GuidHob = GetFirstGuidHob (&gFspHobGuid); ASSERT (GuidHob != NULL); FspHobListPtr = *(VOID **)GET_GUID_HOB_DATA (GuidHob); DEBUG ((DEBUG_INFO, "FspHobListPtr - 0x%x\n", FspHobListPtr)); PostFspsHobProcess (FspHobListPtr); // // Install FspSiliconInitDonePpi so that any other driver can consume this info. // Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi); ASSERT_EFI_ERROR(Status); return Status; }
/** Call FspMemoryInit API. @return Status returned by FspMemoryInit API. **/ EFI_STATUS PeiFspMemoryInit ( VOID ) { FSP_INFO_HEADER *FspmHeaderPtr; EFI_STATUS Status; UINT64 TimeStampCounterStart; VOID *FspHobListPtr; VOID *HobData; FSPM_UPD_COMMON *FspmUpdDataPtr; UINTN *SourceData; DEBUG ((DEBUG_INFO, "PeiFspMemoryInit enter\n")); FspHobListPtr = NULL; // // Copy default FSP-M UPD data from Flash // FspmHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress)); FspmUpdDataPtr = (FSPM_UPD_COMMON *)AllocateZeroPool ((UINTN)FspmHeaderPtr->CfgRegionSize); ASSERT (FspmUpdDataPtr != NULL); SourceData = (UINTN *)((UINTN)FspmHeaderPtr->ImageBase + (UINTN)FspmHeaderPtr->CfgRegionOffset); CopyMem (FspmUpdDataPtr, SourceData, (UINTN)FspmHeaderPtr->CfgRegionSize); DEBUG ((DEBUG_INFO, "UpdateFspmUpdData enter\n")); UpdateFspmUpdData ((VOID *)FspmUpdDataPtr); DEBUG ((DEBUG_INFO, " NvsBufferPtr - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.NvsBufferPtr)); DEBUG ((DEBUG_INFO, " StackBase - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.StackBase)); DEBUG ((DEBUG_INFO, " StackSize - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.StackSize)); DEBUG ((DEBUG_INFO, " BootLoaderTolumSize - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.BootLoaderTolumSize)); DEBUG ((DEBUG_INFO, " BootMode - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.BootMode)); DEBUG ((DEBUG_INFO, " HobListPtr - 0x%x\n", &FspHobListPtr)); TimeStampCounterStart = AsmReadTsc (); Status = CallFspMemoryInit (FspmUpdDataPtr, &FspHobListPtr); // Create hobs after memory initialization and not in temp RAM. Hence passing the recorded timestamp here PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, TimeStampCounterStart, 0xD000); PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0xD07F); DEBUG ((DEBUG_INFO, "Total time spent executing FspMemoryInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000))); if (EFI_ERROR(Status)) { DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspMemoryInitApi(), Status = %r\n", Status)); } DEBUG((DEBUG_INFO, "FspMemoryInit status: 0x%x\n", Status)); ASSERT_EFI_ERROR (Status); Status = TestFspMemoryInitApiOutput (FspmUpdDataPtr, &FspHobListPtr); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "ERROR - TestFspMemoryInitApiOutput () fail, Status = %r\n", Status)); } DEBUG ((DEBUG_INFO, " FspHobListPtr (returned) - 0x%x\n", FspHobListPtr)); ASSERT (FspHobListPtr != NULL); PostFspmHobProcess (FspHobListPtr); // // FspHobList is not complete at this moment. // Save FspHobList pointer to hob, so that it can be got later // HobData = BuildGuidHob ( &gFspHobGuid, sizeof (VOID *) ); ASSERT (HobData != NULL); CopyMem (HobData, &FspHobListPtr, sizeof (FspHobListPtr)); return Status; }