- Adds few DT related fixes required for Linux EFI stub to work on
  RISC-V.
- Makes SBI v0.2 the default SBI version to work with OpenSBI v0.7.
- Revert "riscv: qemu: clear kernel-start/-end in device tree as
  workaround for BBL"
- Remove unnecessary CONFIG_IS_ENABLED().
This commit is contained in:
Tom Rini 2020-04-23 08:24:47 -04:00
commit a5f9b8a8b5
17 changed files with 211 additions and 86 deletions

View file

@ -193,6 +193,7 @@ config SYS_MALLOC_F_LEN
config SMP
bool "Symmetric Multi-Processing"
depends on SBI_V01 || !RISCV_SMODE
help
This enables support for systems with more than one CPU. If
you say N here, U-Boot will run on single and multiprocessor
@ -200,10 +201,21 @@ config SMP
machine. If you say Y here, U-Boot will run on many, but not
all, single processor machines.
config SPL_SMP
bool "Symmetric Multi-Processing in SPL"
depends on SPL && SPL_RISCV_MMODE
default y
help
This enables support for systems with more than one CPU in SPL.
If you say N here, U-Boot SPL will run on single and multiprocessor
machines, but will use only one CPU of a multiprocessor
machine. If you say Y here, U-Boot SPL will run on many, but not
all, single processor machines.
config NR_CPUS
int "Maximum number of CPUs (2-32)"
range 2 32
depends on SMP
depends on SMP || SPL_SMP
default 8
help
On multiprocessor machines, U-Boot sets up a stack for each CPU.
@ -214,14 +226,32 @@ config SBI
bool
default y if RISCV_SMODE || SPL_RISCV_SMODE
choice
prompt "SBI support"
default SBI_V02
config SBI_V01
bool "SBI v0.1 support"
default y
depends on SBI
help
This config allows kernel to use SBI v0.1 APIs. This will be
deprecated in future once legacy M-mode software are no longer in use.
config SBI_V02
bool "SBI v0.2 support"
depends on SBI
help
This config allows kernel to use SBI v0.2 APIs. SBI v0.2 is more
scalable and extendable to handle future needs for RISC-V supervisor
interfaces. For example, with SBI v0.2 HSM extension, only a single
hart need to boot and enter operating system. The booting hart can
bring up secondary harts one by one afterwards.
Choose this option if OpenSBI v0.7 or above release is used together
with U-Boot.
endchoice
config SBI_IPI
bool
depends on SBI

View file

