mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-03-13 21:36:57 +00:00
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:
parent
5e30e45c83
commit
8c59f2023c
8 changed files with 196 additions and 1 deletions
|
@ -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"
|
||||
|
|
|
@ -226,4 +226,7 @@ config STACK_SIZE_SHIFT
|
|||
int
|
||||
default 13
|
||||
|
||||
config SPL_LDSCRIPT
|
||||
default "arch/riscv/cpu/u-boot-spl.lds"
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
82
arch/riscv/cpu/u-boot-spl.lds
Normal file
82
arch/riscv/cpu/u-boot-spl.lds
Normal 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
|
||||
}
|
31
arch/riscv/include/asm/spl.h
Normal file
31
arch/riscv/include/asm/spl.h
Normal 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
|
|
@ -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
48
arch/riscv/lib/spl.c
Normal 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);
|
||||
}
|
Loading…
Add table
Reference in a new issue