Philipp Hug has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/31215
Change subject: WIP: riscv: Implement FIT for RISC-V ......................................................................
WIP: riscv: Implement FIT for RISC-V
Change-Id: Ic50f14a4f483d904db590ecd53bb1fc5bdeb06d6 --- M payloads/Kconfig M src/arch/riscv/Makefile.inc A src/arch/riscv/fit_payload.c M src/soc/sifive/fu540/Kconfig 4 files changed, 171 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/15/31215/1
diff --git a/payloads/Kconfig b/payloads/Kconfig index c7a7ba6..0c5ce8f 100644 --- a/payloads/Kconfig +++ b/payloads/Kconfig @@ -30,7 +30,7 @@
config PAYLOAD_FIT bool "A FIT payload" - depends on ARCH_ARM64 + depends on ARCH_ARM64 || ARCH_RISCV select PAYLOAD_FIT_SUPPORT help Select this option if you have a payload image (a FIT file) which diff --git a/src/arch/riscv/Makefile.inc b/src/arch/riscv/Makefile.inc index e4c8468..12609d4 100644 --- a/src/arch/riscv/Makefile.inc +++ b/src/arch/riscv/Makefile.inc @@ -139,6 +139,7 @@ ramstage-y += tables.c ramstage-y += payload.S ramstage-$(ARCH_RISCV_PMP) += pmp.c +ramstage-$(CONFIG_PAYLOAD_FIT_SUPPORT) += fit_payload.c ramstage-y += \ $(top)/src/lib/memchr.c \ $(top)/src/lib/memcmp.c \ diff --git a/src/arch/riscv/fit_payload.c b/src/arch/riscv/fit_payload.c new file mode 100644 index 0000000..2176095 --- /dev/null +++ b/src/arch/riscv/fit_payload.c @@ -0,0 +1,166 @@ +/* + * Copyright 2013 Google Inc. + * Copyright 2018 Facebook, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <bootmem.h> +#include <stdlib.h> +#include <program_loading.h> +#include <string.h> +#include <commonlib/compression.h> +#include <commonlib/cbfs_serialized.h> +#include <lib.h> +#include <fit.h> +#include <endian.h> + +#define MAX_KERNEL_SIZE (64*MiB) + +static bool fit_place_kernel(const struct range_entry *r, void *arg) +{ + struct region *region = arg; + resource_t start; + + if (range_entry_tag(r) != BM_MEM_RAM) + return true; + + /** + * The Image must be placed text_offset bytes from a 2MB aligned base + * address anywhere in usable system RAM and called there. The region + * between the 2 MB aligned base address and the start of the image has + * no special significance to the kernel, and may be used for other + * purposes. + * + * If the reserved memory (BL31 for example) is smaller than text_offset + * we can use the 2 MiB base address, otherwise use the next 2 MiB page. + * It's not mandatory, but wastes less memory below the kernel. + */ + start = ALIGN_DOWN(range_entry_base(r), 2 * MiB); + + if (start < range_entry_base(r)) + start += 2 * MiB; + /** + * At least image_size bytes from the start of the image must be free + * for use by the kernel. + */ + if (start + region->size < range_entry_end(r)) { + region->offset = (size_t)start; + return false; + } + + return true; +} + +/** + * Place the region in free memory range. + * + * The caller has to set region->offset to the minimum allowed address. + * The region->offset is usually 0 on kernel >v4.6 and kernel_base + kernel_size + * on kernel <v4.6. + */ +static bool fit_place_mem(const struct range_entry *r, void *arg) +{ + struct region *region = arg; + resource_t start; + + if (range_entry_tag(r) != BM_MEM_RAM) + return true; + + /* Linux 4.15 doesn't like 4KiB alignment. Align to 1 MiB for now. */ + start = ALIGN_UP(MAX(region->offset, range_entry_base(r)), 1 * MiB); + + if (start + region->size < range_entry_end(r)) { + region->offset = (size_t)start; + return false; + } + + return true; +} + +bool fit_payload_arch(struct prog *payload, struct fit_config_node *config, + struct region *kernel, + struct region *fdt, + struct region *initrd) +{ + bool place_anywhere; + void *arg = NULL; + + if (!config->fdt || !fdt) { + printk(BIOS_CRIT, "CRIT: Providing a valid FDT is mandatory to " + "boot an RISCV kernel!\n"); + return false; + } + + /* Update kernel size from image header, if possible */ + kernel->size = 0x2000000; //get_kernel_size(config->kernel_node); + printk(BIOS_DEBUG, "FIT: Using kernel size of 0x%zx bytes\n", + kernel->size); + + + /** + * The code assumes that bootmem_walk provides a sorted list of memory + * regions, starting from the lowest address. + * The order of the calls here doesn't matter, as the placement is + * enforced in the called functions. + * For details check code on top. + */ + + if (!bootmem_walk(fit_place_kernel, kernel)) + return false; + + /* Mark as reserved for future allocations. */ + bootmem_add_range(kernel->offset, kernel->size, BM_MEM_PAYLOAD); + + /** + * NOTE: versions prior to v4.6 cannot make use of memory below the + * physical offset of the Image so it is recommended that the Image be + * placed as close as possible to the start of system RAM. + * + * For kernel <v4.6 the INITRD and FDT can't be placed below the kernel. + * In that case set region offset to an address on top of kernel. + */ + + place_anywhere = false; + printk(BIOS_DEBUG, "FIT: Placing FDT and INITRD %s\n", + place_anywhere ? "anywhere" : "on top of kernel"); + + /* Place INITRD */ + if (config->ramdisk) { + initrd->offset = 0; + + if (!bootmem_walk(fit_place_mem, initrd)) + return false; + /* Mark as reserved for future allocations. */ + bootmem_add_range(initrd->offset, initrd->size, BM_MEM_PAYLOAD); + } + + /* Place FDT */ + if (place_anywhere) + fdt->offset = 0; + else + fdt->offset = kernel->offset + kernel->size; + + if (!bootmem_walk(fit_place_mem, fdt)) + return false; + /* Mark as reserved for future allocations. */ + bootmem_add_range(fdt->offset, fdt->size, BM_MEM_PAYLOAD); + + /* Kernel expects FDT as argument */ + arg = (void *)fdt->offset; + + prog_set_entry(payload, (void *)kernel->offset, arg); + + bootmem_dump_ranges(); + + return true; +} diff --git a/src/soc/sifive/fu540/Kconfig b/src/soc/sifive/fu540/Kconfig index 6ebde33..20645da 100644 --- a/src/soc/sifive/fu540/Kconfig +++ b/src/soc/sifive/fu540/Kconfig @@ -49,4 +49,7 @@ int default 0
+config HEAP_SIZE + default 0x10000 + endif
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/31215 )
Change subject: WIP: riscv: Implement FIT for RISC-V ......................................................................
Patch Set 1:
(5 comments)
https://review.coreboot.org/#/c/31215/1/src/arch/riscv/fit_payload.c File src/arch/riscv/fit_payload.c:
https://review.coreboot.org/#/c/31215/1/src/arch/riscv/fit_payload.c@104 PS1, Line 104: /* Update kernel size from image header, if possible */ code indent should use tabs where possible
https://review.coreboot.org/#/c/31215/1/src/arch/riscv/fit_payload.c@106 PS1, Line 106: printk(BIOS_DEBUG, "FIT: Using kernel size of 0x%zx bytes\n", code indent should use tabs where possible
https://review.coreboot.org/#/c/31215/1/src/arch/riscv/fit_payload.c@106 PS1, Line 106: printk(BIOS_DEBUG, "FIT: Using kernel size of 0x%zx bytes\n", please, no spaces at the start of a line
https://review.coreboot.org/#/c/31215/1/src/arch/riscv/fit_payload.c@107 PS1, Line 107: kernel->size); code indent should use tabs where possible
https://review.coreboot.org/#/c/31215/1/src/arch/riscv/fit_payload.c@107 PS1, Line 107: kernel->size); please, no spaces at the start of a line
Xiang Wang has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/31215 )
Change subject: WIP: riscv: Implement FIT for RISC-V ......................................................................
Patch Set 1:
If want to support fit, should we add SBI first?
Philipp Hug has abandoned this change. ( https://review.coreboot.org/c/coreboot/+/31215 )
Change subject: WIP: riscv: Implement FIT for RISC-V ......................................................................
Abandoned
superseeded by #30292