diff options
author | Pierre-Clément Tosi <ptosi@google.com> | 2022-04-06 21:44:40 +0100 |
---|---|---|
committer | Pierre-Clément Tosi <ptosi@google.com> | 2022-05-16 07:51:05 +0100 |
commit | 6649866e3b01109ea23e7c2f524eea7b36d90b94 (patch) | |
tree | 2befabf9f63fa3e7a5e0938c081c6fe5342a17a0 | |
parent | fb382a51073c3a18275b6d37d4f551e88a9609da (diff) | |
download | u-boot-6649866e3b01109ea23e7c2f524eea7b36d90b94.tar.gz |
ANDROID: pvmfw: Support DICE & AVF in DT template
Make the DT template hold the relevant nodes and patch/remove them as
necessary while producing the DT for the next stage, instead of
injecting them once it has been produced.
Bug: 224922775
Signed-off-by: Pierre-Clément Tosi <ptosi@google.com>
Change-Id: I820fce2cf9da772363abfdf8f5dbf12b781a1fbf
-rw-r--r-- | board/android/pvmfw-arm64/boot.c | 155 | ||||
-rw-r--r-- | board/android/pvmfw-arm64/generate_fdt.c | 19 | ||||
-rw-r--r-- | board/android/pvmfw-arm64/generate_fdt.h | 3 | ||||
-rw-r--r-- | board/android/pvmfw-arm64/platform.dts | 9 |
4 files changed, 50 insertions, 136 deletions
diff --git a/board/android/pvmfw-arm64/boot.c b/board/android/pvmfw-arm64/boot.c index f0d52a74a2..7c3cb19326 100644 --- a/board/android/pvmfw-arm64/boot.c +++ b/board/android/pvmfw-arm64/boot.c @@ -4,6 +4,7 @@ */ #include <asm/global_data.h> +#include <asm/io.h> #include <android_bootloader.h> #include <android_image.h> @@ -19,13 +20,6 @@ #include "avb_preloaded.h" #include "generate_fdt.h" -/* This assumes reserved-memory#address-cells/size-cells <= 2 */ -#define DICE_NODE_SIZE 96 -#define RSV_MEM_SIZE (DICE_NODE_SIZE + 128) -#define COMPAT_DICE "google,open-dice" - -#define CHOSEN_MEM_SIZE 64 - /* Taken from libavb/avb_slot_verify.c */ #define VBMETA_MAX_SIZE SZ_64K @@ -46,116 +40,6 @@ static bool is_valid_ram_region(const void *ptr, size_t size) return is_valid_ram(ptr) && (size <= gd->ram_top - (uintptr_t)ptr); } -static int alloc_subnode(void *fdt, int parentoffset, const char *name, - size_t size) -{ - int offset, res; - - offset = fdt_add_subnode(fdt, parentoffset, name); - if (offset != -FDT_ERR_NOSPACE) - return offset; - - res = fdt_increase_size(fdt, size); - if (res) - return res; - - return fdt_add_subnode(fdt, parentoffset, name); -} - -static int find_or_alloc_subnode(void *fdt, int parentoffset, const char *name, - size_t size) -{ - int offset; - - offset = fdt_subnode_offset(fdt, parentoffset, name); - if (offset != -FDT_ERR_NOTFOUND) - return offset; - - return alloc_subnode(fdt, parentoffset, name, size); -} - -static bool pvmfw_fdt_is_valid(const void *fdt) -{ - int offset; - - if (fdt != (const void *)CONFIG_SYS_SDRAM_BASE) - return false; - - if (fdt_totalsize(fdt) > FDT_MAX_SIZE) - return false; - - /* Reject DICE-compatible DT nodes. */ - offset = fdt_node_offset_by_compatible(fdt, -1, COMPAT_DICE); - if (offset != -FDT_ERR_NOTFOUND) - return false; - - /* Reject "/reserved-memory/dice" nodes. */ - offset = fdt_subnode_offset(fdt, -1, "reserved-memory"); - if (offset >= 0) - offset = fdt_subnode_offset(fdt, offset, "dice"); - if (offset != -FDT_ERR_NOTFOUND) - return false; - - return true; -} - -static int add_dice_fdt_mem_rsv(void *fdt, void *addr, size_t size) -{ - int mem, dice, err; - - mem = find_or_alloc_subnode(fdt, 0, "reserved-memory", RSV_MEM_SIZE); - if (mem < 0) - return mem; - - dice = alloc_subnode(fdt, mem, "dice", DICE_NODE_SIZE); - if (dice < 0) - return dice; - - err = fdt_appendprop_addrrange(fdt, mem, dice, "reg", - (uint64_t)addr, size); - if (err) - return err; - - err = fdt_appendprop(fdt, dice, "no-map", NULL, 0); - if (err) - return err; - - err = fdt_appendprop_string(fdt, dice, "compatible", COMPAT_DICE); - if (err) - return err; - - return dice; -} - -static int add_avf_fdt_chosen_properties(void *fdt, bool new_instance) -{ - int chosen, err; - - chosen = find_or_alloc_subnode(fdt, 0, "chosen", CHOSEN_MEM_SIZE); - if (chosen < 0) - return chosen; - - err = fdt_increase_size(fdt, CHOSEN_MEM_SIZE); - if (err) - return err; - - err = fdt_appendprop(fdt, chosen, "avf,strict-boot", NULL, 0); - if (err) - return err; - - if (new_instance) { - err = fdt_appendprop(fdt, chosen, "avf,new-instance", NULL, 0); - if (err) - return err; - } else { - err = fdt_delprop(fdt, chosen, "avf,new-instance"); - if (err && err != -FDT_ERR_NOTFOUND) - return err; - } - - return 0; -} - static struct AvbOps *alloc_avb_ops(void *image, size_t size) { int error; @@ -195,8 +79,7 @@ free_ops: return NULL; } -static int verify_image(void *image, size_t size, void* fdt, - struct boot_config *cfg) +static int verify_image(void *image, size_t size, struct boot_config *cfg) { const char *instance_uuid = "90d2174a-038a-4bc6-adf3-824848fc5825"; const char *iface_str = "virtio"; @@ -219,6 +102,8 @@ static int verify_image(void *image, size_t size, void* fdt, goto err; } + cfg->new_instance = false; + ret = bcc_vm_instance_handover(iface_str, devnum, instance_uuid, /*must_exist=*/false, "vm_entry", BCC_MODE_NORMAL, data, NULL, @@ -226,11 +111,8 @@ static int verify_image(void *image, size_t size, void* fdt, if (ret < 0) goto err; - ret = add_avf_fdt_chosen_properties(fdt, ret == BCC_VM_INSTANCE_CREATED); - if (ret) { - ret = -EIO; - goto err; - } + cfg->new_instance = (ret == BCC_VM_INSTANCE_CREATED); + ret = 0; err: if (data) @@ -245,15 +127,23 @@ int pvmfw_boot_flow(void *fdt, size_t fdt_max_size, void *image, size_t size, void *bcc, size_t bcc_size) { int ret; - struct boot_config cfg; + struct boot_config cfg = { + .bcc_addr = virt_to_phys(bcc), + .bcc_size = bcc_size, + }; if (!size || !is_valid_ram_region(image, size)) { ret = -EPERM; goto err; } - if (!pvmfw_fdt_is_valid(fdt)) { - ret = -EINVAL; + if (fdt != (const void *)CONFIG_SYS_SDRAM_BASE) { + ret = -EFAULT; + goto err; + } + + if (fdt_totalsize(fdt) > fdt_max_size) { + ret = -E2BIG; goto err; } @@ -263,18 +153,11 @@ int pvmfw_boot_flow(void *fdt, size_t fdt_max_size, void *image, size_t size, if (ret) goto err; - /* Transferring template here so that verify_image() can update it */ - ret = transfer_fdt_template(fdt, fdt_max_size); + ret = verify_image(image, size, &cfg); if (ret) goto err; - ret = add_dice_fdt_mem_rsv(fdt, bcc, bcc_size); - if (ret < 0) { - ret = -EIO; - goto err; - } - - ret = verify_image(image, size, fdt, &cfg); + ret = transfer_fdt_template(fdt, fdt_max_size); if (ret) goto err; diff --git a/board/android/pvmfw-arm64/generate_fdt.c b/board/android/pvmfw-arm64/generate_fdt.c index 022f11b77e..9c77fb7866 100644 --- a/board/android/pvmfw-arm64/generate_fdt.c +++ b/board/android/pvmfw-arm64/generate_fdt.c @@ -476,6 +476,21 @@ static int patch_chosen_node(void *fdt, const struct boot_config *cfg) if (TRY_OPTIONAL(fdt_path_offset(fdt, path)) == -FDT_ERR_NOTFOUND) TRY(fdt_nop_property(fdt, node, "stdout-path")); + if (!cfg->new_instance) + TRY(fdt_nop_property(fdt, node, "avf,new-instance")); + + /* '/chosen/avf,strict-boot' is always set (from the base DT) */ + + return 0; +} + +static int patch_resmem_node(void *fdt, const struct boot_config *cfg) +{ + int node = TRY(fdt_path_offset(fdt, "/reserved-memory/dice")); + + TRY(fdt_setpair_inplace_u64(fdt, node, "reg", cfg->bcc_addr, + cfg->bcc_size)); + return 0; } @@ -538,6 +553,10 @@ int patch_output_fdt(void *fdt, const struct boot_config *cfg) if (err) return err; + err = patch_resmem_node(fdt, cfg); + if (err) + return err; + /* Keep patch_chosen_node() last as it relies on other nodes. */ return patch_chosen_node(fdt, cfg); } diff --git a/board/android/pvmfw-arm64/generate_fdt.h b/board/android/pvmfw-arm64/generate_fdt.h index dc7eef6db1..4cf0832edc 100644 --- a/board/android/pvmfw-arm64/generate_fdt.h +++ b/board/android/pvmfw-arm64/generate_fdt.h @@ -37,6 +37,9 @@ struct boot_config { uint64_t serials[4]; uint64_t swiotlb_size; uint64_t swiotlb_align; + uint64_t bcc_addr; + uint64_t bcc_size; + bool new_instance; }; int parse_input_fdt(const void *fdt, struct boot_config *cfg); diff --git a/board/android/pvmfw-arm64/platform.dts b/board/android/pvmfw-arm64/platform.dts index c793022e29..ee48f22ec5 100644 --- a/board/android/pvmfw-arm64/platform.dts +++ b/board/android/pvmfw-arm64/platform.dts @@ -7,6 +7,7 @@ #define PLACEHOLDER 0xffffffff #define PLACEHOLDER2 PLACEHOLDER PLACEHOLDER +#define PLACEHOLDER4 PLACEHOLDER2 PLACEHOLDER2 /dts-v1/; @@ -19,6 +20,8 @@ chosen { stdout-path = "/uart@3f8"; linux,pci-probe-only = <1>; + avf,strict-boot; + avf,new-instance; }; memory { @@ -35,6 +38,12 @@ size = <PLACEHOLDER2>; alignment = <PLACEHOLDER2>; }; + + dice { + compatible = "google,open-dice"; + no-map; + reg = <PLACEHOLDER4>; + }; }; cpus { |