Kory has updated the A/B implementation and added an invalid bank
state. This is already described in the spec and can help boards
boot faster by skipping banks marked as invalid
This commit is contained in:
Tom Rini
2026-02-11 10:42:18 -06:00
5 changed files with 50 additions and 49 deletions

View File

@@ -80,9 +80,11 @@ struct fwu_mdata_ops {
#define FWU_IMAGE_ACCEPTED 0x1
#define FWU_BANK_INVALID (uint8_t)0xFF
#define FWU_BANK_VALID (uint8_t)0xFE
#define FWU_BANK_ACCEPTED (uint8_t)0xFC
enum fwu_bank_states {
FWU_BANK_INVALID = 0xFF,
FWU_BANK_VALID = 0xFE,
FWU_BANK_ACCEPTED = 0xFC,
};
enum {
PRIMARY_PART = 1,
@@ -396,24 +398,24 @@ int fwu_get_mdata_size(uint32_t *mdata_size);
/**
* fwu_state_machine_updates() - Update FWU state of the platform
* @trial_state: Is platform transitioning into Trial State
* @state: FWU bank state
* @update_index: Bank number to which images have been updated
*
* On successful completion of updates, transition the platform to
* either Trial State or Regular State.
* FWU_BANK_VALID transition the platform to Trial state
* FWU_BANK_ACCEPTED accept the FWU bank state
* FWU_BANK_INVALID invalid the FWU bank state
*
* To transition the platform to Trial State, start the
* TrialStateCtr counter, followed by setting the value of bank_state
* field of the metadata to Valid state(applicable only in version 2
* of metadata).
*
* In case, the platform is to transition directly to Regular State,
* update the bank_state field of the metadata to Accepted
* state(applicable only in version 2 of metadata).
* Saving the bank_state field of the metadata is only applicable in
* version 2 of metadata.
*
* Return: 0 if OK, -ve on error
*/
int fwu_state_machine_updates(bool trial_state, uint32_t update_index);
int fwu_state_machine_updates(enum fwu_bank_states state, uint32_t update_index);
/**
* fwu_init() - FWU specific initialisations

View File

@@ -465,7 +465,7 @@ static __maybe_unused efi_status_t fwu_empty_capsule_process(
log_err("Unable to set the Accept bit for the image %pUs\n",
image_guid);
status = fwu_state_machine_updates(0, active_idx);
status = fwu_state_machine_updates(FWU_BANK_ACCEPTED, active_idx);
if (status < 0)
ret = EFI_DEVICE_ERROR;
@@ -510,7 +510,8 @@ static __maybe_unused efi_status_t fwu_post_update_process(bool fw_accept_os)
log_err("Failed to update FWU metadata index values\n");
} else {
log_debug("Successfully updated the active_index\n");
status = fwu_state_machine_updates(fw_accept_os ? 1 : 0,
status = fwu_state_machine_updates(fw_accept_os ?
FWU_BANK_VALID : FWU_BANK_ACCEPTED,
update_index);
if (status < 0)
ret = EFI_DEVICE_ERROR;

View File

@@ -766,6 +766,12 @@ static int fwu_boottime_checks(void)
if (boot_idx != active_idx) {
log_info("Boot idx %u is not matching active idx %u, changing active_idx\n",
boot_idx, active_idx);
ret = fwu_state_machine_updates(FWU_BANK_INVALID, active_idx);
if (ret)
log_err("Unable to set bank %u state as invalid",
active_idx);
ret = fwu_set_active_index(boot_idx);
if (!ret)
boottime_check = 1;

View File

@@ -98,27 +98,27 @@ void fwu_populate_mdata_image_info(struct fwu_data *data)
/**
* fwu_state_machine_updates() - Update FWU state of the platform
* @trial_state: Is platform transitioning into Trial State
* @state: FWU bank state
* @update_index: Bank number to which images have been updated
*
* On successful completion of updates, transition the platform to
* either Trial State or Regular State.
* FWU_BANK_VALID transition the platform to Trial state
* FWU_BANK_ACCEPTED accept the FWU bank state
* FWU_BANK_INVALID invalid the FWU bank state
*
* To transition the platform to Trial State, start the
* TrialStateCtr counter, followed by setting the value of bank_state
* field of the metadata to Valid state(applicable only in version 2
* of metadata).
*
* In case, the platform is to transition directly to Regular State,
* update the bank_state field of the metadata to Accepted
* state(applicable only in version 2 of metadata).
* Saving the bank_state field of the metadata is only applicable in
* version 2 of metadata.
*
* Return: 0 if OK, -ve on error
*/
int fwu_state_machine_updates(bool trial_state,
int fwu_state_machine_updates(enum fwu_bank_states state,
uint32_t update_index)
{
return fwu_trial_state_update(trial_state, update_index);
return fwu_trial_state_update(state == FWU_BANK_VALID, update_index);
}
/**

View File

@@ -80,42 +80,27 @@ static int fwu_mdata_sanity_checks(void)
return 0;
}
static int fwu_bank_state_update(bool trial_state, uint32_t bank)
static int fwu_bank_state_update(enum fwu_bank_states state, uint32_t bank)
{
int ret;
struct fwu_data *data = fwu_get_data();
struct fwu_mdata *mdata = data->fwu_mdata;
if (!trial_state && !fwu_bank_accepted(data, bank))
if (state == FWU_BANK_ACCEPTED && !fwu_bank_accepted(data, bank))
return 0;
mdata->bank_state[bank] = data->bank_state[bank] = trial_state ?
FWU_BANK_VALID : FWU_BANK_ACCEPTED;
mdata->bank_state[bank] = (uint8_t)state;
data->bank_state[bank] = (uint8_t)state;
ret = fwu_sync_mdata(mdata, BOTH_PARTS);
if (ret)
log_err("Unable to set bank_state for bank %u\n", bank);
else
data->trial_state = trial_state;
data->trial_state = state == FWU_BANK_VALID ? 1 : 0;
return ret;
}
static int fwu_trial_state_start(uint update_index)
{
int ret;
ret = fwu_trial_state_ctr_start();
if (ret)
return ret;
ret = fwu_bank_state_update(1, update_index);
if (ret)
return ret;
return 0;
}
static bool fwu_get_mdata_mandatory(uint part)
{
int ret = 0;
@@ -171,27 +156,34 @@ void fwu_populate_mdata_image_info(struct fwu_data *data)
/**
* fwu_state_machine_updates() - Update FWU state of the platform
* @trial_state: Is platform transitioning into Trial State
* @state: FWU bank state
* @update_index: Bank number to which images have been updated
*
* On successful completion of updates, transition the platform to
* either Trial State or Regular State.
* FWU_BANK_VALID transition the platform to Trial state
* FWU_BANK_ACCEPTED accept the FWU bank state
* FWU_BANK_INVALID invalid the FWU bank state
*
* To transition the platform to Trial State, start the
* TrialStateCtr counter, followed by setting the value of bank_state
* field of the metadata to Valid state(applicable only in version 2
* of metadata).
*
* In case, the platform is to transition directly to Regular State,
* update the bank_state field of the metadata to Accepted
* state(applicable only in version 2 of metadata).
* Saving the bank_state field of the metadata is only applicable in
* version 2 of metadata.
*
* Return: 0 if OK, -ve on error
*/
int fwu_state_machine_updates(bool trial_state, uint32_t update_index)
int fwu_state_machine_updates(enum fwu_bank_states state, uint32_t update_index)
{
return trial_state ? fwu_trial_state_start(update_index) :
fwu_bank_state_update(0, update_index);
int ret;
if (state == FWU_BANK_VALID) {
ret = fwu_trial_state_ctr_start();
if (ret)
return ret;
}
return fwu_bank_state_update(state, update_index);
}
/**