dasharo-issues
dasharo-issues copied to clipboard
Booting is slow in QEMU
Component
Dasharo firmware
Device
QEMU Q35 Emulator
Dasharo version
v0.2.0
Dasharo Tools Suite version
No response
Brief summary
Booting takes 15-25 seconds before logo is shown. In addition, saving multiple UEFI variables at once (e.g. restoring default SB keys) is also slow.
How reproducible
100%
How to reproduce
Start with ./qemu_run.sh graphic firmware and wait for logo.
Expected behavior
- Start QEMU
- Wait a second or two
- See the Dasharo logo
Actual behavior
- Start QEMU
- Wait a second or two
- More waiting
- Just a bit more more
- See the Dasharo logo
Screenshots
No response
Additional context
Booting is significantly faster with Secure Boot enabled, but still not as fast as it should be.
Solutions you've tried
Using OvmfPkg/LocalApicTimerDxe/LocalApicTimerDxe.inf instead of HPET makes it boot faster, but it also makes the delays shorter, up to a point where tests can't traverse iPXE menu before autoboot, which should normally should take 3 seconds. It may be controlled by modifying gEfiMdePkgTokenSpaceGuid.PcdFSBClock (MdePkg defines it as 200M, while most of OVMF platforms use 1G), however I haven't tested how it would work on other platforms.
@krystian-hebel do we know where we should look for the solution to this problem? Any specific ideas to test out?
Yes, the ones described in Solutions you've tried. What is left to be tested is the impact of that change on other platforms.
Could you please link a patch/MR, so we can coordinate testing it perhaps during some other testing activities on other platforms?
Which aspects should be investigated for potential regressions on real hardware platforms?
Notes from Krystian
I haven’t pushed anything yet, but if I remember correctly, after replacing the following lines:
with: OvmfPkg/LocalApicTimerDxe/LocalApicTimerDxe.inf
and setting the frequency in:
to 1GHz, the time started flowing correctly.
However, this would break other platforms, so the change should be applied conditionally (at minimum the frequency change; possibly switching from HPET to LAPIC alone might work). Alternatively, add code to change it at runtime.
Instead of modifying MdePkg.dec directly, consider moving the change to a different .dsc file—similar to how OVMF handles it here:
Implementation Plan
-
[ ] Replace
TimerLibreferences in:- [ ]
DasharoPayloadPkg.fdf - [ ]
DasharoPayloadPkg.dscwithOvmfPkg/LocalApicTimerDxe/LocalApicTimerDxe.inf.
- [ ]
-
[ ] Set timer frequency to 1GHz in build config:
- [ ] Preferably not directly in
MdePkg.dec - [ ] Instead, move this setting to a local
.dsc(e.g., like inOvmfPkgX64.dsc)
- [ ] Preferably not directly in
-
[ ] Implement platform-specific conditional logic:
- [ ] Ensure the change does not break other platforms
- [ ] Potentially add a runtime switch (e.g., HPET → LAPIC)
-
[ ] Test time flow across all supported platforms to confirm no regressions (we can define here a list of platforms to be tested)
@macpijan this may also be relevant:
!if $(CPU_TIMER_LIB_ENABLE) == TRUE
TimerLib|UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf
!else
TimerLib|DasharoPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.inf
!endif
The timer used depends on whether certain CPUID leaves are present to determine the TSC tick frequency. For QEMU these CPUID leaves are definitely not available, so the payload is built with HPET timer support. FYI.
We can add a new define CPU_LAPIC_TIMER_LIB_ENABLE (QEMU exclusive) which would select the LAPIC timer instead of HPET timer to produce gEfiTimerArchProtocolGuid.
Have you tried disabling HPET in QEMU with -machine hpet=off parameter as a possible workaround (-machine q35,smm=on,hpet=off) instead of doing it Firmware image side? I have never used UEFI Secure Boot nor TPM in QEMU, but I do recall encountering people claiming slow boot issues with OVMF Secure Boot enabled images and QEMU SMM, check this: https://old.reddit.com/r/VFIO/comments/1jzg2uy/need_help_investigating_slow_boot_times/
So perhaps it may be a QEMU/OVMF side issue?
Couldn't changing the timer from HPET to APIC be achieved using EDK2_USE_LAPIC_TIMER config?
config EDK2_USE_LAPIC_TIMER
bool "Use LAPIC timer instead of HPET"
default n
help
Select this option to use the LAPIC timer instead of HPET in edk2. The LAPIC is closer
to the CPU than the HPET (on the PCH), resulting in lower latency / higher resolution.
This setting is at least needed for platforms with Core 2 processors, which are reported
to have issues with HPET.
Have you tried disabling HPET in QEMU with -machine hpet=off parameter as a possible workaround (-machine q35,smm=on,hpet=off) instead of doing it Firmware image side?
Disabling the hpet like you suggested causes the firmware to not boot at all. Even after 60 seconds the image is still black, no serial output.
Couldn't changing the timer from HPET to APIC be achieved using
EDK2_USE_LAPIC_TIMERconfig?config EDK2_USE_LAPIC_TIMER bool "Use LAPIC timer instead of HPET" default n help Select this option to use the LAPIC timer instead of HPET in edk2. The LAPIC is closer to the CPU than the HPET (on the PCH), resulting in lower latency / higher resolution. This setting is at least needed for platforms with Core 2 processors, which are reported to have issues with HPET.
This will cause the CPU_LAPIC_TIMER_LIB_ENABLE to be set for the build. However as I explained, it requires the CPUID leaf which QEMU doesn't support AFAIK, so this option won't do.
Disabling the hpet like you suggested causes the firmware to not boot at all. Even after 60 seconds the image is still black, no serial output.
Because you end up without any timer in that case...
Changes to fix the issue were implemented: https://github.com/Dasharo/edk2/pull/245 https://github.com/Dasharo/coreboot/pull/674 First boot takes up to 8-9 seconds now, with the consecutive reboots being quicker.