mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +00:00
124 lines
2.6 KiB
C
124 lines
2.6 KiB
C
|
// 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);
|
||
|
}
|