
Hi Anup,
On Mon, 2019-07-29 at 14:02 +0530, Anup Patel wrote:
On Sun, Jul 28, 2019 at 9:55 PM Lukas Auer lukas.auer@aisec.fraunhofer.de wrote:
RISC-V OpenSBI is an open-source implementation of the RISC-V Supervisor Binary Interface (SBI) specification. It is required by Linux and U-Boot running in supervisor mode. This patch adds support for booting via the OpenSBI FW_DYNAMIC firmware.
In this configuration, U-Boot SPL starts in machine mode. After loading OpenSBI and U-Boot proper, it will start OpenSBI. All necessary parameters are generated by U-Boot SPL and passed to OpenSBI. U-Boot proper is started in supervisor mode by OpenSBI. Support for OpenSBI is enabled with CONFIG_SPL_OPENSBI. An additional configuration entry, CONFIG_SPL_OPENSBI_LOAD_ADDR, is used to specify the load address of the OpenSBI firmware binary. It is not used directly in U-Boot and instead is intended to make the value available to scripts such as FIT configuration generators.
The header file include/opensbi.h is based on header files from the OpenSBI project. They are recent, as of commit bae54f764570 ("firmware: Add fw_dynamic firmware").
Instead of OpenSBI commit, may be mention that we need OpenSBI v0.4 or higher.
If there are no other comments on the series I would prefer to keep the commit message as is, if that is ok for you. Adding the minimum OpenSBI version is a good idea, however. I can send a follow-up patch to this series to add the minimum version to the QEMU board documentation.
Signed-off-by: Lukas Auer lukas.auer@aisec.fraunhofer.de Reviewed-by: Bin Meng bmeng.cn@gmail.com Tested-by: Bin Meng bmeng.cn@gmail.com
Changes in v2: None
common/image.c | 1 + common/spl/Kconfig | 17 ++++++++ common/spl/Makefile | 1 + common/spl/spl.c | 6 +++ common/spl/spl_opensbi.c | 85 ++++++++++++++++++++++++++++++++++++++++ include/image.h | 1 + include/opensbi.h | 40 +++++++++++++++++++ include/spl.h | 5 +++ 8 files changed, 156 insertions(+) create mode 100644 common/spl/spl_opensbi.c create mode 100644 include/opensbi.h
diff --git a/common/image.c b/common/image.c index 9f9538fac2..7c7353a989 100644 --- a/common/image.c +++ b/common/image.c @@ -125,6 +125,7 @@ static const table_entry_t uimage_os[] = { #if defined(CONFIG_BOOTM_OPENRTOS) || defined(USE_HOSTCC) { IH_OS_OPENRTOS, "openrtos", "OpenRTOS", }, #endif
{ IH_OS_OPENSBI, "opensbi", "RISC-V OpenSBI", }, { -1, "", "", },
}; diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 5d6da5db89..939c8517cd 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -1126,6 +1126,23 @@ config SPL_OPTEE OP-TEE is an open source Trusted OS which is loaded by SPL. More detail at: https://github.com/OP-TEE/optee_os
+config SPL_OPENSBI
bool "Support RISC-V OpenSBI"
depends on RISCV && SPL_RISCV_MMODE && RISCV_SMODE
help
OpenSBI is an open-source implementation of the RISC-V Supervisor Binary
Interface (SBI) specification. U-Boot supports the OpenSBI FW_DYNAMIC
firmware. It is loaded and started by U-Boot SPL.
More details are available at https://github.com/riscv/opensbi and
https://github.com/riscv/riscv-sbi-doc
+config SPL_OPENSBI_LOAD_ADDR
hex "OpenSBI load address"
depends on SPL_OPENSBI
help
Load address of the OpenSBI binary.
config TPL bool depends on SUPPORT_TPL diff --git a/common/spl/Makefile b/common/spl/Makefile index d28de692dd..5ce6f4ae48 100644 --- a/common/spl/Makefile +++ b/common/spl/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_$(SPL_TPL_)NET_SUPPORT) += spl_net.o obj-$(CONFIG_$(SPL_TPL_)MMC_SUPPORT) += spl_mmc.o obj-$(CONFIG_$(SPL_TPL_)ATF) += spl_atf.o obj-$(CONFIG_$(SPL_TPL_)OPTEE) += spl_optee.o +obj-$(CONFIG_$(SPL_TPL_)OPENSBI) += spl_opensbi.o obj-$(CONFIG_$(SPL_TPL_)USB_STORAGE) += spl_usb.o obj-$(CONFIG_$(SPL_TPL_)FS_FAT) += spl_fat.o obj-$(CONFIG_$(SPL_TPL_)FS_EXT4) += spl_ext.o diff --git a/common/spl/spl.c b/common/spl/spl.c index d5e3f680f4..1ed4741bdc 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -659,6 +659,12 @@ void board_init_r(gd_t *dummy1, ulong dummy2) (void *)spl_image.entry_point); break; #endif +#if CONFIG_IS_ENABLED(OPENSBI)
Should this be "CONFIG_IS_ENABLED(SPL_OPENSBI)" ?
Am I missing something here ?
The CONFIG_IS_ENABLED(option) macro automatically handles the SPL_* symbols. On SPL builds, it evaluates to one if CONFIG_SPL_option is defined. On normal builds, it evaluates to one if CONFIG_option is defined.
Thanks, Lukas
case IH_OS_OPENSBI:
debug("Jumping to U-Boot via RISC-V OpenSBI\n");
spl_invoke_opensbi(&spl_image);
break;
+#endif #ifdef CONFIG_SPL_OS_BOOT case IH_OS_LINUX: debug("Jumping to Linux\n"); diff --git a/common/spl/spl_opensbi.c b/common/spl/spl_opensbi.c new file mode 100644 index 0000000000..a6b4480ed2 --- /dev/null +++ b/common/spl/spl_opensbi.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2019 Fraunhofer AISEC,
- Lukas Auer lukas.auer@aisec.fraunhofer.de
- Based on common/spl/spl_atf.c
- */
+#include <common.h> +#include <errno.h> +#include <spl.h> +#include <asm/smp.h> +#include <opensbi.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct fw_dynamic_info opensbi_info;
+static int spl_opensbi_find_uboot_node(void *blob, int *uboot_node) +{
int fit_images_node, node;
const char *fit_os;
fit_images_node = fdt_path_offset(blob, "/fit-images");
if (fit_images_node < 0)
return -ENODEV;
fdt_for_each_subnode(node, blob, fit_images_node) {
fit_os = fdt_getprop(blob, node, FIT_OS_PROP, NULL);
if (!fit_os)
continue;
if (genimg_get_os_id(fit_os) == IH_OS_U_BOOT) {
*uboot_node = node;
return 0;
}
}
return -ENODEV;
+}
+void spl_invoke_opensbi(struct spl_image_info *spl_image) +{
int ret, uboot_node;
ulong uboot_entry;
void (*opensbi_entry)(ulong hartid, ulong dtb, ulong info);
if (!spl_image->fdt_addr) {
pr_err("No device tree specified in SPL image\n");
hang();
}
/* Find U-Boot image in /fit-images */
ret = spl_opensbi_find_uboot_node(spl_image->fdt_addr, &uboot_node);
if (ret) {
pr_err("Can't find U-Boot node, %d", ret);
hang();
}
/* Get U-Boot entry point */
uboot_entry = fdt_getprop_u32(spl_image->fdt_addr, uboot_node,
"entry-point");
if (uboot_entry == FDT_ERROR)
uboot_entry = fdt_getprop_u32(spl_image->fdt_addr, uboot_node,
"load-addr");
/* Prepare obensbi_info object */
opensbi_info.magic = FW_DYNAMIC_INFO_MAGIC_VALUE;
opensbi_info.version = FW_DYNAMIC_INFO_VERSION;
opensbi_info.next_addr = uboot_entry;
opensbi_info.next_mode = FW_DYNAMIC_INFO_NEXT_MODE_S;
opensbi_info.options = SBI_SCRATCH_NO_BOOT_PRINTS;
opensbi_entry = (void (*)(ulong, ulong, ulong))spl_image->entry_point;
invalidate_icache_all();
+#ifdef CONFIG_SMP
ret = smp_call_function((ulong)spl_image->entry_point,
(ulong)spl_image->fdt_addr,
(ulong)&opensbi_info);
if (ret)
hang();
+#endif
opensbi_entry(gd->arch.boot_hart, (ulong)spl_image->fdt_addr,
(ulong)&opensbi_info);
+} diff --git a/include/image.h b/include/image.h index 5f82194951..78a2dffe54 100644 --- a/include/image.h +++ b/include/image.h @@ -156,6 +156,7 @@ enum { IH_OS_OPENRTOS, /* OpenRTOS */ IH_OS_ARM_TRUSTED_FIRMWARE, /* ARM Trusted Firmware */ IH_OS_TEE, /* Trusted Execution Environment */
IH_OS_OPENSBI, /* RISC-V OpenSBI */ IH_OS_COUNT,
}; diff --git a/include/opensbi.h b/include/opensbi.h new file mode 100644 index 0000000000..9f1d62e7dd --- /dev/null +++ b/include/opensbi.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/*
- Copyright (c) 2019 Western Digital Corporation or its affiliates.
- Based on include/sbi/{fw_dynamic.h,sbi_scratch.h} from the OpenSBI project.
- */
+#ifndef OPENSBI_H +#define OPENSBI_H
+/** Expected value of info magic ('OSBI' ascii string in hex) */ +#define FW_DYNAMIC_INFO_MAGIC_VALUE 0x4942534f
+/** Maximum supported info version */ +#define FW_DYNAMIC_INFO_VERSION 0x1
+/** Possible next mode values */ +#define FW_DYNAMIC_INFO_NEXT_MODE_U 0x0 +#define FW_DYNAMIC_INFO_NEXT_MODE_S 0x1 +#define FW_DYNAMIC_INFO_NEXT_MODE_M 0x3
+enum sbi_scratch_options {
/** Disable prints during boot */
SBI_SCRATCH_NO_BOOT_PRINTS = (1 << 0),
+};
+/** Representation dynamic info passed by previous booting stage */ +struct fw_dynamic_info {
/** Info magic */
unsigned long magic;
/** Info version */
unsigned long version;
/** Next booting stage address */
unsigned long next_addr;
/** Next booting stage mode */
unsigned long next_mode;
/** Options for OpenSBI library */
unsigned long options;
+} __packed;
+#endif diff --git a/include/spl.h b/include/spl.h index a90f971a23..e4640f3830 100644 --- a/include/spl.h +++ b/include/spl.h @@ -374,6 +374,11 @@ void spl_invoke_atf(struct spl_image_info *spl_image); */ void spl_optee_entry(void *arg0, void *arg1, void *arg2, void *arg3);
+/**
- spl_invoke_opensbi - boot using a RISC-V OpenSBI image
- */
+void spl_invoke_opensbi(struct spl_image_info *spl_image);
/**
- board_return_to_bootrom - allow for boards to continue with the boot ROM
-- 2.21.0
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Apart from minor queries/comments above, looks good to me.
Reviewed-by: Anup Patel anup.patel@wdc.com
Regards, Anup