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
					
				|  | @ -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) | ||||
|  |  | |||
|  | @ -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 | ||||
| } | ||||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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…
	
		Reference in New Issue