
On Thu, 2018-08-30 at 00:54 -0700, Bin Meng wrote:
This adds QEMU RISC-V 'virt' board target support, with the hope of helping people easily test U-Boot on RISC-V.
The QEMU virt machine models a generic RISC-V virtual machine with support for the VirtIO standard networking and block storage devices. It has CLINT, PLIC, 16550A UART devices in addition to VirtIO and it also uses device-tree to pass configuration information to guest software. It implements RISC-V privileged architecture spec v1.10.
Both 32-bit and 64-bit builds are supported. Support is pretty much preliminary, only booting to U-Boot shell with the UART driver on a single core. Booting Linux is not supported yet.
For your information and to avoid duplicate work, I am working on a patch set that improves RISC-V support in u-boot. I am currently able to boot Linux on a multi-core setup in QEMU, but they are not quite ready to submit yet.
Thank you for your patches, it's great to see better support for RISC-V in u-boot! I will add a few comments based on what I have learned so far from working with u-boot on RISC-V.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
arch/riscv/Kconfig | 4 +++ arch/riscv/cpu/qemu/Makefile | 6 +++++ arch/riscv/cpu/qemu/cpu.c | 29 +++++++++++++++++++++ arch/riscv/cpu/qemu/dram.c | 17 ++++++++++++ board/emulation/qemu-riscv/Kconfig | 21 +++++++++++++++ board/emulation/qemu-riscv/MAINTAINERS | 7 +++++ board/emulation/qemu-riscv/Makefile | 5 ++++ board/emulation/qemu-riscv/qemu-riscv.c | 23 +++++++++++++++++ configs/qemu-riscv32_defconfig | 10 +++++++ configs/qemu-riscv64_defconfig | 11 ++++++++ doc/README.qemu-riscv | 46 +++++++++++++++++++++++++++++++++ include/configs/qemu-riscv.h | 21 +++++++++++++++ 12 files changed, 200 insertions(+) create mode 100644 arch/riscv/cpu/qemu/Makefile create mode 100644 arch/riscv/cpu/qemu/cpu.c create mode 100644 arch/riscv/cpu/qemu/dram.c create mode 100644 board/emulation/qemu-riscv/Kconfig create mode 100644 board/emulation/qemu-riscv/MAINTAINERS create mode 100644 board/emulation/qemu-riscv/Makefile create mode 100644 board/emulation/qemu-riscv/qemu-riscv.c create mode 100644 configs/qemu-riscv32_defconfig create mode 100644 configs/qemu-riscv64_defconfig create mode 100644 doc/README.qemu-riscv create mode 100644 include/configs/qemu-riscv.h
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 49f87de..168ca3d 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -11,9 +11,13 @@ choice config TARGET_AX25_AE350 bool "Support ax25-ae350"
+config TARGET_QEMU_VIRT
- bool "Support QEMU Virt Board"
endchoice
source "board/AndesTech/ax25-ae350/Kconfig" +source "board/emulation/qemu-riscv/Kconfig"
choice prompt "CPU selection" diff --git a/arch/riscv/cpu/qemu/Makefile b/arch/riscv/cpu/qemu/Makefile new file mode 100644 index 0000000..258e462 --- /dev/null +++ b/arch/riscv/cpu/qemu/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com
+obj-y += dram.o +obj-y += cpu.o diff --git a/arch/riscv/cpu/qemu/cpu.c b/arch/riscv/cpu/qemu/cpu.c new file mode 100644 index 0000000..a064639 --- /dev/null +++ b/arch/riscv/cpu/qemu/cpu.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com
- */
+#include <common.h> +#include <command.h>
+/*
- cleanup_before_linux() is called just before we call linux
- it prepares the processor for linux
- we disable interrupt and caches.
- */
+int cleanup_before_linux(void) +{
- disable_interrupts();
- /* turn off I/D-cache */
- return 0;
+}
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{
- printf("reset unsupported yet\n");
- return 0;
+}
We don't have a reset method on any RISC-V board yet. Instead of adding the same 'unsupported' message for each CPU variant it might make more sense to add a generic do_reset function for all CPU variants to lib/, similar to the one for ARM (arch/arm/lib/reset.c).
diff --git a/arch/riscv/cpu/qemu/dram.c b/arch/riscv/cpu/qemu/dram.c new file mode 100644 index 0000000..84d87d2 --- /dev/null +++ b/arch/riscv/cpu/qemu/dram.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com
- */
+#include <common.h> +#include <fdtdec.h>
+int dram_init(void) +{
- return fdtdec_setup_mem_size_base();
+}
+int dram_init_banksize(void) +{
- return fdtdec_setup_memory_banksize();
+} diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig new file mode 100644 index 0000000..029f5efb --- /dev/null +++ b/board/emulation/qemu-riscv/Kconfig @@ -0,0 +1,21 @@ +if TARGET_QEMU_VIRT
+config SYS_BOARD
- default "qemu-riscv"
+config SYS_VENDOR
- default "emulation"
+config SYS_CPU
- default "qemu"
+config SYS_CONFIG_NAME
- default "qemu-riscv"
+config SYS_TEXT_BASE
- default 0x80000000
+config BOARD_SPECIFIC_OPTIONS # dummy
- def_bool y
+endif diff --git a/board/emulation/qemu-riscv/MAINTAINERS b/board/emulation/qemu-riscv/MAINTAINERS new file mode 100644 index 0000000..3c6eb4f --- /dev/null +++ b/board/emulation/qemu-riscv/MAINTAINERS @@ -0,0 +1,7 @@ +QEMU RISC-V 'VIRT' BOARD +M: Bin Meng bmeng.cn@gmail.com +S: Maintained +F: board/emulation/qemu-riscv/ +F: include/configs/qemu-riscv.h +F: configs/qemu-riscv32_defconfig +F: configs/qemu-riscv64_defconfig diff --git a/board/emulation/qemu-riscv/Makefile b/board/emulation/qemu-riscv/Makefile new file mode 100644 index 0000000..3f29b90 --- /dev/null +++ b/board/emulation/qemu-riscv/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com
+obj-y += qemu-riscv.o diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c new file mode 100644 index 0000000..041e716 --- /dev/null +++ b/board/emulation/qemu-riscv/qemu-riscv.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com
- */
+#include <common.h> +#include <fdtdec.h>
+#define MROM_FDT_ADDR 0x1020
This value is not specified anywhere, so it could change without prior warning. The value is also passed in a1 by ROM. If you want I can update the code to use this value when I submit my patches.
Thanks, Lukas
+int board_init(void) +{
- return 0;
+}
+void *board_fdt_blob_setup(void) +{
- /*
* QEMU loads a generated DTB for us immediately
* after the reset vectors in the MROM
*/
- return (void *)MROM_FDT_ADDR;
+} diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu- riscv32_defconfig new file mode 100644 index 0000000..cbd2c91 --- /dev/null +++ b/configs/qemu-riscv32_defconfig @@ -0,0 +1,10 @@ +CONFIG_RISCV=y +CONFIG_TARGET_QEMU_VIRT=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_BOOTDELAY=3 +CONFIG_DISPLAY_CPUINFO=y +CONFIG_DISPLAY_BOARDINFO=y +CONFIG_OF_BOARD=y +CONFIG_DM_SERIAL=y +CONFIG_SYS_NS16550=y +CONFIG_TIMER=y diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu- riscv64_defconfig new file mode 100644 index 0000000..af8b307 --- /dev/null +++ b/configs/qemu-riscv64_defconfig @@ -0,0 +1,11 @@ +CONFIG_RISCV=y +CONFIG_TARGET_QEMU_VIRT=y +CONFIG_CPU_RISCV_64=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_BOOTDELAY=3 +CONFIG_DISPLAY_CPUINFO=y +CONFIG_DISPLAY_BOARDINFO=y +CONFIG_OF_BOARD=y +CONFIG_DM_SERIAL=y +CONFIG_SYS_NS16550=y +CONFIG_TIMER=y diff --git a/doc/README.qemu-riscv b/doc/README.qemu-riscv new file mode 100644 index 0000000..e2e4804 --- /dev/null +++ b/doc/README.qemu-riscv @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com
+U-Boot on QEMU's 'virt' machine on RISC-V +=========================================
+QEMU for RISC-V supports a special 'virt' machine designed for emulation and +virtualization purposes. This document describes how to run U-Boot under it. +Both 32-bit 64-bit targets are supported.
+The QEMU virt machine models a generic RISC-V virtual machine with support for +the VirtIO standard networking and block storage devices. It has CLINT, PLIC, +16550A UART devices in addition to VirtIO and it also uses device- tree to pass +configuration information to guest software. It implements RISC-V privileged +architecture spec v1.10.
+Building U-Boot +--------------- +Set the CROSS_COMPILE environment variable as usual, and run:
+- For 32-bit RISC-V:
- make qemu-riscv32_defconfig
- make
+- For 64-bit RISC-V:
- make qemu-riscv64_defconfig
- make
+Running U-Boot +-------------- +The minimal QEMU command line to get U-Boot up and running is:
+- For 32-bit RISC-V:
- qemu-system-riscv32 -nographic -machine virt -kernel u-boot
+- For 64-bit RISC-V:
- qemu-system-riscv64 -nographic -machine virt -kernel u-boot
+The commands above create targets with 128MiB memory by default. +A freely configurable amount of RAM can be created via the '-m' +parameter. For example, '-m 2G' creates 2GiB memory for the target, +and the memory node in the embedded DTB created by QEMU reflects +the new setting.
+These have been tested in QEMU 3.0.0. diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu- riscv.h new file mode 100644 index 0000000..d279c23 --- /dev/null +++ b/include/configs/qemu-riscv.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com
- */
+#ifndef __CONFIG_H +#define __CONFIG_H
+#include <linux/sizes.h>
+#define CONFIG_SYS_SDRAM_BASE 0x80000000 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE
- SZ_2M)
+#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M)
+#define CONFIG_SYS_MALLOC_LEN SZ_8M
+/* Environment options */ +#define CONFIG_ENV_SIZE SZ_4K
+#endif /* __CONFIG_H */