aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorTom Rini2019-08-26 09:50:46 -0400
committerTom Rini2019-08-26 09:50:46 -0400
commit7a4b0bc5fe70225ae3595ba81d1473c06fd6b83b (patch)
tree08de46c2eb44560654871f78380d4363efdce5ec /arch
parent6f9656d726235b4cbb4f469a82c30e5006a75b53 (diff)
parent44016bc59870c8816fe2cd4721dc5ff11038dd98 (diff)
Merge https://gitlab.denx.de/u-boot/custodians/u-boot-riscv
- Support SPL and OpenSBI (FW_DYNAMIC firmware) boot. - Fix qemu kconfig build warning.
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig6
-rw-r--r--arch/riscv/Kconfig36
-rw-r--r--arch/riscv/cpu/ax25/Kconfig6
-rw-r--r--arch/riscv/cpu/cpu.c6
-rw-r--r--arch/riscv/cpu/generic/Kconfig5
-rw-r--r--arch/riscv/cpu/start.S62
-rw-r--r--arch/riscv/cpu/u-boot-spl.lds82
-rw-r--r--arch/riscv/include/asm/encoding.h2
-rw-r--r--arch/riscv/include/asm/spl.h31
-rw-r--r--arch/riscv/lib/Makefile8
-rwxr-xr-xarch/riscv/lib/mkimage_fit_opensbi.sh100
-rw-r--r--arch/riscv/lib/spl.c48
12 files changed, 373 insertions, 19 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index e510e971b47..f4ada57909a 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 8cfc7d0faaa..01975d7c60c 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -113,6 +113,23 @@ config RISCV_SMODE
endchoice
+choice
+ prompt "SPL Run Mode"
+ default SPL_RISCV_MMODE
+ depends on SPL
+
+config SPL_RISCV_MMODE
+ bool "Machine"
+ help
+ Choose this option to build U-Boot SPL for RISC-V M-Mode.
+
+config SPL_RISCV_SMODE
+ bool "Supervisor"
+ help
+ Choose this option to build U-Boot SPL for RISC-V S-Mode.
+
+endchoice
+
config RISCV_ISA_C
bool "Emit compressed instructions"
default y
@@ -132,34 +149,40 @@ config 64BIT
config SIFIVE_CLINT
bool
- depends on RISCV_MMODE
+ depends on RISCV_MMODE || SPL_RISCV_MMODE
select REGMAP
select SYSCON
+ select SPL_REGMAP if SPL
+ select SPL_SYSCON if SPL
help
The SiFive CLINT block holds memory-mapped control and status registers
associated with software and timer interrupts.
config ANDES_PLIC
bool
- depends on RISCV_MMODE
+ depends on RISCV_MMODE || SPL_RISCV_MMODE
select REGMAP
select SYSCON
+ select SPL_REGMAP if SPL
+ select SPL_SYSCON if SPL
help
The Andes PLIC block holds memory-mapped claim and pending registers
associated with software interrupt.
config ANDES_PLMT
bool
- depends on RISCV_MMODE
+ depends on RISCV_MMODE || SPL_RISCV_MMODE
select REGMAP
select SYSCON
+ select SPL_REGMAP if SPL
+ select SPL_SYSCON if SPL
help
The Andes PLMT block holds memory-mapped mtime register
associated with timer tick.
config RISCV_RDTIME
bool
- default y if RISCV_SMODE
+ default y if RISCV_SMODE || SPL_RISCV_SMODE
help
The provides the riscv_get_time() API that is implemented using the
standard rdtime instruction. This is the case for S-mode U-Boot, and
@@ -189,7 +212,7 @@ config NR_CPUS
config SBI_IPI
bool
- default y if RISCV_SMODE
+ default y if RISCV_SMODE || SPL_RISCV_SMODE
depends on SMP
config XIP
@@ -203,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/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig
index 6b4b92e6921..f4b59cb71d6 100644
--- a/arch/riscv/cpu/ax25/Kconfig
+++ b/arch/riscv/cpu/ax25/Kconfig
@@ -4,8 +4,8 @@ config RISCV_NDS
imply CPU
imply CPU_RISCV
imply RISCV_TIMER
- imply ANDES_PLIC if RISCV_MMODE
- imply ANDES_PLMT if RISCV_MMODE
+ imply ANDES_PLIC if (RISCV_MMODE || SPL_RISCV_MMODE)
+ imply ANDES_PLMT if (RISCV_MMODE || SPL_RISCV_MMODE)
help
Run U-Boot on AndeStar V5 platforms and use some specific features
which are provided by Andes Technology AndeStar V5 families.
@@ -14,7 +14,7 @@ if RISCV_NDS
config RISCV_NDS_CACHE
bool "AndeStar V5 families specific cache support"
- depends on RISCV_MMODE
+ depends on RISCV_MMODE || SPL_RISCV_MMODE
help
Provide Andes Technology AndeStar V5 families specific cache support.
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index 5ca185745ee..e457f6acbf1 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/arch/riscv/cpu/cpu.c
@@ -46,13 +46,13 @@ static inline bool supports_extension(char ext)
return false;
#else /* !CONFIG_CPU */
-#ifdef CONFIG_RISCV_MMODE
+#if CONFIG_IS_ENABLED(RISCV_MMODE)
return csr_read(CSR_MISA) & (1 << (ext - 'a'));
-#else /* !CONFIG_RISCV_MMODE */
+#else /* !CONFIG_IS_ENABLED(RISCV_MMODE) */
#warning "There is no way to determine the available extensions in S-mode."
#warning "Please convert your board to use the RISC-V CPU driver."
return false;
-#endif /* CONFIG_RISCV_MMODE */
+#endif /* CONFIG_IS_ENABLED(RISCV_MMODE) */
#endif /* CONFIG_CPU */
}
diff --git a/arch/riscv/cpu/generic/Kconfig b/arch/riscv/cpu/generic/Kconfig
index 1d6ab5032da..b2cb155d6da 100644
--- a/arch/riscv/cpu/generic/Kconfig
+++ b/arch/riscv/cpu/generic/Kconfig
@@ -8,5 +8,8 @@ config GENERIC_RISCV
imply CPU
imply CPU_RISCV
imply RISCV_TIMER
- imply SIFIVE_CLINT if RISCV_MMODE
+ 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 e06db404f5a..b15209d6231 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -39,7 +39,7 @@ secondary_harts_relocation_error:
.section .text
.globl _start
_start:
-#ifdef CONFIG_RISCV_MMODE
+#if CONFIG_IS_ENABLED(RISCV_MMODE)
csrr a0, CSR_MHARTID
#endif
@@ -62,7 +62,7 @@ _start:
#ifdef CONFIG_SMP
/* set xSIE bit to receive IPIs */
-#ifdef CONFIG_RISCV_MMODE
+#if CONFIG_IS_ENABLED(RISCV_MMODE)
li t0, MIE_MSIE
#else
li t0, SIE_SSIE
@@ -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,57 @@ 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_stack_gd_setup
+
+spl_clear_bss_loop:
+ SREG zero, 0(t0)
+ addi t0, t0, REGBYTES
+ bne t0, t1, spl_clear_bss_loop
+
+spl_stack_gd_setup:
+ jal spl_relocate_stack_gd
+
+ /* skip setup if we did not relocate */
+ beqz a0, spl_call_board_init_r
+ mv s0, a0
+
+ /* setup stack on main hart */
+#ifdef CONFIG_SMP
+ /* tp: hart id */
+ slli t0, tp, CONFIG_STACK_SIZE_SHIFT
+ sub sp, s0, t0
+#else
+ mv sp, s0
+#endif
+
+ /* set new stack and global data pointer on secondary harts */
+spl_secondary_hart_stack_gd_setup:
+ la a0, secondary_hart_relocate
+ mv a1, s0
+ mv a2, s0
+ jal smp_call_function
+
+ /* hang if relocation of secondary harts has failed */
+ beqz a0, 1f
+ mv a1, a0
+ la a0, secondary_harts_relocation_error
+ jal printf
+ jal hang
+
+ /* set new global data pointer on main hart */
+1: mv gp, s0
+
+spl_call_board_init_r:
+ mv a0, zero
+ mv a1, zero
+ jal board_init_r
+#endif
/*
* void relocate_code (addr_sp, gd, addr_moni)
@@ -344,7 +398,7 @@ secondary_hart_loop:
#ifdef CONFIG_SMP
csrr t0, MODE_PREFIX(ip)
-#ifdef CONFIG_RISCV_MMODE
+#if CONFIG_IS_ENABLED(RISCV_MMODE)
andi t0, t0, MIE_MSIE
#else
andi t0, t0, SIE_SSIE
diff --git a/arch/riscv/cpu/u-boot-spl.lds b/arch/riscv/cpu/u-boot-spl.lds
new file mode 100644
index 00000000000..32255d58deb
--- /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/encoding.h b/arch/riscv/include/asm/encoding.h
index c450eb9103b..a0695da9364 100644
--- a/arch/riscv/include/asm/encoding.h
+++ b/arch/riscv/include/asm/encoding.h
@@ -9,7 +9,7 @@
#include <asm/csr.h>
-#ifdef CONFIG_RISCV_SMODE
+#if CONFIG_IS_ENABLED(RISCV_SMODE)
#define MODE_PREFIX(__suffix) s##__suffix
#else
#define MODE_PREFIX(__suffix) m##__suffix
diff --git a/arch/riscv/include/asm/spl.h b/arch/riscv/include/asm/spl.h
new file mode 100644
index 00000000000..45c03fb9b62
--- /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 6ae6ebbeafd..c9179a5ff86 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -10,15 +10,19 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o
obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o
obj-$(CONFIG_CMD_GO) += boot.o
obj-y += cache.o
-obj-$(CONFIG_RISCV_RDTIME) += rdtime.o
+ifeq ($(CONFIG_$(SPL_)RISCV_MMODE),y)
obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o
obj-$(CONFIG_ANDES_PLIC) += andes_plic.o
obj-$(CONFIG_ANDES_PLMT) += andes_plmt.o
+else
+obj-$(CONFIG_RISCV_RDTIME) += rdtime.o
+obj-$(CONFIG_SBI_IPI) += sbi_ipi.o
+endif
obj-y += interrupts.o
obj-y += reset.o
-obj-$(CONFIG_SBI_IPI) += sbi_ipi.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/mkimage_fit_opensbi.sh b/arch/riscv/lib/mkimage_fit_opensbi.sh
new file mode 100755
index 00000000000..d6f95e5bfd2
--- /dev/null
+++ b/arch/riscv/lib/mkimage_fit_opensbi.sh
@@ -0,0 +1,100 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0+
+#
+# script to generate FIT image source for RISC-V boards with OpenSBI
+# and, optionally, multiple device trees (given on the command line).
+#
+# usage: $0 [<dt_name> [<dt_name] ...]
+
+[ -z "$OPENSBI" ] && OPENSBI="fw_dynamic.bin"
+
+if [ -z "$UBOOT_LOAD_ADDR" ]; then
+ UBOOT_LOAD_ADDR="$(grep "^CONFIG_SYS_TEXT_BASE=" .config | awk 'BEGIN{FS="="} {print $2}')"
+fi
+
+if [ -z "$OPENSBI_LOAD_ADDR" ]; then
+ OPENSBI_LOAD_ADDR="$(grep "^CONFIG_SPL_OPENSBI_LOAD_ADDR=" .config | awk 'BEGIN{FS="="} {print $2}')"
+fi
+
+if [ ! -f $OPENSBI ]; then
+ echo "WARNING: OpenSBI binary \"$OPENSBI\" not found, resulting binary is not functional." >&2
+ OPENSBI=/dev/null
+fi
+
+cat << __HEADER_EOF
+/dts-v1/;
+
+/ {
+ description = "Configuration to load OpenSBI before U-Boot";
+
+ images {
+ uboot {
+ description = "U-Boot";
+ data = /incbin/("u-boot-nodtb.bin");
+ type = "standalone";
+ os = "U-Boot";
+ arch = "riscv";
+ compression = "none";
+ load = <$UBOOT_LOAD_ADDR>;
+ };
+ opensbi {
+ description = "RISC-V OpenSBI";
+ data = /incbin/("$OPENSBI");
+ type = "firmware";
+ os = "opensbi";
+ arch = "riscv";
+ compression = "none";
+ load = <$OPENSBI_LOAD_ADDR>;
+ entry = <$OPENSBI_LOAD_ADDR>;
+ };
+__HEADER_EOF
+
+cnt=1
+for dtname in $*
+do
+ cat << __FDT_IMAGE_EOF
+ fdt_$cnt {
+ description = "$(basename $dtname .dtb)";
+ data = /incbin/("$dtname");
+ type = "flat_dt";
+ compression = "none";
+ };
+__FDT_IMAGE_EOF
+cnt=$((cnt+1))
+done
+
+cat << __CONF_HEADER_EOF
+ };
+ configurations {
+ default = "config_1";
+
+__CONF_HEADER_EOF
+
+if [ $# -eq 0 ]; then
+cat << __CONF_SECTION_EOF
+ config_1 {
+ description = "U-Boot FIT";
+ firmware = "opensbi";
+ loadables = "uboot";
+ };
+__CONF_SECTION_EOF
+else
+cnt=1
+for dtname in $*
+do
+cat << __CONF_SECTION_EOF
+ config_$cnt {
+ description = "$(basename $dtname .dtb)";
+ firmware = "opensbi";
+ loadables = "uboot";
+ fdt = "fdt_$cnt";
+ };
+__CONF_SECTION_EOF
+cnt=$((cnt+1))
+done
+fi
+
+cat << __ITS_EOF
+ };
+};
+__ITS_EOF
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);
+}