Skip to content

Commit

Permalink
riscv: add SPL support
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Bin Meng <[email protected]>
Tested-by: Bin Meng <[email protected]>
Reviewed-by: Anup Patel <[email protected]>
  • Loading branch information
lukasauer authored and Andes committed Aug 26, 2019
1 parent 5e30e45 commit 8c59f20
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 1 deletion.
6 changes: 6 additions & 0 deletions arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
3 changes: 3 additions & 0 deletions arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,7 @@ config STACK_SIZE_SHIFT
int
default 13

config SPL_LDSCRIPT
default "arch/riscv/cpu/u-boot-spl.lds"

endmenu
3 changes: 3 additions & 0 deletions arch/riscv/cpu/generic/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
23 changes: 22 additions & 1 deletion arch/riscv/cpu/start.S
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand Down
82 changes: 82 additions & 0 deletions arch/riscv/cpu/u-boot-spl.lds
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
*
* 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
}
31 changes: 31 additions & 0 deletions arch/riscv/include/asm/spl.h
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions arch/riscv/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
48 changes: 48 additions & 0 deletions arch/riscv/lib/spl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019 Fraunhofer AISEC,
* Lukas Auer <[email protected]>
*/
#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);
}

0 comments on commit 8c59f20

Please sign in to comment.