aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Auer <lukas.auer@aisec.fraunhofer.de>2019-08-21 21:14:45 +0200
committerAndes <uboot@andestech.com>2019-08-26 16:07:42 +0800
commit8c59f2023cc8d4ab32b3988193ff2eb116df5995 (patch)
treef00b5a0faf61438352a4a8caab2d62a8f9539f2c
parent5e30e45c83264841018dc8135034426fd0c0f857 (diff)
downloadu-boot-8c59f2023cc8d4ab32b3988193ff2eb116df5995.zip
u-boot-8c59f2023cc8d4ab32b3988193ff2eb116df5995.tar.gz
u-boot-8c59f2023cc8d4ab32b3988193ff2eb116df5995.tar.bz2
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>
-rw-r--r--arch/Kconfig6
-rw-r--r--arch/riscv/Kconfig3
-rw-r--r--arch/riscv/cpu/generic/Kconfig3
-rw-r--r--arch/riscv/cpu/start.S23
-rw-r--r--arch/riscv/cpu/u-boot-spl.lds82
-rw-r--r--arch/riscv/include/asm/spl.h31
-rw-r--r--arch/riscv/lib/Makefile1
-rw-r--r--arch/riscv/lib/spl.c48
8 files changed, 196 insertions, 1 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index e510e97..f4ada57 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -76,6 +76,12 @@ config RISCV
imply MTD
imply TIMER
imply CMD_DM
+ imply SPL_DM
+ imply SPL_OF_CONTROL
+ imply SPL_LIBCOMMON_SUPPORT
+ imply SPL_LIBGENERIC_SUPPORT
+ imply SPL_SERIAL_SUPPORT
+ imply SPL_TIMER
config SANDBOX
bool "Sandbox"
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index b8d01ba..01975d7 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -226,4 +226,7 @@ config STACK_SIZE_SHIFT
int
default 13
+config SPL_LDSCRIPT
+ default "arch/riscv/cpu/u-boot-spl.lds"
+
endmenu
diff --git a/arch/riscv/cpu/generic/Kconfig b/arch/riscv/cpu/generic/Kconfig
index b7552f5..b2cb155 100644
--- a/arch/riscv/cpu/generic/Kconfig
+++ b/arch/riscv/cpu/generic/Kconfig
@@ -10,3 +10,6 @@ config GENERIC_RISCV
imply RISCV_TIMER
imply SIFIVE_CLINT if (RISCV_MMODE || SPL_RISCV_MMODE)
imply CMD_CPU
+ imply SPL_CPU_SUPPORT
+ imply SPL_OPENSBI
+ imply SPL_LOAD_FIT
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index e82ee9e..66c6039 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -75,7 +75,11 @@ _start:
*/
call_board_init_f:
li t0, -16
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
+ li t1, CONFIG_SPL_STACK
+#else
li t1, CONFIG_SYS_INIT_SP_ADDR
+#endif
and sp, t1, t0 /* force 16 byte alignment */
call_board_init_f_0:
@@ -159,7 +163,24 @@ wait_for_gd_init:
mv a0, zero /* a0 <-- boot_flags = 0 */
la t5, board_init_f
- jr t5 /* jump to board_init_f() */
+ jalr t5 /* jump to board_init_f() */
+
+#ifdef CONFIG_SPL_BUILD
+spl_clear_bss:
+ la t0, __bss_start
+ la t1, __bss_end
+ beq t0, t1, spl_call_board_init_r
+
+spl_clear_bss_loop:
+ SREG zero, 0(t0)
+ addi t0, t0, REGBYTES
+ bne t0, t1, spl_clear_bss_loop
+
+spl_call_board_init_r:
+ mv a0, zero
+ mv a1, zero
+ jal board_init_r
+#endif
/*
* void relocate_code (addr_sp, gd, addr_moni)
diff --git a/arch/riscv/cpu/u-boot-spl.lds b/arch/riscv/cpu/u-boot-spl.lds
new file mode 100644
index 0000000..32255d5
--- /dev/null
+++ b/arch/riscv/cpu/u-boot-spl.lds
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Based on arch/riscv/cpu/u-boot.lds, which is
+ * Copyright (C) 2017 Andes Technology Corporation
+ * Rick Chen, Andes Technology Corporation <rick@andestech.com>
+ *
+ * and arch/mips/cpu/u-boot-spl.lds.
+ */
+MEMORY { .spl_mem : ORIGIN = IMAGE_TEXT_BASE, LENGTH = IMAGE_MAX_SIZE }
+MEMORY { .bss_mem : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
+ LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_ARCH("riscv")
+ENTRY(_start)
+
+SECTIONS
+{
+ . = ALIGN(4);
+ .text : {
+ arch/riscv/cpu/start.o (.text)
+ *(.text*)
+ } > .spl_mem
+
+ . = ALIGN(4);
+ .rodata : {
+ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+ } > .spl_mem
+
+ . = ALIGN(4);
+ .data : {
+ *(.data*)
+ } > .spl_mem
+ . = ALIGN(4);
+
+ .got : {
+ __got_start = .;
+ *(.got.plt) *(.got)
+ __got_end = .;
+ } > .spl_mem
+
+ . = ALIGN(4);
+
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*)));
+ } > .spl_mem
+
+ . = ALIGN(4);
+
+ .binman_sym_table : {
+ __binman_sym_start = .;
+ KEEP(*(SORT(.binman_sym*)));
+ __binman_sym_end = .;
+ } > .spl_mem
+
+ . = ALIGN(4);
+
+ /DISCARD/ : { *(.rela.plt*) }
+ .rela.dyn : {
+ __rel_dyn_start = .;
+ *(.rela*)
+ __rel_dyn_end = .;
+ } > .spl_mem
+
+ . = ALIGN(4);
+
+ .dynsym : {
+ __dyn_sym_start = .;
+ *(.dynsym)
+ __dyn_sym_end = .;
+ } > .spl_mem
+
+ . = ALIGN(4);
+
+ _end = .;
+
+ .bss : {
+ __bss_start = .;
+ *(.bss*)
+ . = ALIGN(4);
+ __bss_end = .;
+ } > .bss_mem
+}
diff --git a/arch/riscv/include/asm/spl.h b/arch/riscv/include/asm/spl.h
new file mode 100644
index 0000000..45c03fb
--- /dev/null
+++ b/arch/riscv/include/asm/spl.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Based on arch/mips/include/asm/spl.h.
+ *
+ * (C) Copyright 2012
+ * Texas Instruments, <www.ti.com>
+ */
+#ifndef _ASM_RISCV_SPL_H_
+#define _ASM_RISCV_SPL_H_
+
+enum {
+ BOOT_DEVICE_RAM,
+ BOOT_DEVICE_MMC1,
+ BOOT_DEVICE_MMC2,
+ BOOT_DEVICE_MMC2_2,
+ BOOT_DEVICE_NAND,
+ BOOT_DEVICE_ONENAND,
+ BOOT_DEVICE_NOR,
+ BOOT_DEVICE_UART,
+ BOOT_DEVICE_SPI,
+ BOOT_DEVICE_USB,
+ BOOT_DEVICE_SATA,
+ BOOT_DEVICE_I2C,
+ BOOT_DEVICE_BOARD,
+ BOOT_DEVICE_DFU,
+ BOOT_DEVICE_XIP,
+ BOOT_DEVICE_BOOTROM,
+ BOOT_DEVICE_NONE
+};
+
+#endif
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index e4bc5df..c9179a5 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 0000000..bea8695
--- /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);
+}