
On Sun, Jul 28, 2019 at 9:31 PM Lukas Auer lukas.auer@aisec.fraunhofer.de wrote:
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
Changes in v2: None
arch/Kconfig | 6 +++ arch/riscv/Kconfig | 3 ++ arch/riscv/cpu/generic/Kconfig | 3 ++ arch/riscv/cpu/start.S | 23 +++++++++- arch/riscv/cpu/u-boot-spl.lds | 82 ++++++++++++++++++++++++++++++++++ arch/riscv/include/asm/spl.h | 31 +++++++++++++ arch/riscv/lib/Makefile | 1 + arch/riscv/lib/spl.c | 48 ++++++++++++++++++++ 8 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 arch/riscv/cpu/u-boot-spl.lds create mode 100644 arch/riscv/include/asm/spl.h create mode 100644 arch/riscv/lib/spl.c
diff --git a/arch/Kconfig b/arch/Kconfig index 949eb28dfa..8350d9b1ea 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 b8d01ba8e1..01975d7c60 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 b7552f539f..b2cb155d6d 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 08b9812c4d..e053197645 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -76,7 +76,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: @@ -160,7 +164,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 0000000000..32255d58de --- /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 0000000000..45c03fb9b6 --- /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 e4bc5df297..c9179a5ff8 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 0000000000..bea8695987 --- /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);
+}
2.21.0
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Reviewed-by: Anup Patel anup.patel@wdc.com
Regards, Anup