aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv/lib
diff options
context:
space:
mode:
authorLukas Auer2019-08-21 21:14:45 +0200
committerAndes2019-08-26 16:07:42 +0800
commit8c59f2023cc8d4ab32b3988193ff2eb116df5995 (patch)
treef00b5a0faf61438352a4a8caab2d62a8f9539f2c /arch/riscv/lib
parent5e30e45c83264841018dc8135034426fd0c0f857 (diff)
riscv: add SPL support
U-Boot SPL on the generic RISC-V CPU supports two boot flows, directly jumping to the image and via OpenSBI firmware. In the first case, both U-Boot SPL and proper must be compiled to run in the same privilege mode. Using OpenSBI firmware, U-Boot SPL must be compiled for machine mode and U-Boot proper for supervisor mode. To be able to use SPL, boards have to provide a supported SPL boot device. 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>
Diffstat (limited to 'arch/riscv/lib')
-rw-r--r--arch/riscv/lib/Makefile1
-rw-r--r--arch/riscv/lib/spl.c48
2 files changed, 49 insertions, 0 deletions
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index e4bc5df297f..c9179a5ff86 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -22,6 +22,7 @@ obj-y += interrupts.o
obj-y += reset.o
obj-y += setjmp.o
obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
# For building EFI apps
CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI)
diff --git a/arch/riscv/lib/spl.c b/arch/riscv/lib/spl.c
new file mode 100644
index 00000000000..bea86959872
--- /dev/null
+++ b/arch/riscv/lib/spl.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Fraunhofer AISEC,
+ * Lukas Auer <lukas.auer@aisec.fraunhofer.de>
+ */
+#include <common.h>
+#include <spl.h>
+#include <asm/smp.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+__weak void board_init_f(ulong dummy)
+{
+ int ret;
+
+ ret = spl_early_init();
+ if (ret)
+ panic("spl_early_init() failed: %d\n", ret);
+
+ arch_cpu_init_dm();
+
+ preloader_console_init();
+}
+
+void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+{
+ typedef void __noreturn (*image_entry_riscv_t)(ulong hart, void *dtb);
+ void *fdt_blob;
+ int ret;
+
+#if CONFIG_IS_ENABLED(LOAD_FIT) || CONFIG_IS_ENABLED(LOAD_FIT_FULL)
+ fdt_blob = spl_image->fdt_addr;
+#else
+ fdt_blob = (void *)gd->fdt_blob;
+#endif
+
+ image_entry_riscv_t image_entry =
+ (image_entry_riscv_t)spl_image->entry_point;
+ invalidate_icache_all();
+
+ debug("image entry point: 0x%lX\n", spl_image->entry_point);
+#ifdef CONFIG_SMP
+ ret = smp_call_function(spl_image->entry_point, (ulong)fdt_blob, 0);
+ if (ret)
+ hang();
+#endif
+ image_entry(gd->arch.boot_hart, fdt_blob);
+}