diff mbox series

[U-Boot,v2,06/11] riscv: add SPL support

Message ID 20190728155723.3412-7-lukas.auer@aisec.fraunhofer.de
State Superseded
Delegated to: Andes
Headers show
Series SPL support for RISC-V | expand

Commit Message

Lukas Auer July 28, 2019, 3:57 p.m. UTC
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

Comments

Anup Patel July 29, 2019, 8:34 a.m. UTC | #1
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 mbox series

Patch

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);
+}