mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
spl: support booting via RISC-V OpenSBI
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. It supports OpenSBI version 0.4 and higher. 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 are 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"). 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> Reviewed-by: Anup Patel <anup.patel@wdc.com>
This commit is contained in:
parent
fbfd92bf9b
commit
5e30e45c83
8 changed files with 156 additions and 0 deletions
|
@ -132,6 +132,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, "", "", },
|
||||
};
|
||||
|
|
|
@ -1148,6 +1148,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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
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");
|
||||
|
|
85
common/spl/spl_opensbi.c
Normal file
85
common/spl/spl_opensbi.c
Normal file
|
@ -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);
|
||||
}
|
|
@ -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,
|
||||
};
|
||||
|
|
40
include/opensbi.h
Normal file
40
include/opensbi.h
Normal file
|
@ -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
|
|
@ -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
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue