bootm: Update FPDT boot times before handing off to OS
Update the FPDT boot performance record's ebs_entry and ebs_exit fields in bootm_final() to record the time when we're about to hand off to the operating system. The timing is recorded just before we start the kernel, after all device cleanup and before interrupts are disabled, which corresponds to the ExitBootServices phase in UEFI. If EFI is used to boot, a further update could be made, but that is left for later. Avoid including asm/acpi_table.h on platforms without ACPI. Ad a special case for the QEMU RISC-V ACPI board. Series-changes: 2 - Depend on ACPIGEN instead of GENERATE_ACPI_TABLE - Avoid including asm/acpi_table.h on platforms without ACPI Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include <bootstage.h>
|
||||
#include <event.h>
|
||||
#include <usb.h>
|
||||
#include <acpi/acpi_table.h>
|
||||
#include <dm/root.h>
|
||||
|
||||
__weak void board_quiesce_devices(void)
|
||||
@@ -25,6 +26,11 @@ void bootm_final(enum bootm_final_t flags)
|
||||
|
||||
bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
|
||||
|
||||
/* Update FPDT boot performance record if it exists */
|
||||
if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE) &&
|
||||
IS_ENABLED(CONFIG_ACPIGEN))
|
||||
acpi_final_fpdt();
|
||||
|
||||
if (IS_ENABLED(CONFIG_BOOTSTAGE_FDT) && IS_ENABLED(CONFIG_CMD_FDT))
|
||||
bootstage_fdt_add_report();
|
||||
if (IS_ENABLED(CONFIG_BOOTSTAGE_REPORT))
|
||||
|
||||
@@ -1383,8 +1383,22 @@ struct acpi_fpdt_boot *acpi_get_fpdt_boot(void);
|
||||
*/
|
||||
int acpi_fix_fpdt_checksum(void);
|
||||
|
||||
/**
|
||||
* acpi_final_fpdt() - Finalize FPDT boot performance record before OS handoff
|
||||
*
|
||||
* Updates the FPDT boot performance record with the final boot timing
|
||||
* information just before handing control to the operating system. This
|
||||
* sets the ExitBootServices entry and exit times to the current time.
|
||||
* If FPDT table exists, the checksum is automatically recalculated.
|
||||
*
|
||||
* This function does nothing if the FPDT table is not present.
|
||||
*/
|
||||
void acpi_final_fpdt(void);
|
||||
|
||||
#endif /* !__ACPI__*/
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
#include <asm/acpi_table.h>
|
||||
#endif
|
||||
|
||||
#endif /* __ACPI_TABLE_H__ */
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <mapmem.h>
|
||||
#include <tables_csum.h>
|
||||
#include <serial.h>
|
||||
#include <timer.h>
|
||||
#include <acpi/acpi_table.h>
|
||||
#include <acpi/acpi_device.h>
|
||||
#include <asm/global_data.h>
|
||||
@@ -786,6 +787,24 @@ int acpi_fix_fpdt_checksum(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void acpi_final_fpdt(void)
|
||||
{
|
||||
struct acpi_fpdt_boot *fpdt;
|
||||
|
||||
if (IS_ENABLED(CONFIG_TARGET_QEMU_VIRT))
|
||||
return;
|
||||
|
||||
fpdt = acpi_get_fpdt_boot();
|
||||
if (fpdt) {
|
||||
u64 time;
|
||||
|
||||
time = timer_get_boot_us();
|
||||
fpdt->ebs_entry = time;
|
||||
fpdt->ebs_exit = time;
|
||||
acpi_fix_fpdt_checksum();
|
||||
}
|
||||
}
|
||||
|
||||
/* this board lacks the bootstage timer */
|
||||
#ifndef CONFIG_TARGET_QEMU_VIRT
|
||||
|
||||
@@ -799,4 +818,5 @@ static int acpi_create_fpdt(struct acpi_ctx *ctx,
|
||||
return acpi_write_fpdt(ctx, uboot_start);
|
||||
}
|
||||
ACPI_WRITER(6fpdt, "FPDT", acpi_create_fpdt, 0);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user