113 lines
2.7 KiB
C
113 lines
2.7 KiB
C
// SPDX-License-Identifier: BSD-3-Clause
|
|
/*
|
|
* Copyright (c) 2019 The Fuchsia Authors
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <amlogic/image_check.h>
|
|
#include <bootm.h>
|
|
#include <command.h>
|
|
#include <config.h>
|
|
#include <environment.h>
|
|
#include <image.h>
|
|
|
|
#include <zircon/image.h>
|
|
#include <zircon/partition.h>
|
|
#include <zircon/abr.h>
|
|
|
|
#include <asm/arch/bl31_apis.h>
|
|
#include <asm/arch/secure_apb.h>
|
|
#include <linux/compat.h>
|
|
|
|
size_t img_offset;
|
|
|
|
static int do_zbi_load(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
|
{
|
|
unsigned long loadaddr;
|
|
const char *type;
|
|
bool force_recovery = false;
|
|
int ret;
|
|
|
|
if (argc < 3)
|
|
return 1;
|
|
|
|
type = argv[1];
|
|
loadaddr = simple_strtoul(argv[2], NULL, 16);
|
|
|
|
/* check recovery mode */
|
|
if (!strcmp(type, "recovery")) {
|
|
force_recovery = true;
|
|
} else if (strcmp(type, "kernel")) {
|
|
fprintf(stderr, "Err zbi_load: unknown image type '%s'", type);
|
|
return 1;
|
|
}
|
|
|
|
ret = zircon_abr_img_load((unsigned char *)loadaddr, force_recovery,
|
|
&img_offset);
|
|
if (ret) {
|
|
fprintf(stderr, "Err zbi_load: failed to load the image\n");
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define MAX_ADDR_LEN_HEX 20
|
|
|
|
static int do_zbi_boot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
|
{
|
|
int ret;
|
|
unsigned int loadaddr;
|
|
|
|
if (argc < 2)
|
|
return 1;
|
|
|
|
loadaddr = simple_strtoul(argv[1], NULL, 16);
|
|
|
|
char argv0_new[MAX_ADDR_LEN_HEX + 1] = { 0 };
|
|
char *argv_new = (char *)&argv0_new;
|
|
|
|
snprintf(argv0_new, sizeof(argv0_new), "%lx", loadaddr + img_offset);
|
|
|
|
ret = do_bootm_states(cmdtp, flag, 1, &argv_new,
|
|
BOOTM_STATE_START | BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER |
|
|
BOOTM_STATE_LOADOS | BOOTM_STATE_OS_PREP |
|
|
BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO,
|
|
&images, 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int do_zbi_existence_check(cmd_tbl_t *cmdtp, int flag, int argc,
|
|
char *const argv[])
|
|
{
|
|
int i;
|
|
|
|
/* check if one of the A/B/R slots has valid ZBI image */
|
|
for (i = 0; i < ARRAY_SIZE(zircon_slot_idx_to_pname); i++) {
|
|
const char *partition = zircon_slot_idx_to_pname[i];
|
|
|
|
printf("looking for zbi in partition '%s'\n", partition);
|
|
if (zircon_find_zbi(partition)) {
|
|
printf("found zbi in partition %s\n", partition);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
printf("No ZBI header found\n");
|
|
return 1;
|
|
}
|
|
|
|
U_BOOT_CMD(zbi_load, 3, 0, do_zbi_load,
|
|
"Read the image from internal flash with actual size",
|
|
"argv: <imageType> <loadaddr>\n"
|
|
"\t<imageType>: current support is kernel or recovery\n"
|
|
"\t<loadaddr>: memory address in hex to store the image\n");
|
|
|
|
U_BOOT_CMD(zbi_boot, 2, 0, do_zbi_boot, "Boot the ZBI at the specified address",
|
|
"argv: <addr>\n"
|
|
"\t<addr>: memory address in hex of the image to boot\n");
|
|
|
|
U_BOOT_CMD(zbi_existence_check, 1, 0, do_zbi_existence_check,
|
|
"Check if there exists a ZBI in the A, B, or R slot.", "");
|