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>
This commit is contained in:
Lukas Auer 2019-08-21 21:14:45 +02:00 committed by Andes
parent 5e30e45c83
commit 8c59f2023c
8 changed files with 196 additions and 1 deletions

View File

@ -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"

View File

@ -226,4 +226,7 @@ config STACK_SIZE_SHIFT
int
default 13
config SPL_LDSCRIPT
default "arch/riscv/cpu/u-boot-spl.lds"
endmenu

View File

@ -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

View File

@ -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)

View File

@ -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
}

View File

@ -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

View File

@ -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)

48
arch/riscv/lib/spl.c Normal file
View File

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