DasharoPayloadPkg: Use proper timer for firmware performance measurement

coreboot always uses TSC for timestamps, force correct timer library
so measurements are accurate. A mismatch of timers will result in
incorrect tick and nanosecond calculations due to different timer
frequency.

Add a copy of BaseCpuTimerLib from UefiCpuPkg and replace TSC frequency
calculation with the value obtained from coreboot timestamp table.
On Intel systems where the UefiCpuPkg/CpuTimerLib is used, there is no
mismatch. However, AMD systems do not have the required CPUID, so the
default timer is HPET, not TSC.

TEST=Boot Gigabyte MZ33-AR1 and use systemd-analyze. The firmware boot
time is no longer 19 minutes, but indicates correct time spent in
firmware.

Upstream-Status: Pending
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
This commit is contained in:
Michał Żygowski
2026-03-23 10:56:48 +01:00
parent 9b14cd3199
commit 0beada2027
2 changed files with 6 additions and 7 deletions
+4 -5
View File
@@ -276,8 +276,8 @@
# coreboot will expose proper ACPI Timer I/O port from QEMU too
# No need to use OVMF HPET Timer libraries
TimerLib|DasharoPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.inf
!else
!if $(CPU_TIMER_LIB_ENABLE) == TRUE
!elseif $(CPU_TIMER_LIB_ENABLE) == TRUE
# QEMU_PLATFORM and CPU_TIMER_LIB_ENABLE are mutually exclusive
TimerLib|UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf
!else
# coreboot always uses TSC for timestamps, force correct timer library so performance
@@ -288,9 +288,8 @@
TimerLib|DasharoPayloadPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf
!else
TimerLib|DasharoPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.inf
!endif # PERFORMANCE_MEASUREMENT_ENABLE
!endif # CPU_TIMER_LIB_ENABLE
!endif # QEMU_PLATFORM
!endif
!endif # $(QEMU_PLATFORM) == FASLE && $(CPU_TIMER_LIB_ENABLE) == FALSE
ResetSystemLib|DasharoPayloadPkg/Library/ResetSystemLib/ResetSystemLib.inf
!if (($(USE_CBMEM_FOR_CONSOLE) == TRUE) && ($(TARGET) == RELEASE))
@@ -1136,13 +1136,13 @@ ParseTimestampTable (
CbEntry = FindCbTag (CB_TAG_TIMESTAMPS);
if (CbEntry == NULL) {
DEBUG ((DEBUG_ERROR, "coreboot timestamp entry not found\n"));
return 0;
return RETURN_NOT_FOUND;
}
CbTsRec = (struct timestamp_table *)(UINTN)CbEntry->address;
if (CbTsRec == NULL) {
DEBUG ((DEBUG_ERROR, "coreboot timestamp table not found\n"));
return 0;
return RETURN_NOT_FOUND;
}
Frequency = MultU64x32 (CbTsRec->tick_freq_mhz, 1000000u);