Message ID | 20190728155723.3412-7-lukas.auer@aisec.fraunhofer.de |
---|---|
State | Superseded |
Delegated to: | Andes |
Headers | show |
Series | SPL support for RISC-V | expand |
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
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); +}