diff options
author | Tom Rini | 2019-08-26 09:50:46 -0400 |
---|---|---|
committer | Tom Rini | 2019-08-26 09:50:46 -0400 |
commit | 7a4b0bc5fe70225ae3595ba81d1473c06fd6b83b (patch) | |
tree | 08de46c2eb44560654871f78380d4363efdce5ec /arch | |
parent | 6f9656d726235b4cbb4f469a82c30e5006a75b53 (diff) | |
parent | 44016bc59870c8816fe2cd4721dc5ff11038dd98 (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/Kconfig | 6 | ||||
-rw-r--r-- | arch/riscv/Kconfig | 36 | ||||
-rw-r--r-- | arch/riscv/cpu/ax25/Kconfig | 6 | ||||
-rw-r--r-- | arch/riscv/cpu/cpu.c | 6 | ||||
-rw-r--r-- | arch/riscv/cpu/generic/Kconfig | 5 | ||||
-rw-r--r-- | arch/riscv/cpu/start.S | 62 | ||||
-rw-r--r-- | arch/riscv/cpu/u-boot-spl.lds | 82 | ||||
-rw-r--r-- | arch/riscv/include/asm/encoding.h | 2 | ||||
-rw-r--r-- | arch/riscv/include/asm/spl.h | 31 | ||||
-rw-r--r-- | arch/riscv/lib/Makefile | 8 | ||||
-rwxr-xr-x | arch/riscv/lib/mkimage_fit_opensbi.sh | 100 | ||||
-rw-r--r-- | arch/riscv/lib/spl.c | 48 |
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); +} |