soc/qualcomm: Add Kconfig to skip redundant MMU toggling

Introduce SOC_QUALCOMM_QCLIB_SKIP_MMU_TOGGLE to allow platforms to
maintain the MMU state across the QCLib execution boundary.

Traditionally, coreboot enables the MMU and performs cache maintenance
before disabling it and handing control to QCLib. QCLib then performs
its own initialization: saving MMU registers, performing cache flushes,
and disabling the MMU before returning to coreboot. During the
subsequent entry, QCLib would restore registers and repeat the cycle.

By selecting this Kconfig, we optimize boot time by avoiding these
repeated enable/disable operations. QCLib is permitted to utilize the
MMU context already established by coreboot, bypassing redundant
reinitialization, register restoration, and expensive cache flushes
to the Point of Coherency.

- Legacy platforms continue to toggle the MMU by default.
- Platforms selecting this option bypass mmu_disable() and mmu_enable().

BUG=b:449871690, b:477139887
TEST=Able to reduce boot time by 600ms while booting google/quenbi.

Change-Id: I6b5e199afc27dcb27d74d2753d2ce269ee22f0ac
Signed-off-by: Subrata Banik <subratabanik@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/90041
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Kapil Porwal <kapilporwal@google.com>
This commit is contained in:
Subrata Banik 2026-02-18 12:31:05 +05:30
commit 220669643b
2 changed files with 32 additions and 11 deletions

View file

@ -41,4 +41,17 @@ config QC_RAMDUMP_ENABLE
Ramdump is a debug image that is loaded during a system crash to capture
memory contents for post-crash analysis.
config SOC_QUALCOMM_QCLIB_SKIP_MMU_TOGGLE
bool
default n
help
Avoid disabling and re-enabling the MMU during QCLib execution.
Select this option if the platform's QCLib version supports running
within the existing coreboot MMU configuration without modification.
Enabling this reduces boot latency by eliminating redundant cache
flushes and TLB invalidations associated with mmu_disable() and
mmu_enable() calls.
endif

View file

@ -224,20 +224,28 @@ static void qclib_prepare_and_run(void)
printk(BIOS_DEBUG, "Jumping to QCLib code at %p(%p)\n",
prog_entry(&qclib), prog_entry_arg(&qclib));
/* back-up mmu context before disabling mmu and executing qclib */
mmu_save_context(&pre_qclib_mmu_context);
/* disable mmu before jumping to qclib. mmu_disable also
flushes and invalidates caches before disabling mmu. */
mmu_disable();
/*
* Backup MMU context and disable the MMU before executing QCLib,
* unless the platform handles QCLib with the MMU enabled.
* mmu_disable() also handles required cache maintenance.
*/
if (!CONFIG(SOC_QUALCOMM_QCLIB_SKIP_MMU_TOGGLE)) {
mmu_save_context(&pre_qclib_mmu_context);
mmu_disable();
}
prog_run(&qclib);
/* Before returning, QCLib flushes cache and disables mmu.
Explicitly disable mmu (flush, invalidate and disable mmu)
before re-enabling mmu with backed-up mmu context */
mmu_disable();
mmu_restore_context(&pre_qclib_mmu_context);
mmu_enable();
/*
* Post-QCLib execution: If the MMU was toggled off, ensure it is
* cleanly disabled (flushed/invalidated) before restoring the
* previous context and re-enabling. Otherwise, just restore context.
*/
if (!CONFIG(SOC_QUALCOMM_QCLIB_SKIP_MMU_TOGGLE)) {
mmu_disable();
mmu_restore_context(&pre_qclib_mmu_context);
mmu_enable();
}
if (qclib_cb_if_table.global_attributes & QCLIB_GA_FORCE_COLD_REBOOT) {
printk(BIOS_NOTICE, "QcLib requested cold reboot\n");