@ -12,7 +12,7 @@
#include <asm/csr.h>
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
#if CONFIG_IS_ENABLED(RISCV_MMODE)
/* mcctlcommand */
#define CCTL_REG_MCCTLCOMMAND_NUM 0x7cc
@ -47,7 +47,7 @@ void flush_dcache_all(void)
{
#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
#if CONFIG_IS_ENABLED(RISCV_MMODE)
csr_write(CCTL_REG_MCCTLCOMMAND_NUM, CCTL_L1D_WBINVAL_ALL);
#endif
#endif
@ -68,7 +68,7 @@ void icache_enable(void)
{
#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
#if CONFIG_IS_ENABLED(RISCV_MMODE)
asm volatile (
"csrr t1, mcache_ctl\n\t"
"ori t0, t1, 0x1\n\t"
@ -83,7 +83,7 @@ void icache_disable(void)
{
#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
#if CONFIG_IS_ENABLED(RISCV_MMODE)
asm volatile (
"fence.i\n\t"
"csrr t1, mcache_ctl\n\t"
@ -99,7 +99,7 @@ void dcache_enable(void)
{
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
#if CONFIG_IS_ENABLED(RISCV_MMODE)
asm volatile (
"csrr t1, mcache_ctl\n\t"
"ori t0, t1, 0x2\n\t"
@ -117,7 +117,7 @@ void dcache_disable(void)
{
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
#if CONFIG_IS_ENABLED(RISCV_MMODE)
csr_write(CCTL_REG_MCCTLCOMMAND_NUM, CCTL_L1D_WBINVAL_ALL);
asm volatile (
"csrr t1, mcache_ctl\n\t"
@ -137,7 +137,7 @@ int icache_status(void)
int ret = 0;
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
#if CONFIG_IS_ENABLED(RISCV_MMODE)
asm volatile (
"csrr t1, mcache_ctl\n\t"
"andi %0, t1, 0x01\n\t"
@ -156,7 +156,7 @@ int dcache_status(void)
int ret = 0;
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
#if CONFIG_IS_ENABLED(RISCV_MMODE)
asm volatile (
"csrr t1, mcache_ctl\n\t"
"andi %0, t1, 0x02\n\t"

View file

@ -4,7 +4,6 @@
*/
#include <common.h>
#include <dm.h>
#include <irq_func.h>
/*
@ -21,16 +20,3 @@ int cleanup_before_linux(void)
return 0;
}
/* To enumerate devices on the /soc/ node, create a "simple-bus" driver */
static const struct udevice_id riscv_virtio_soc_ids[] = {
{ .compatible = "riscv-virtio-soc" },
{ }
};
U_BOOT_DRIVER(riscv_virtio_soc) = {
.name = "riscv_virtio_soc",
.id = UCLASS_SIMPLE_BUS,
.of_match = riscv_virtio_soc_ids,
.flags = DM_FLAG_PRE_RELOC,
};

View file

@ -53,14 +53,12 @@ _start:
/* mask all interrupts */
csrw MODE_PREFIX(ie), zero
#ifdef CONFIG_SMP
#if CONFIG_IS_ENABLED(SMP)
/* check if hart is within range */
/* tp: hart id */
li t0, CONFIG_NR_CPUS
bge tp, t0, hart_out_of_bounds_loop
#endif
#ifdef CONFIG_SMP
/* set xSIE bit to receive IPIs */
#if CONFIG_IS_ENABLED(RISCV_MMODE)
li t0, MIE_MSIE
@ -93,7 +91,7 @@ call_board_init_f_0:
mv gp, a0
/* setup stack */
#ifdef CONFIG_SMP
#if CONFIG_IS_ENABLED(SMP)
/* tp: hart id */
slli t0, tp, CONFIG_STACK_SIZE_SHIFT
sub sp, a0, t0
@ -121,6 +119,7 @@ call_board_init_f_0:
jal board_init_f_init_reserve
SREG s1, GD_FIRMWARE_FDT_ADDR(gp)
/* save the boot hart id to global_data */
SREG tp, GD_BOOT_HART(gp)
@ -184,7 +183,7 @@ spl_stack_gd_setup:
mv s0, a0
/* setup stack on main hart */
#ifdef CONFIG_SMP
#if CONFIG_IS_ENABLED(SMP)
/* tp: hart id */
slli t0, tp, CONFIG_STACK_SIZE_SHIFT
sub sp, s0, t0
@ -233,7 +232,7 @@ relocate_code:
*Set up the stack
*/
stack_setup:
#ifdef CONFIG_SMP
#if CONFIG_IS_ENABLED(SMP)
/* tp: hart id */
slli t0, tp, CONFIG_STACK_SIZE_SHIFT
sub sp, s2, t0
@ -328,7 +327,7 @@ clbss_l:
blt t0, t1, clbss_l
relocate_secondary_harts:
#ifdef CONFIG_SMP
#if CONFIG_IS_ENABLED(SMP)
/* send relocation IPI */
la t0, secondary_hart_relocate
add a0, t0, t6
@ -372,14 +371,12 @@ call_board_init_r:
*/
jr t4 /* jump to board_init_r() */
#ifdef CONFIG_SMP
#if CONFIG_IS_ENABLED(SMP)
hart_out_of_bounds_loop:
/* Harts in this loop are out of bounds, increase CONFIG_NR_CPUS. */
wfi
j hart_out_of_bounds_loop
#endif
#ifdef CONFIG_SMP
/* SMP relocation entry */
secondary_hart_relocate:
/* a1: new sp */
@ -397,7 +394,7 @@ secondary_hart_relocate:
secondary_hart_loop:
wfi
#ifdef CONFIG_SMP
#if CONFIG_IS_ENABLED(SMP)
csrr t0, MODE_PREFIX(ip)
#if CONFIG_IS_ENABLED(RISCV_MMODE)
andi t0, t0, MIE_MSIE

View file

@ -15,6 +15,7 @@
/* Architecture-specific global data */
struct arch_global_data {
long boot_hart; /* boot hart id */
phys_addr_t firmware_fdt_addr;
#ifdef CONFIG_SIFIVE_CLINT
void __iomem *clint; /* clint base address */
#endif
@ -24,7 +25,7 @@ struct arch_global_data {
#ifdef CONFIG_ANDES_PLMT
void __iomem *plmt; /* plmt base address */
#endif
#ifdef CONFIG_SMP
#if CONFIG_IS_ENABLED(SMP)
struct ipi_data ipi[CONFIG_NR_CPUS];
#endif
#ifndef CONFIG_XIP

View file

@ -17,5 +17,7 @@ int cleanup_before_linux(void);
/* board/.../... */
int board_init(void);
void board_quiesce_devices(void);
int riscv_board_reserved_mem_fixup(void *fdt);
int riscv_fdt_copy_resv_mem_node(const void *src_fdt, void *dest_fdt);
#endif /* _U_BOOT_RISCV_H_ */

View file

@ -22,8 +22,9 @@ endif
obj-y += interrupts.o
obj-y += reset.o
obj-y += setjmp.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_$(SPL_)SMP) += smp.o
obj-$(CONFIG_SPL_BUILD) += spl.o
obj-y += fdt_fixup.o
# For building EFI apps
CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI)

View file

@ -14,6 +14,7 @@
int main(void)
{
DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart));
DEFINE(GD_FIRMWARE_FDT_ADDR, offsetof(gd_t, arch.firmware_fdt_addr));
#ifndef CONFIG_XIP
DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts));
#endif

View file

@ -26,11 +26,6 @@ __weak void board_quiesce_devices(void)
{
}
int arch_fixup_fdt(void *blob)
{
return 0;
}
/**
* announce_and_cleanup() - Print message and prepare for kernel boot
*

150
arch/riscv/lib/fdt_fixup.c Normal file
View file

@ -0,0 +1,150 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2020 Western Digital Corporation or its affiliates
*
*/
#include <common.h>
#include <fdt_support.h>
#include <mapmem.h>
DECLARE_GLOBAL_DATA_PTR;
/**
* riscv_fdt_copy_resv_mem_node() - Copy reserve memory node entry
* @src: Pointer to the source device tree from which reserved memory node
* needs to be copied.
* @dst: Pointer to the destination device tree to which reserved memory node
* needs to be copied.
*
* Return: 0 on success or if source doesn't have reserved memory node.
* Error if copy process failed.
*/
int riscv_fdt_copy_resv_mem_node(const void *src, void *dst)
{
u32 phandle;
struct fdt_memory pmp_mem;
fdt_addr_t addr;
fdt_size_t size;
int offset, node, err, rmem_offset;
bool nomap = true;
char basename[32] = {0};
int bname_len;
int max_len = sizeof(basename);
const char *name;
char *temp;
offset = fdt_path_offset(src, "/reserved-memory");
if (offset < 0) {
printf("No reserved memory region found in source FDT\n");
return 0;
}
fdt_for_each_subnode(node, src, offset) {
name = fdt_get_name(src, node, NULL);
addr = fdtdec_get_addr_size_auto_noparent(src, node,
"reg", 0, &size,
false);
if (addr == FDT_ADDR_T_NONE) {
debug("failed to read address/size for %s\n", name);
continue;
}
strncpy(basename, name, max_len);
temp = strchr(basename, '@');
if (temp) {
bname_len = strnlen(basename, max_len) - strnlen(temp,
max_len);
*(basename + bname_len) = '\0';
}
pmp_mem.start = addr;
pmp_mem.end = addr + size - 1;
err = fdtdec_add_reserved_memory(dst, basename, &pmp_mem,
&phandle);
if (err < 0) {
printf("failed to add reserved memory: %d\n", err);
return err;
}
if (!fdt_getprop(src, node, "no-map", NULL))
nomap = false;
if (nomap) {
rmem_offset = fdt_node_offset_by_phandle(dst, phandle);
fdt_setprop_empty(dst, rmem_offset, "no-map");
}
}
return 0;
}
/**
* riscv_board_reserved_mem_fixup() - Fix up reserved memory node for a board
* @fdt: Pointer to the device tree in which reserved memory node needs to be
* added.
*
* In RISC-V, any board compiled with OF_SEPARATE needs to copy the reserved
* memory node from the device tree provided by the firmware to the device tree
* used by U-Boot. This is a common function that individual board fixup
* functions can invoke.
*
* Return: 0 on success or error otherwise.
*/
int riscv_board_reserved_mem_fixup(void *fdt)
{
int err;
void *src_fdt_addr;
src_fdt_addr = map_sysmem(gd->arch.firmware_fdt_addr, 0);
err = riscv_fdt_copy_resv_mem_node(src_fdt_addr, fdt);
if (err < 0)
return err;
return 0;
}
#ifdef CONFIG_OF_BOARD_FIXUP
int board_fix_fdt(void *fdt)
{
int err;
err = riscv_board_reserved_mem_fixup(fdt);
if (err < 0) {
printf("failed to fixup DT for reserved memory: %d\n", err);
return err;
}
return 0;
}
#endif
int arch_fixup_fdt(void *blob)
{
int err;
#ifdef CONFIG_EFI_LOADER
u32 size;
int chosen_offset;
size = fdt_totalsize(blob);
err = fdt_open_into(blob, blob, size + 32);
if (err < 0) {
printf("Device Tree can't be expanded to accommodate new node");
return err;
}
chosen_offset = fdt_path_offset(blob, "/chosen");
if (chosen_offset < 0) {
err = fdt_add_subnode(blob, 0, "chosen");
if (err < 0) {
printf("chosen node can not be added\n");
return err;
}
}
/* Overwrite the boot-hartid as U-Boot is the last stage BL */
fdt_setprop_u32(blob, chosen_offset, "boot-hartid", gd->arch.boot_hart);
#endif
/* Copy the reserved-memory node to the DT used by OS */
err = riscv_fdt_copy_resv_mem_node(gd->fdt_blob, blob);
if (err < 0)
return err;
return 0;
}

View file

@ -41,7 +41,7 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
invalidate_icache_all();
debug("image entry point: 0x%lX\n", spl_image->entry_point);
#ifdef CONFIG_SMP
#ifdef CONFIG_SPL_SMP
ret = smp_call_function(spl_image->entry_point, (ulong)fdt_blob, 0, 0);
if (ret)
hang();

View file

@ -43,7 +43,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
imply CMD_EXT4
imply CMD_FAT
imply BOARD_LATE_INIT
imply OF_BOARD_SETUP
imply SIFIVE_SERIAL
imply SMP
imply PCI

View file

@ -52,45 +52,6 @@ int board_late_init(void)
return 0;
}
/*
* QEMU specifies the location of Linux (supplied with the -kernel argument)
* in the device tree using the riscv,kernel-start and riscv,kernel-end
* properties. We currently rely on the SBI implementation of BBL to run
* Linux and therefore embed Linux as payload in BBL. This causes an issue,
* because BBL detects the kernel properties in the device tree and ignores
* the Linux payload as a result. To work around this issue, we clear the
* kernel properties before booting Linux.
*
* This workaround can be removed, once we do not require BBL for its SBI
* implementation anymore.
*/
int ft_board_setup(void *blob, bd_t *bd)
{
int chosen_offset, ret;
chosen_offset = fdt_path_offset(blob, "/chosen");
if (chosen_offset < 0)
return 0;
#ifdef CONFIG_ARCH_RV64I
ret = fdt_setprop_u64(blob, chosen_offset, "riscv,kernel-start", 0);
#else
ret = fdt_setprop_u32(blob, chosen_offset, "riscv,kernel-start", 0);
#endif
if (ret)
return ret;
#ifdef CONFIG_ARCH_RV64I
ret = fdt_setprop_u64(blob, chosen_offset, "riscv,kernel-end", 0);
#else
ret = fdt_setprop_u32(blob, chosen_offset, "riscv,kernel-end", 0);
#endif
if (ret)
return ret;
return 0;
}
#ifdef CONFIG_SPL
u32 spl_boot_device(void)
{

View file

@ -76,7 +76,7 @@ void spl_invoke_opensbi(struct spl_image_info *spl_image)
opensbi_entry = (void (*)(ulong, ulong, ulong))spl_image->entry_point;
invalidate_icache_all();
#ifdef CONFIG_SMP
#ifdef CONFIG_SPL_SMP
/*
* Start OpenSBI on all secondary harts and wait for acknowledgment.
*

View file

@ -9,6 +9,7 @@ CONFIG_FIT=y
CONFIG_MISC_INIT_R=y
CONFIG_DISPLAY_CPUINFO=y
CONFIG_DISPLAY_BOARDINFO=y
CONFIG_OF_BOARD_FIXUP=y
CONFIG_DEFAULT_DEVICE_TREE="hifive-unleashed-a00"
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_DM_MTD=y

View file

@ -56,7 +56,7 @@ For instructions on how to run U-Boot in supervisor mode on QEMU
with OpenSBI, see the documentation available with OpenSBI:
https://github.com/riscv/opensbi/blob/master/docs/platform/qemu_virt.md
These have been tested in QEMU 3.0.0.
These have been tested in QEMU 4.2.0.
Running U-Boot SPL
------------------

View file

@ -1311,7 +1311,8 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename,
continue;
}
if (addr == carveout->start && (addr + size) == carveout->end) {
if (addr == carveout->start && (addr + size - 1) ==
carveout->end) {
if (phandlep)
*phandlep = fdt_get_phandle(blob, node);
return 0;