/** Measure main BIOS. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS MeasureMainBios ( VOID ) { EFI_STATUS Status; UINT32 FvInstances; EFI_PEI_FV_HANDLE VolumeHandle; EFI_FV_INFO VolumeInfo; EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi; PERF_START_EX (mFileHandle, "EventRec", "TrEEPei", 0, PERF_ID_TREE_PEI); FvInstances = 0; while (TRUE) { // // Traverse all firmware volume instances of Static Core Root of Trust for Measurement // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special // platform for special CRTM TPM measuring. // Status = PeiServicesFfsFindNextVolume (FvInstances, &VolumeHandle); if (EFI_ERROR (Status)) { break; } // // Measure and record the firmware volume that is dispatched by PeiCore // Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo); ASSERT_EFI_ERROR (Status); // // Locate the corresponding FV_PPI according to founded FV's format guid // Status = PeiServicesLocatePpi ( &VolumeInfo.FvFormat, 0, NULL, (VOID**)&FvPpi ); if (!EFI_ERROR (Status)) { MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) VolumeInfo.FvStart, VolumeInfo.FvSize); } FvInstances++; } PERF_END_EX (mFileHandle, "EventRec", "TrEEPei", 0, PERF_ID_TREE_PEI + 1); return EFI_SUCCESS; }
/** This function returns control to BootLoader after TempRamExitApi. @param[in] Status return status for the TempRamExitApi. **/ VOID EFIAPI FspTempRamExitDone2 ( IN EFI_STATUS Status ) { // // Convert to FSP EAS defined API return codes // switch (Status) { case EFI_SUCCESS: case EFI_INVALID_PARAMETER: case EFI_UNSUPPORTED: case EFI_DEVICE_ERROR: break; default: DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() Invalid Error - [Status: 0x%08X]\n", Status)); Status = EFI_DEVICE_ERROR; // Force to known error. break; } // // This is the end of the TempRamExit API // Give control back to the boot loader // DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - [Status: 0x%08X] - End\n", Status)); SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT); PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); do { SetFspApiReturnStatus (Status); Pei2LoaderSwitchStack (); if (Status != EFI_SUCCESS) { DEBUG ((DEBUG_ERROR, "!!!ERROR: TempRamExitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status)); } } while (Status != EFI_SUCCESS); SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT); SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY); PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); DEBUG ((DEBUG_INFO | DEBUG_INIT, "SiliconInitApi() - Begin\n")); }
/** This function transfer control back to BootLoader after FspSiliconInit. **/ VOID EFIAPI FspSiliconInitDone ( VOID ) { // // This is the end of the FspSiliconInit API // Give control back to the boot loader // SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_EXIT); DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - End\n")); PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, 0x907F); REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); SetFspApiReturnStatus (EFI_SUCCESS); Pei2LoaderSwitchStack(); PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, 0x6000); }
/** 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. // }
/** This function returns control to BootLoader after MemoryInitApi. @param[in] Status return status for the MemoryInitApi. @param[in,out] HobListPtr The address of HobList pointer, if NULL, will get value from GetFspApiParameter2 () **/ VOID EFIAPI FspMemoryInitDone2 ( IN EFI_STATUS Status, IN OUT VOID **HobListPtr ) { FSP_GLOBAL_DATA *FspData; // // Calling use FspMemoryInit API // Update HOB and return the control directly // if (HobListPtr == NULL) { HobListPtr = (VOID **)GetFspApiParameter2 (); } if (HobListPtr != NULL) { *HobListPtr = (VOID *) GetHobList (); } // // Convert to FSP EAS defined API return codes // switch (Status) { case EFI_SUCCESS: case EFI_INVALID_PARAMETER: case EFI_UNSUPPORTED: case EFI_DEVICE_ERROR: case EFI_OUT_OF_RESOURCES: break; default: DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() Invalid Error [Status: 0x%08X]\n", Status)); Status = EFI_DEVICE_ERROR; // Force to known error. break; } // // This is the end of the FspMemoryInit API // Give control back to the boot loader // DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() - [Status: 0x%08X] - End\n", Status)); SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT); FspData = GetFspGlobalDataPointer (); PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[0] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_TEMP_RAM_INIT | FSP_STATUS_CODE_COMMON_CODE| FSP_STATUS_CODE_API_ENTRY); PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[1] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_TEMP_RAM_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[2] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); do { SetFspApiReturnStatus (Status); Pei2LoaderSwitchStack (); if (Status != EFI_SUCCESS) { DEBUG ((DEBUG_ERROR, "!!!ERROR: FspMemoryInitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status)); } } while (Status != EFI_SUCCESS); // // The TempRamExitApi is called // if (GetFspApiCallingIndex () == TempRamExitApiIndex) { SetPhaseStatusCode (FSP_STATUS_CODE_TEMP_RAM_EXIT); SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY); PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - Begin\n")); } else { SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT); SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY); PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - Begin\n")); } }
/** 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; }