rockchip: capsule: Add functions for supporting capsule updates
Add functions needed to support the UEFI capsule update feature on rockchip boards. Currently, the feature is being enabled on the RockPi4 boards with firmware images residing on GPT partitioned storage media. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
This commit is contained in:
parent
b5194c2258
commit
bea9267d7e
@ -246,6 +246,7 @@ config ROCKCHIP_RK3399
|
||||
select DM_PMIC
|
||||
select DM_REGULATOR_FIXED
|
||||
select BOARD_LATE_INIT
|
||||
imply PARTITION_TYPE_GUID
|
||||
imply PRE_CONSOLE_BUFFER
|
||||
imply ROCKCHIP_COMMON_BOARD
|
||||
imply ROCKCHIP_SDRAM_COMMON
|
||||
|
@ -6,11 +6,15 @@
|
||||
#include <clk.h>
|
||||
#include <cpu_func.h>
|
||||
#include <dm.h>
|
||||
#include <efi_loader.h>
|
||||
#include <fastboot.h>
|
||||
#include <init.h>
|
||||
#include <log.h>
|
||||
#include <mmc.h>
|
||||
#include <part.h>
|
||||
#include <ram.h>
|
||||
#include <syscon.h>
|
||||
#include <uuid.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <asm/io.h>
|
||||
@ -22,8 +26,157 @@
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#if defined(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) && defined(CONFIG_EFI_PARTITION)
|
||||
|
||||
#define DFU_ALT_BUF_LEN SZ_1K
|
||||
|
||||
static struct efi_fw_image *fw_images;
|
||||
|
||||
static bool updatable_image(struct disk_partition *info)
|
||||
{
|
||||
int i;
|
||||
bool ret = false;
|
||||
efi_guid_t image_type_guid;
|
||||
|
||||
uuid_str_to_bin(info->type_guid, image_type_guid.b,
|
||||
UUID_STR_FORMAT_GUID);
|
||||
|
||||
for (i = 0; i < num_image_type_guids; i++) {
|
||||
if (!guidcmp(&fw_images[i].image_type_id, &image_type_guid)) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void set_image_index(struct disk_partition *info, int index)
|
||||
{
|
||||
int i;
|
||||
efi_guid_t image_type_guid;
|
||||
|
||||
uuid_str_to_bin(info->type_guid, image_type_guid.b,
|
||||
UUID_STR_FORMAT_GUID);
|
||||
|
||||
for (i = 0; i < num_image_type_guids; i++) {
|
||||
if (!guidcmp(&fw_images[i].image_type_id, &image_type_guid)) {
|
||||
fw_images[i].image_index = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int get_mmc_desc(struct blk_desc **desc)
|
||||
{
|
||||
int ret;
|
||||
struct mmc *mmc;
|
||||
struct udevice *dev;
|
||||
|
||||
/*
|
||||
* For now the firmware images are assumed to
|
||||
* be on the SD card
|
||||
*/
|
||||
ret = uclass_get_device(UCLASS_MMC, 1, &dev);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
mmc = mmc_get_mmc_dev(dev);
|
||||
if (!mmc)
|
||||
return -ENODEV;
|
||||
|
||||
if ((ret = mmc_init(mmc)))
|
||||
return ret;
|
||||
|
||||
*desc = mmc_get_blk_desc(mmc);
|
||||
if (!*desc)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_dfu_alt_info(char *interface, char *devstr)
|
||||
{
|
||||
const char *name;
|
||||
bool first = true;
|
||||
int p, len, devnum, ret;
|
||||
char buf[DFU_ALT_BUF_LEN];
|
||||
struct disk_partition info;
|
||||
struct blk_desc *desc = NULL;
|
||||
|
||||
ret = get_mmc_desc(&desc);
|
||||
if (ret) {
|
||||
log_err("Unable to get mmc desc\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
name = blk_get_uclass_name(desc->uclass_id);
|
||||
devnum = desc->devnum;
|
||||
len = strlen(buf);
|
||||
|
||||
len += snprintf(buf + len, DFU_ALT_BUF_LEN - len,
|
||||
"%s %d=", name, devnum);
|
||||
|
||||
for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
|
||||
if (part_get_info(desc, p, &info))
|
||||
continue;
|
||||
|
||||
/* Add entry to dfu_alt_info only for updatable images */
|
||||
if (updatable_image(&info)) {
|
||||
if (!first)
|
||||
len += snprintf(buf + len,
|
||||
DFU_ALT_BUF_LEN - len, ";");
|
||||
|
||||
len += snprintf(buf + len, DFU_ALT_BUF_LEN - len,
|
||||
"%s%d_%s part %d %d",
|
||||
name, devnum, info.name, devnum, p);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
log_debug("dfu_alt_info => %s\n", buf);
|
||||
env_set("dfu_alt_info", buf);
|
||||
}
|
||||
|
||||
static void gpt_capsule_update_setup(void)
|
||||
{
|
||||
int p, i, ret;
|
||||
struct disk_partition info;
|
||||
struct blk_desc *desc = NULL;
|
||||
|
||||
fw_images = update_info.images;
|
||||
rockchip_capsule_update_board_setup();
|
||||
|
||||
ret = get_mmc_desc(&desc);
|
||||
if (ret) {
|
||||
log_err("Unable to get mmc desc\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (p = 1, i = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
|
||||
if (part_get_info(desc, p, &info))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Since we have a GPT partitioned device, the updatable
|
||||
* images could be stored in any order. Populate the
|
||||
* image_index at runtime.
|
||||
*/
|
||||
if (updatable_image(&info)) {
|
||||
set_image_index(&info, i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_EFI_HAVE_CAPSULE_SUPPORT && CONFIG_EFI_PARTITION */
|
||||
|
||||
__weak int rk_board_late_init(void)
|
||||
{
|
||||
#if defined(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) && defined(CONFIG_EFI_PARTITION)
|
||||
gpt_capsule_update_setup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user