| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
- * Copyright (c) 2022, Linaro Limited
- */
- #include <blk.h>
- #include <dfu.h>
- #include <efi.h>
- #include <efi_loader.h>
- #include <fwu.h>
- #include <log.h>
- #include <part.h>
- #include <linux/errno.h>
- static int get_gpt_dfu_identifier(struct blk_desc *desc, efi_guid_t *image_guid)
- {
- int i;
- struct disk_partition info;
- efi_guid_t unique_part_guid;
- for (i = 1; i < MAX_SEARCH_PARTITIONS; i++) {
- if (part_get_info(desc, i, &info))
- continue;
- uuid_str_to_bin(info.uuid, unique_part_guid.b,
- UUID_STR_FORMAT_GUID);
- if (!guidcmp(&unique_part_guid, image_guid))
- return i;
- }
- log_err("No partition found with image_guid %pUs\n", image_guid);
- return -ENOENT;
- }
- static int fwu_alt_num_for_dfu_dev(struct dfu_entity *dfu, int dev_num,
- int part, unsigned char dfu_dev,
- u8 *alt_num)
- {
- int ret;
- switch(dfu_dev) {
- case DFU_DEV_MMC:
- if (dfu->layout == DFU_RAW_ADDR &&
- dfu->data.mmc.dev_num == dev_num &&
- dfu->data.mmc.part == part) {
- *alt_num = dfu->alt;
- ret = 0;
- } else {
- ret = -ENOENT;
- }
- break;
- default:
- ret = -ENOENT;
- }
- return ret;
- }
- static int fwu_gpt_get_alt_num(struct blk_desc *desc, efi_guid_t *image_guid,
- u8 *alt_num, unsigned char dfu_dev)
- {
- int ret = -1;
- int i, part, dev_num;
- struct dfu_entity *dfu;
- dev_num = desc->devnum;
- part = get_gpt_dfu_identifier(desc, image_guid);
- if (part < 0)
- return -ENOENT;
- ret = dfu_init_env_entities(NULL, NULL);
- if (ret)
- goto out;
- i = 0;
- while (true) {
- dfu = dfu_get_entity(i++);
- if (!dfu) {
- ret = -ENOENT;
- break;
- }
- if (dfu->dev_type != dfu_dev)
- continue;
- ret = fwu_alt_num_for_dfu_dev(dfu, dev_num, part, dfu_dev,
- alt_num);
- if (!ret)
- break;
- }
- out:
- dfu_free_entities();
- return ret;
- }
- /**
- * fwu_plat_get_alt_num() - Get the DFU alt number
- * @dev: FWU metadata device
- * @image_guid: GUID value of the image for which the alt num is to
- * be obtained
- * @alt_num: The DFU alt number for the image that is to be updated
- *
- * Get the DFU alt number for the image that is to be updated. The
- * image is identified with the image_guid parameter that is passed
- * to the function.
- *
- * Note: This is a weak function and platforms can override this with
- * their own implementation for obtaining the alt number value.
- *
- * Return: 0 if OK, -ve on error
- *
- */
- __weak int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_guid,
- u8 *alt_num)
- {
- struct fwu_mdata_gpt_blk_priv *priv = dev_get_priv(dev);
- return fwu_gpt_get_alt_num(dev_get_uclass_plat(priv->blk_dev),
- image_guid, alt_num, DFU_DEV_MMC);
- }
|