From 893a2b008a0f2c5f2dc43cbcedcb6cb5afb7dcad Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 2 Sep 2025 12:16:50 +0000 Subject: [PATCH] libpayload: Add coreboot boot mode table This commit adds a new coreboot table, CB_TAG_BOOT_MODE, to pass platform boot mode information to the payload. The new table defines flags for low-battery mode and off-mode charging, which are essential for a payload to properly initialize the charger driver. The cb_parse_boot_mode function is added to read this information, and the sysinfo_t structure is updated to store the parsed boot mode data. This ensures that the payload can accurately determine the system's power state at boot and payload operations are also in sync with the boot firmware. The following scenarios were tested and verified: Scenario 1: Low-battery, no charger - coreboot detects the low-battery state and performs an immediate shutdown after displaying the low-battery splash screen. Scenario 2: Low-battery, charger attached - coreboot detects the low-battery state but continues booting because a charger is present. The payload receives the low-battery information (using the same source as coreboot) and correctly initiates the charging process. Scenario 3: Off-mode charging - The system boots directly from an S5 state due to a charger being plugged in. coreboot detects the off-mode state, skips the firmware splash screen, and hands off control to the payload, which then starts charging. Scenario 4: Normal boot - The system boots without any low-battery or off-mode conditions. coreboot and the payload both detect a normal boot (using the same information), bypass charging initialization, and proceed to boot the operating system. TEST=Able to build and boot on google/quenbi device and verify the boot mode flag is correctly passed. Change-Id: Iec25c6fdfcdc5ea7c397d2430ac7b545e1e068f2 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/89015 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) --- payloads/libpayload/include/coreboot_tables.h | 18 ++++++++++++++++++ payloads/libpayload/include/sysinfo.h | 1 + payloads/libpayload/libc/coreboot.c | 10 ++++++++++ 3 files changed, 29 insertions(+) diff --git a/payloads/libpayload/include/coreboot_tables.h b/payloads/libpayload/include/coreboot_tables.h index b43a558b49..04d205c053 100644 --- a/payloads/libpayload/include/coreboot_tables.h +++ b/payloads/libpayload/include/coreboot_tables.h @@ -90,6 +90,7 @@ enum { CB_TAG_OPTION_ENUM = 0x00ca, CB_TAG_OPTION_DEFAULTS = 0x00cb, CB_TAG_OPTION_CHECKSUM = 0x00cc, + CB_TAG_BOOT_MODE = 0x00cd, }; typedef __aligned(4) uint64_t cb_uint64_t; @@ -443,6 +444,23 @@ struct cb_acpi_rsdp { cb_uint64_t rsdp_pointer; /* Address of the ACPI RSDP */ }; +enum boot_mode_t { + CB_BOOT_MODE_NORMAL, + CB_BOOT_MODE_LOW_BATTERY, + CB_BOOT_MODE_OFFMODE_CHARGING, +}; + +/* + * Boot Mode: Pass the platform boot mode information to payload about + * booting in low-battery mode or off-mode charging. These information + * is useful for payload to implement charger driver. + */ +struct cb_boot_mode { + uint32_t tag; + uint32_t size; + + enum boot_mode_t boot_mode; +}; /* Helpful inlines */ diff --git a/payloads/libpayload/include/sysinfo.h b/payloads/libpayload/include/sysinfo.h index 2db306eba9..7c47074aa1 100644 --- a/payloads/libpayload/include/sysinfo.h +++ b/payloads/libpayload/include/sysinfo.h @@ -173,6 +173,7 @@ struct sysinfo_t { /* pvmfw buffer location */ uintptr_t pvmfw; uint32_t pvmfw_size; + enum boot_mode_t boot_mode; }; extern struct sysinfo_t lib_sysinfo; diff --git a/payloads/libpayload/libc/coreboot.c b/payloads/libpayload/libc/coreboot.c index 2788f870be..11703ee178 100644 --- a/payloads/libpayload/libc/coreboot.c +++ b/payloads/libpayload/libc/coreboot.c @@ -285,6 +285,13 @@ static void cb_parse_pcie(void *ptr, struct sysinfo_t *info) info->pcie_ctrl_base = pcie->ctrl_base; } +static void cb_parse_boot_mode(void *ptr, struct sysinfo_t *info) +{ + const struct cb_boot_mode *mode = ptr; + + info->boot_mode = mode->boot_mode; +} + static void cb_parse_rsdp(void *ptr, struct sysinfo_t *info) { const struct cb_acpi_rsdp *cb_acpi_rsdp = ptr; @@ -437,6 +444,9 @@ int cb_parse_header(void *addr, int len, struct sysinfo_t *info) case CB_TAG_PCIE: cb_parse_pcie(ptr, info); break; + case CB_TAG_BOOT_MODE: + cb_parse_boot_mode(ptr, info); + break; default: cb_parse_arch_specific(rec, info); break;