Skip to content

[qcom-next] Multi-partition Capsule update support for Qualcomm platforms - #110

Open
balajiselvanathan wants to merge 8 commits into
qualcomm-linux:qcom-nextfrom
balajiselvanathan:capsule-update-all-qn
Open

[qcom-next] Multi-partition Capsule update support for Qualcomm platforms#110
balajiselvanathan wants to merge 8 commits into
qualcomm-linux:qcom-nextfrom
balajiselvanathan:capsule-update-all-qn

Conversation

The last_attempt_version and last_attempt_status fields in struct
fmp_state were carried but never populated, so the ESRT last-attempt
information exposed to the OS stayed at its boot-time defaults
regardless of what happened during an update.

Add the plumbing to maintain them: a helper to record the attempted
version and status, a mapping from internal efi_status_t codes to the
UEFI LAST_ATTEMPT_STATUS_* values, and reads/writes of the two fields
in efi_firmware_fill_version_info() and efi_firmware_set_fmp_state_var().
fw_version is now only advanced on a successful update so a failed
attempt no longer overwrites the recorded good version.

Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
Now that the tracking helpers exist, call them from the RAW capsule
path. efi_firmware_raw_set_image() records the attempted version and
the mapped status at each point it can bail out (verification failure,
strdup/env_set errors, and a failed dfu_write_by_alt), and records
success once the write completes.

Either way it then writes the FMP state variable, so a query of ESRT
reflects the outcome of the last attempt instead of stale boot-time
values.

Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
efi_capsule_authenticate() already strips the authentication wrapper
before it verifies the signature, so on a security violation the payload
pointer and size it computed already point at the FMP payload header -
but efi_firmware_capsule_authenticate() discards them on that path and
returns. Pass them back to the caller on the violation path too.

With that in place, move the efi_firmware_get_fw_version() call in
efi_firmware_verify_image() ahead of the error check so the version is
read whether or not authentication passed. A rejected capsule then
reports its real version in ESRT rather than a stale one.

Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
There is no easy way to see which firmware images a capsule can actually
target on a given board. On platforms that build their fw_images[] table
at runtime this is worse, since the set of images vary per board.

Add "efidebug capsule images", which walks the installed Firmware
Management Protocol handles and prints the image descriptors each one
reports, along with the image index, name and type GUID. This is the
same information capsule matching looks at, so it doubles as a quick way
to check the GUIDs in a capsule line up with what the board expects
before attempting an update.

Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
RAW capsule updates assume dfu_alt_num is always image_index - 1, i.e.
that fw_images[] is a positionally-ordered mirror of the DFU alt
settings. That holds for every board that builds its fw_images[] table
by hand, but a platform whose image list is discovered at runtime
(varying per board, with gaps for missing components) can't guarantee
image_index and dfu_alt_num stay in lockstep.

Move the (image_index - 1) calculation into a __weak function that
platforms can override, following the pattern already used for
efi_firmware_get_image_type_id(). The default keeps the
existing behaviour, so no other board needs any change.

Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
Add a third sandbox fw_images[] entry (image_index 3) that aliases
onto the same DFU alt setting as image_index 1 through a strong
efi_firmware_get_dfu_alt_num() override, plus the matching capsule
GUID and test case that applies it via ESRT and checks the write
landed. Without the override this would fail, since dfu_alt_info has
no alt number 2 (the default image_index - 1) defined.

Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
Capsule update on Qualcomm boards only ever handled a single image:
U-Boot itself, found by find_target_partition() and hardcoded as the
lone fw_images[] entry. There was no way to update any other firmware
component (xbl, tz, hyp, aop, devcfg, qupfw, ...) through a capsule.

Replace this with a table, qcom_image_map[], that maps each
partition_base to an image_index and fw_name. Scan every partition on
every probed block device; each map row with a matching partition
contributes one entry to a variable-length fw_images[] and to a
matching dfu_alt_info string. num_images is set to whatever was
actually discovered, so a component missing on a given board is simply
left out.

U-Boot's own image keeps image_index 1. Rather than a separate code
path, it is now expressed as three boot-source-gated rows (uefi/xbl/
boot), so find_target_partition()'s uefi-over-xbl priority and A/B slot
selection are reproduced by the same generic scan rather than
duplicated logic.

image_index values are frozen once a capsule references them, so
qcom_image_map[] is meant to only ever grow by appending new rows;
existing indices must never be renumbered.

Since dfu_alt_num can no longer be derived positionally from
image_index once components are missing on a board, this also adds a
strong efi_firmware_get_dfu_alt_num() override that looks up the
dfu_alt_num recorded for each image_index while building the DFU
string, falling back to the generic (image_index - 1) for anything it
doesn't recognize.

Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
Qualcomm boards apply capsule-on-disk updates from U-Boot without the
OS first setting the OsIndications EFI variable that the capsule
runtime normally checks. EFI_IGNORE_OSINDICATIONS makes U-Boot skip
that check so an on-disk capsule is applied at boot.

Set it once in the shared qcom_defconfig so the boards that include it
(qcm6490, qcs615, qcs8300, qcs9100) all pick it up.

Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant