/** Produce current time as ascii text string @retval pointer to statuc buffer with current time or zero length string **/ CHAR8* GetTiming(VOID) { UINT64 dTStartSec; UINT64 dTStartMs; UINT64 dTLastSec; UINT64 dTLastMs; UINT64 CurrentTsc; mTimingTxt[0] = '\0'; if (mMemLog != NULL && mMemLog->TscFreqSec != 0) { CurrentTsc = AsmReadTsc(); dTStartMs = DivU64x64Remainder(MultU64x32(CurrentTsc - mMemLog->TscStart, 1000), mMemLog->TscFreqSec, NULL); dTStartSec = DivU64x64Remainder(dTStartMs, 1000, &dTStartMs); dTLastMs = DivU64x64Remainder(MultU64x32(CurrentTsc - mMemLog->TscLast, 1000), mMemLog->TscFreqSec, NULL); dTLastSec = DivU64x64Remainder(dTLastMs, 1000, &dTLastMs); AsciiSPrint(mTimingTxt, sizeof(mTimingTxt), "%ld:%03ld %ld:%03ld", dTStartSec, dTStartMs, dTLastSec, dTLastMs); mMemLog->TscLast = CurrentTsc; } return mTimingTxt; }
/** Retrieves the current value of a 64-bit free running performance counter. Retrieves the current value of a 64-bit free running performance counter. The counter can either count up by 1 or count down by 1. If the physical performance counter counts by a larger increment, then the counter values must be translated. The properties of the counter can be retrieved from GetPerformanceCounterProperties(). @return The current value of the free running performance counter. **/ UINT64 EFIAPI GetPerformanceCounter ( VOID ) { return AsmReadTsc(); }
/** Set FSP measurement point timestamp. @param[in] Id Measurement point ID. @return performance timestamp. **/ UINT64 EFIAPI SetFspMeasurePoint ( IN UINT8 Id ) { FSP_GLOBAL_DATA *FspData; // // Bit [55: 0] will be the timestamp // Bit [63:56] will be the ID // FspData = GetFspGlobalDataPointer (); if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) { FspData->PerfData[FspData->PerfIdx] = AsmReadTsc (); ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id; } return FspData->PerfData[(FspData->PerfIdx)++]; }
UINT8 smb_read_byte(UINT32 base, UINT8 adr, UINT8 cmd) { // INTN l1, h1, l2, h2; UINT64 t, t1, t2; if (smbIntel) { IoWrite8(base + SMBHSTSTS, 0x1f); // reset SMBus Controller IoWrite8(base + SMBHSTDAT, 0xff); t1 = AsmReadTsc(); //rdtsc(l1, h1); while ( IoRead8(base + SMBHSTSTS) & 0x01) // wait until read { t2 = AsmReadTsc(); //rdtsc(l2, h2); t = DivU64x64Remainder((t2 - t1), DivU64x32(gCPUStructure.TSCFrequency, 1000), 0); if (t > 5) return 0xFF; // break } IoWrite8(base + SMBHSTCMD, cmd); IoWrite8(base + SMBHSTADD, (adr << 1) | 0x01 ); IoWrite8(base + SMBHSTCNT, 0x48 ); t1 = AsmReadTsc(); while (!( IoRead8(base + SMBHSTSTS) & 0x02)) // wait til command finished { t2 = AsmReadTsc(); t = DivU64x64Remainder((t2 - t1), DivU64x32(gCPUStructure.TSCFrequency, 1000), 0); if (t > 5) break; // break after 5ms } return IoRead8(base + SMBHSTDAT); } else { IoWrite8(base + SMBHSTSTS_NV, 0x1f); // reset SMBus Controller IoWrite8(base + SMBHSTDAT_NV, 0xff); t1 = AsmReadTsc(); //rdtsc(l1, h1); while ( IoRead8(base + SMBHSTSTS_NV) & 0x01) // wait until read { t2 = AsmReadTsc(); //rdtsc(l2, h2); t = DivU64x64Remainder((t2 - t1), DivU64x32(gCPUStructure.TSCFrequency, 1000), 0); if (t > 5) return 0xFF; // break } IoWrite8(base + SMBHSTSTS_NV, 0x00); // clear status register IoWrite8(base + SMBHSTCMD_NV, cmd); IoWrite8(base + SMBHSTADD_NV, (adr << 1) | 0x01 ); IoWrite8(base + SMBHPRTCL_NV, 0x07 ); t1 = AsmReadTsc(); while (!( IoRead8(base + SMBHSTSTS_NV) & 0x9F)) // wait till command finished { t2 = AsmReadTsc(); t = DivU64x64Remainder((t2 - t1), DivU64x32(gCPUStructure.TSCFrequency, 1000), 0); if (t > 5) break; // break after 5ms } return IoRead8(base + SMBHSTDAT_NV); } }
/** 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; }
/** Inits mem log. @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. **/ EFI_STATUS EFIAPI MemLogInit ( VOID ) { EFI_STATUS Status; UINT64 T0; UINT64 T1; if (mMemLog != NULL) { return EFI_SUCCESS; } // // Try to use existing MEM_LOG // Status = gBS->LocateProtocol (&mMemLogProtocolGuid, NULL, (VOID **) &mMemLog); if (Status == EFI_SUCCESS && mMemLog != NULL) { // // We are inited with existing MEM_LOG // return EFI_SUCCESS; } // // Set up and publish new MEM_LOG // mMemLog = AllocateZeroPool ( sizeof (MEM_LOG) ); if (mMemLog == NULL) { return EFI_OUT_OF_RESOURCES; } mMemLog->BufferSize = MEM_LOG_INITIAL_SIZE; mMemLog->Buffer = AllocateZeroPool (MEM_LOG_INITIAL_SIZE); mMemLog->Cursor = mMemLog->Buffer; mMemLog->Callback = NULL; // // Calibrate TSC for timings // T0 = AsmReadTsc(); gBS->Stall(100000); //100ms T1 = AsmReadTsc(); mMemLog->TscFreqSec = MultU64x32((T1 - T0), 10); mMemLog->TscStart = T0; mMemLog->TscLast = T0; // // Install (publish) MEM_LOG // Status = gBS->InstallMultipleProtocolInterfaces ( &gImageHandle, &mMemLogProtocolGuid, mMemLog, NULL ); MemLog(FALSE, 1, FIRMWARE_REVISION_ASCII); MemLog(FALSE, 1, FIRMWARE_BUILDDATE_ASCII); MemLog(TRUE, 1, "\nMemLog inited, TSC freq: %ld\n", mMemLog->TscFreqSec); return Status; }