diff --git a/src/drivers/efi/capsules.c b/src/drivers/efi/capsules.c index e8078bbd48..bb63de908f 100644 --- a/src/drivers/efi/capsules.c +++ b/src/drivers/efi/capsules.c @@ -10,9 +10,10 @@ #include #include #include +#include +#include #include #include -#include #include #include @@ -786,3 +787,16 @@ static void parse_capsules(void *unused) BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, parse_capsules, NULL); #endif + +static void enable_capsule_smi(void *unused) +{ + uint32_t ret; + + ret = call_smm(APM_CNT_SMMSTORE, SMMSTORE_CMD_USE_FULL_FLASH, + (void*)(uintptr_t)uefi_capsule_count); + + printk(BIOS_INFO, "%sabled capsule update SMI handler\n", + ret == SMMSTORE_RET_SUCCESS ? "En" : "Dis"); +} + +BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_ENTRY, enable_capsule_smi, NULL); diff --git a/src/drivers/smmstore/smi.c b/src/drivers/smmstore/smi.c index 053d88817f..3ac52dc345 100644 --- a/src/drivers/smmstore/smi.c +++ b/src/drivers/smmstore/smi.c @@ -138,7 +138,7 @@ static uint32_t smmstorev2_exec(uint8_t command, void *param) uint32_t smmstore_exec(uint8_t command, void *param) { - if (smmstore_preprocess_cmd(&command)) + if (smmstore_preprocess_cmd(&command, param)) return SMMSTORE_RET_SUCCESS; if (command != SMMSTORE_CMD_CLEAR && !param) diff --git a/src/drivers/smmstore/store.c b/src/drivers/smmstore/store.c index a5053329f1..2fca79f180 100644 --- a/src/drivers/smmstore/store.c +++ b/src/drivers/smmstore/store.c @@ -49,11 +49,20 @@ _Static_assert(SMM_BLOCK_SIZE <= FMAP_SECTION_SMMSTORE_SIZE, */ static int use_full_flash; +static int has_capsules = -1; -int smmstore_preprocess_cmd(uint8_t *cmd) +int smmstore_preprocess_cmd(uint8_t *cmd, void *param) { if (CONFIG(DRIVERS_EFI_UPDATE_CAPSULES)) { - if (*cmd & SMMSTORE_CMD_USE_FULL_FLASH) { + if (has_capsules == -1 && *cmd == SMMSTORE_CMD_USE_FULL_FLASH) { + has_capsules = !!(uintptr_t)param; + /* + * If we have capsules, return success, otherwise let smmstore_exec() + * fail on !param check, which will be 0 in that case. This informs + * the caller whether capsule handling was enabled or not. + */ + return has_capsules; + } else if (has_capsules == 1 && *cmd & SMMSTORE_CMD_USE_FULL_FLASH) { use_full_flash = 1; *cmd &= ~SMMSTORE_CMD_USE_FULL_FLASH; } else { diff --git a/src/include/smmstore.h b/src/include/smmstore.h index 829170c3c3..202e681ab9 100644 --- a/src/include/smmstore.h +++ b/src/include/smmstore.h @@ -121,7 +121,7 @@ int smmstore_get_info(struct smmstore_params_info *info); struct region_device; int smmstore_lookup_region(struct region_device *rstore); /* Returns 0 if normal parsing should continue, 1 otherwise */ -int smmstore_preprocess_cmd(uint8_t *cmd); +int smmstore_preprocess_cmd(uint8_t *cmd, void *param); /* Advertise SMMSTORE v2 support */ struct lb_header;