aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2018-10-03 08:09:53 -0400
committerTom Rini <trini@konsulko.com>2018-10-03 08:09:53 -0400
commit94228a9188803473206544c8f33649ea72bf1ee1 (patch)
tree90404ec7c59822c3706f3051e393001a5c53aef5
parente5145ad0e8c2a21f1db376b01c676907f1500ac6 (diff)
parent5845f6612372a63877b2175e058a841e1237ffd6 (diff)
downloadu-boot-94228a9188803473206544c8f33649ea72bf1ee1.zip
u-boot-94228a9188803473206544c8f33649ea72bf1ee1.tar.gz
u-boot-94228a9188803473206544c8f33649ea72bf1ee1.tar.bz2
Merge git://git.denx.de/u-boot-riscv
- QEMU support
-rw-r--r--arch/Kconfig14
-rw-r--r--arch/riscv/Kconfig10
-rw-r--r--arch/riscv/Makefile3
-rw-r--r--arch/riscv/config.mk12
-rw-r--r--arch/riscv/cpu/Makefile7
-rw-r--r--arch/riscv/cpu/ax25/Makefile2
-rw-r--r--arch/riscv/cpu/ax25/cpu.c9
-rw-r--r--arch/riscv/cpu/cpu.c49
-rw-r--r--arch/riscv/cpu/qemu/Makefile6
-rw-r--r--arch/riscv/cpu/qemu/cpu.c21
-rw-r--r--arch/riscv/cpu/qemu/dram.c17
-rw-r--r--arch/riscv/cpu/start.S (renamed from arch/riscv/cpu/ax25/start.S)0
-rw-r--r--arch/riscv/cpu/u-boot.lds (renamed from arch/riscv/cpu/ax25/u-boot.lds)60
-rw-r--r--arch/riscv/dts/ae350.dts177
-rw-r--r--arch/riscv/include/asm/bootm.h13
-rw-r--r--arch/riscv/include/asm/csr.h124
-rw-r--r--arch/riscv/include/asm/encoding.h50
-rw-r--r--arch/riscv/include/asm/mach-types.h29
-rw-r--r--arch/riscv/include/asm/setup.h194
-rw-r--r--arch/riscv/include/asm/u-boot.h1
-rw-r--r--arch/riscv/lib/Makefile1
-rw-r--r--arch/riscv/lib/bootm.c20
-rw-r--r--arch/riscv/lib/reset.c17
-rw-r--r--board/AndesTech/ax25-ae350/ax25-ae350.c2
-rw-r--r--board/emulation/qemu-riscv/Kconfig22
-rw-r--r--board/emulation/qemu-riscv/MAINTAINERS7
-rw-r--r--board/emulation/qemu-riscv/Makefile5
-rw-r--r--board/emulation/qemu-riscv/qemu-riscv.c23
-rw-r--r--cmd/bdinfo.c3
-rw-r--r--configs/ax25-ae350_defconfig10
-rw-r--r--configs/qemu-riscv32_defconfig6
-rw-r--r--configs/qemu-riscv64_defconfig7
-rw-r--r--doc/README.qemu-riscv46
-rw-r--r--include/configs/qemu-riscv.h21
34 files changed, 538 insertions, 450 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index 9b4bcbf..c988c17 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -60,8 +60,20 @@ config PPC
select SYS_BOOT_GET_KBD
config RISCV
- bool "riscv architecture"
+ bool "RISC-V architecture"
select SUPPORT_OF_CONTROL
+ select OF_CONTROL
+ select DM
+ imply DM_SERIAL
+ imply DM_ETH
+ imply DM_MMC
+ imply DM_SPI
+ imply DM_SPI_FLASH
+ imply BLK
+ imply CLK
+ imply MTD
+ imply TIMER
+ imply CMD_DM
config SANDBOX
bool "Sandbox"
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 20a43d8..168ca3d 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -1,4 +1,4 @@
-menu "RISCV architecture"
+menu "RISC-V architecture"
depends on RISCV
config SYS_ARCH
@@ -11,22 +11,26 @@ 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"
default CPU_RISCV_32
config CPU_RISCV_32
- bool "RISCV 32 bit"
+ bool "RISC-V 32-bit"
select 32BIT
help
Choose this option to build an U-Boot for RISCV32 architecture.
config CPU_RISCV_64
- bool "RISCV 64 bit"
+ bool "RISC-V 64-bit"
select 64BIT
help
Choose this option to build an U-Boot for RISCV64 architecture.
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 084888a..8fb6a88 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -3,7 +3,8 @@
# Copyright (C) 2017 Andes Technology Corporation.
# Rick Chen, Andes Technology Corporation <rick@andestech.com>
-head-y := arch/riscv/cpu/$(CPU)/start.o
+head-y := arch/riscv/cpu/start.o
+libs-y += arch/riscv/cpu/
libs-y += arch/riscv/cpu/$(CPU)/
libs-y += arch/riscv/lib/
diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk
index c0b3858..ed9eb0c 100644
--- a/arch/riscv/config.mk
+++ b/arch/riscv/config.mk
@@ -10,20 +10,20 @@
# Rick Chen, Andes Technology Corporation <rick@andestech.com>
#
-ifeq ($(CROSS_COMPILE),)
-CROSS_COMPILE := riscv32-unknown-linux-gnu-
-endif
-
32bit-emul := elf32lriscv
64bit-emul := elf64lriscv
ifdef CONFIG_32BIT
+PLATFORM_CPPFLAGS += -march=rv32ima -mabi=ilp32
PLATFORM_LDFLAGS += -m $(32bit-emul)
+CFLAGS_EFI += -march=rv32ima -mabi=ilp32
EFI_LDS := elf_riscv32_efi.lds
endif
ifdef CONFIG_64BIT
+PLATFORM_CPPFLAGS += -march=rv64ima -mabi=lp64
PLATFORM_LDFLAGS += -m $(64bit-emul)
+CFLAGS_EFI += -march=rv64ima -mabi=lp64
EFI_LDS := elf_riscv64_efi.lds
endif
@@ -31,8 +31,8 @@ CONFIG_STANDALONE_LOAD_ADDR = 0x00000000 \
-T $(srctree)/examples/standalone/riscv.lds
PLATFORM_CPPFLAGS += -ffixed-gp -fpic
-PLATFORM_RELFLAGS += -fno-common -gdwarf-2 -ffunction-sections
-LDFLAGS_u-boot += --gc-sections -static -pie
+PLATFORM_RELFLAGS += -fno-common -gdwarf-2 -ffunction-sections
+LDFLAGS_u-boot += --gc-sections -static -pie
EFI_CRT0 := crt0_riscv_efi.o
EFI_RELOC := reloc_riscv_efi.o
diff --git a/arch/riscv/cpu/Makefile b/arch/riscv/cpu/Makefile
new file mode 100644
index 0000000..2cc6757
--- /dev/null
+++ b/arch/riscv/cpu/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+
+extra-y = start.o
+
+obj-y += cpu.o
diff --git a/arch/riscv/cpu/ax25/Makefile b/arch/riscv/cpu/ax25/Makefile
index c3f164c..2ab0342 100644
--- a/arch/riscv/cpu/ax25/Makefile
+++ b/arch/riscv/cpu/ax25/Makefile
@@ -3,6 +3,4 @@
# Copyright (C) 2017 Andes Technology Corporation
# Rick Chen, Andes Technology Corporation <rick@andestech.com>
-extra-y = start.o
-
obj-y := cpu.o
diff --git a/arch/riscv/cpu/ax25/cpu.c b/arch/riscv/cpu/ax25/cpu.c
index ab05b57..fddcc15 100644
--- a/arch/riscv/cpu/ax25/cpu.c
+++ b/arch/riscv/cpu/ax25/cpu.c
@@ -6,9 +6,6 @@
/* CPU specific code */
#include <common.h>
-#include <command.h>
-#include <watchdog.h>
-#include <asm/cache.h>
/*
* cleanup_before_linux() is called just before we call linux
@@ -24,9 +21,3 @@ int cleanup_before_linux(void)
return 0;
}
-
-int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- disable_interrupts();
- panic("ax25-ae350 wdt not support yet.\n");
-}
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
new file mode 100644
index 0000000..ae57fb8
--- /dev/null
+++ b/arch/riscv/cpu/cpu.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+#include <asm/csr.h>
+
+enum {
+ ISA_INVALID = 0,
+ ISA_32BIT,
+ ISA_64BIT,
+ ISA_128BIT
+};
+
+static const char * const isa_bits[] = {
+ [ISA_INVALID] = NULL,
+ [ISA_32BIT] = "32",
+ [ISA_64BIT] = "64",
+ [ISA_128BIT] = "128"
+};
+
+static inline bool supports_extension(char ext)
+{
+ return csr_read(misa) & (1 << (ext - 'a'));
+}
+
+int print_cpuinfo(void)
+{
+ char name[32];
+ char *s = name;
+ int bit;
+
+ s += sprintf(name, "rv");
+ bit = csr_read(misa) >> (sizeof(long) * 8 - 2);
+ s += sprintf(s, isa_bits[bit]);
+
+ supports_extension('i') ? *s++ = 'i' : 'r';
+ supports_extension('m') ? *s++ = 'm' : 'i';
+ supports_extension('a') ? *s++ = 'a' : 's';
+ supports_extension('f') ? *s++ = 'f' : 'c';
+ supports_extension('d') ? *s++ = 'd' : '-';
+ supports_extension('c') ? *s++ = 'c' : 'v';
+ *s++ = '\0';
+
+ printf("CPU: %s\n", name);
+
+ return 0;
+}
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..6c7a327
--- /dev/null
+++ b/arch/riscv/cpu/qemu/cpu.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.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;
+}
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/arch/riscv/cpu/ax25/start.S b/arch/riscv/cpu/start.S
index 7cd7755..7cd7755 100644
--- a/arch/riscv/cpu/ax25/start.S
+++ b/arch/riscv/cpu/start.S
diff --git a/arch/riscv/cpu/ax25/u-boot.lds b/arch/riscv/cpu/u-boot.lds
index c50b964..11bc4a7 100644
--- a/arch/riscv/cpu/ax25/u-boot.lds
+++ b/arch/riscv/cpu/u-boot.lds
@@ -3,28 +3,27 @@
* Copyright (C) 2017 Andes Technology Corporation
* Rick Chen, Andes Technology Corporation <rick@andestech.com>
*/
+
OUTPUT_ARCH("riscv")
ENTRY(_start)
SECTIONS
{
. = ALIGN(4);
- .text :
- {
- arch/riscv/cpu/ax25/start.o (.text)
+ .text : {
+ arch/riscv/cpu/start.o (.text)
}
/* This needs to come before *(.text*) */
.efi_runtime : {
- __efi_runtime_start = .;
+ __efi_runtime_start = .;
*(.text.efi_runtime*)
*(.rodata.efi_runtime*)
*(.data.efi_runtime*)
- __efi_runtime_stop = .;
+ __efi_runtime_stop = .;
}
- .text_rest :
- {
+ .text_rest : {
*(.text*)
}
@@ -39,10 +38,10 @@ SECTIONS
. = ALIGN(4);
.got : {
- __got_start = .;
- *(.got.plt) *(.got)
- __got_end = .;
- }
+ __got_start = .;
+ *(.got.plt) *(.got)
+ __got_end = .;
+ }
. = ALIGN(4);
@@ -50,41 +49,40 @@ SECTIONS
KEEP(*(SORT(.u_boot_list*)));
}
- . = ALIGN(4);
+ . = ALIGN(4);
.efi_runtime_rel : {
- __efi_runtime_rel_start = .;
+ __efi_runtime_rel_start = .;
*(.rel*.efi_runtime)
*(.rel*.efi_runtime.*)
- __efi_runtime_rel_stop = .;
+ __efi_runtime_rel_stop = .;
}
- . = ALIGN(4);
+ . = ALIGN(4);
- /DISCARD/ : { *(.rela.plt*) }
- .rela.dyn : {
- __rel_dyn_start = .;
- *(.rela*)
- __rel_dyn_end = .;
- }
+ /DISCARD/ : { *(.rela.plt*) }
+ .rela.dyn : {
+ __rel_dyn_start = .;
+ *(.rela*)
+ __rel_dyn_end = .;
+ }
- . = ALIGN(4);
+ . = ALIGN(4);
- .dynsym : {
- __dyn_sym_start = .;
- *(.dynsym)
- __dyn_sym_end = .;
- }
+ .dynsym : {
+ __dyn_sym_start = .;
+ *(.dynsym)
+ __dyn_sym_end = .;
+ }
- . = ALIGN(4);
+ . = ALIGN(4);
_end = .;
.bss : {
- __bss_start = .;
- *(.bss*)
+ __bss_start = .;
+ *(.bss*)
. = ALIGN(4);
__bss_end = .;
}
-
}
diff --git a/arch/riscv/dts/ae350.dts b/arch/riscv/dts/ae350.dts
index 2927e41..4717ae8 100644
--- a/arch/riscv/dts/ae350.dts
+++ b/arch/riscv/dts/ae350.dts
@@ -1,144 +1,147 @@
/dts-v1/;
/ {
- #address-cells = <2>;
- #size-cells = <2>;
- compatible = "andestech,ax25";
- model = "andestech,ax25";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "andestech,ax25";
+ model = "andestech,ax25";
aliases {
uart0 = &serial0;
spi0 = &spi;
- } ;
+ };
chosen {
bootargs = "console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0xf0300000 debug loglevel=7";
stdout-path = "uart0:38400n8";
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
- timebase-frequency = <10000000>;
- CPU0: cpu@0 {
- device_type = "cpu";
- reg = <0>;
- status = "okay";
- compatible = "riscv";
- riscv,isa = "rv64imafdc";
- mmu-type = "riscv,sv39";
- clock-frequency = <60000000>;
- CPU0_intc: interrupt-controller {
- #interrupt-cells = <1>;
- interrupt-controller;
- compatible = "riscv,cpu-intc";
- };
- };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <10000000>;
+
+ CPU0: cpu@0 {
+ device_type = "cpu";
+ reg = <0>;
+ status = "okay";
+ compatible = "riscv";
+ riscv,isa = "rv64imafdc";
+ mmu-type = "riscv,sv39";
+ clock-frequency = <60000000>;
+
+ CPU0_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "riscv,cpu-intc";
+ };
+ };
};
memory@0 {
device_type = "memory";
- reg = <0x0 0x00000000 0x0 0x40000000>;
+ reg = <0x0 0x00000000 0x0 0x40000000>;
};
- soc {
- #address-cells = <2>;
- #size-cells = <2>;
- compatible = "andestech,riscv-ae350-soc";
- ranges;
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "andestech,riscv-ae350-soc";
+ ranges;
};
- plmt0@e6000000 {
- compatible = "riscv,plmt0";
- interrupts-extended = <&CPU0_intc 7>;
- reg = <0x0 0xe6000000 0x0 0x100000>;
- };
+ plmt0@e6000000 {
+ compatible = "riscv,plmt0";
+ interrupts-extended = <&CPU0_intc 7>;
+ reg = <0x0 0xe6000000 0x0 0x100000>;
+ };
- plic0: interrupt-controller@e4000000 {
- compatible = "riscv,plic0";
- #address-cells = <2>;
- #interrupt-cells = <2>;
- interrupt-controller;
- reg = <0x0 0xe4000000 0x0 0x2000000>;
- riscv,ndev=<31>;
- interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
+ plic0: interrupt-controller@e4000000 {
+ compatible = "riscv,plic0";
+ #address-cells = <2>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0x0 0xe4000000 0x0 0x2000000>;
+ riscv,ndev=<31>;
+ interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
};
- plic1: interrupt-controller@e6400000 {
- compatible = "riscv,plic1";
- #address-cells = <2>;
- #interrupt-cells = <2>;
+ plic1: interrupt-controller@e6400000 {
+ compatible = "riscv,plic1";
+ #address-cells = <2>;
+ #interrupt-cells = <2>;
interrupt-controller;
- reg = <0x0 0xe6400000 0x0 0x400000>;
- riscv,ndev=<1>;
- interrupts-extended = <&CPU0_intc 3>;
- };
+ reg = <0x0 0xe6400000 0x0 0x400000>;
+ riscv,ndev=<1>;
+ interrupts-extended = <&CPU0_intc 3>;
+ };
- spiclk: virt_100mhz {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <100000000>;
- };
+ spiclk: virt_100mhz {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ };
- timer0: timer@f0400000 {
- compatible = "andestech,atcpit100";
- reg = <0x0 0xf0400000 0x0 0x1000>;
- clock-frequency = <40000000>;
- interrupts = <3 4>;
- interrupt-parent = <&plic0>;
+ timer0: timer@f0400000 {
+ compatible = "andestech,atcpit100";
+ reg = <0x0 0xf0400000 0x0 0x1000>;
+ clock-frequency = <40000000>;
+ interrupts = <3 4>;
+ interrupt-parent = <&plic0>;
};
serial0: serial@f0300000 {
compatible = "andestech,uart16550", "ns16550a";
- reg = <0x0 0xf0300000 0x0 0x1000>;
- interrupts = <9 4>;
+ reg = <0x0 0xf0300000 0x0 0x1000>;
+ interrupts = <9 4>;
clock-frequency = <19660800>;
reg-shift = <2>;
reg-offset = <32>;
no-loopback-test = <1>;
- interrupt-parent = <&plic0>;
+ interrupt-parent = <&plic0>;
};
mac0: mac@e0100000 {
compatible = "andestech,atmac100";
- reg = <0x0 0xe0100000 0x0 0x1000>;
- interrupts = <19 4>;
- interrupt-parent = <&plic0>;
+ reg = <0x0 0xe0100000 0x0 0x1000>;
+ interrupts = <19 4>;
+ interrupt-parent = <&plic0>;
};
mmc0: mmc@f0e00000 {
- compatible = "andestech,atfsdc010";
+ compatible = "andestech,atfsdc010";
max-frequency = <100000000>;
- clock-freq-min-max = <400000 100000000>;
+ clock-freq-min-max = <400000 100000000>;
fifo-depth = <0x10>;
- reg = <0x0 0xf0e00000 0x0 0x1000>;
- interrupts = <18 4>;
+ reg = <0x0 0xf0e00000 0x0 0x1000>;
+ interrupts = <18 4>;
cap-sd-highspeed;
- interrupt-parent = <&plic0>;
+ interrupt-parent = <&plic0>;
};
- smc0: smc@e0400000 {
- compatible = "andestech,atfsmc020";
- reg = <0x0 0xe0400000 0x0 0x1000>;
- };
+ smc0: smc@e0400000 {
+ compatible = "andestech,atfsmc020";
+ reg = <0x0 0xe0400000 0x0 0x1000>;
+ };
- nor@0,0 {
- compatible = "cfi-flash";
- reg = <0x0 0x88000000 0x0 0x1000>;
- bank-width = <2>;
- device-width = <1>;
- };
+ nor@0,0 {
+ compatible = "cfi-flash";
+ reg = <0x0 0x88000000 0x0 0x1000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
spi: spi@f0b00000 {
compatible = "andestech,atcspi200";
- reg = <0x0 0xf0b00000 0x0 0x1000>;
+ reg = <0x0 0xf0b00000 0x0 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
num-cs = <1>;
clocks = <&spiclk>;
interrupts = <3 4>;
- interrupt-parent = <&plic0>;
- flash@0 {
+ interrupt-parent = <&plic0>;
+
+ flash@0 {
compatible = "spi-flash";
spi-max-frequency = <50000000>;
reg = <0>;
diff --git a/arch/riscv/include/asm/bootm.h b/arch/riscv/include/asm/bootm.h
deleted file mode 100644
index 6786345..0000000
--- a/arch/riscv/include/asm/bootm.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (c) 2013, Google Inc.
- *
- * Copyright (C) 2011
- * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
- */
-#ifndef NDS32_BOOTM_H
-#define NDS32_BOOTM_H
-
-#include <asm/setup.h>
-
-#endif
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
new file mode 100644
index 0000000..50fccea
--- /dev/null
+++ b/arch/riscv/include/asm/csr.h
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2015 Regents of the University of California
+ *
+ * Taken from Linux arch/riscv/include/asm/csr.h
+ */
+
+#ifndef _ASM_RISCV_CSR_H
+#define _ASM_RISCV_CSR_H
+
+/* Status register flags */
+#define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */
+#define SR_SPIE _AC(0x00000020, UL) /* Previous Supervisor IE */
+#define SR_SPP _AC(0x00000100, UL) /* Previously Supervisor */
+#define SR_SUM _AC(0x00040000, UL) /* Supervisor access User Memory */
+
+#define SR_FS _AC(0x00006000, UL) /* Floating-point Status */
+#define SR_FS_OFF _AC(0x00000000, UL)
+#define SR_FS_INITIAL _AC(0x00002000, UL)
+#define SR_FS_CLEAN _AC(0x00004000, UL)
+#define SR_FS_DIRTY _AC(0x00006000, UL)
+
+#define SR_XS _AC(0x00018000, UL) /* Extension Status */
+#define SR_XS_OFF _AC(0x00000000, UL)
+#define SR_XS_INITIAL _AC(0x00008000, UL)
+#define SR_XS_CLEAN _AC(0x00010000, UL)
+#define SR_XS_DIRTY _AC(0x00018000, UL)
+
+#ifndef CONFIG_64BIT
+#define SR_SD _AC(0x80000000, UL) /* FS/XS dirty */
+#else
+#define SR_SD _AC(0x8000000000000000, UL) /* FS/XS dirty */
+#endif
+
+/* SATP flags */
+#if __riscv_xlen == 32
+#define SATP_PPN _AC(0x003FFFFF, UL)
+#define SATP_MODE_32 _AC(0x80000000, UL)
+#define SATP_MODE SATP_MODE_32
+#else
+#define SATP_PPN _AC(0x00000FFFFFFFFFFF, UL)
+#define SATP_MODE_39 _AC(0x8000000000000000, UL)
+#define SATP_MODE SATP_MODE_39
+#endif
+
+/* Interrupt Enable and Interrupt Pending flags */
+#define SIE_SSIE _AC(0x00000002, UL) /* Software Interrupt Enable */
+#define SIE_STIE _AC(0x00000020, UL) /* Timer Interrupt Enable */
+
+#define EXC_INST_MISALIGNED 0
+#define EXC_INST_ACCESS 1
+#define EXC_BREAKPOINT 3
+#define EXC_LOAD_ACCESS 5
+#define EXC_STORE_ACCESS 7
+#define EXC_SYSCALL 8
+#define EXC_INST_PAGE_FAULT 12
+#define EXC_LOAD_PAGE_FAULT 13
+#define EXC_STORE_PAGE_FAULT 15
+
+#ifndef __ASSEMBLY__
+
+#define csr_swap(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrrw %0, " #csr ", %1" \
+ : "=r" (__v) : "rK" (__v) \
+ : "memory"); \
+ __v; \
+})
+
+#define csr_read(csr) \
+({ \
+ register unsigned long __v; \
+ __asm__ __volatile__ ("csrr %0, " #csr \
+ : "=r" (__v) : \
+ : "memory"); \
+ __v; \
+})
+
+#define csr_write(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrw " #csr ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+
+#define csr_read_set(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrrs %0, " #csr ", %1" \
+ : "=r" (__v) : "rK" (__v) \
+ : "memory"); \
+ __v; \
+})
+
+#define csr_set(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrs " #csr ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+
+#define csr_read_clear(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrrc %0, " #csr ", %1" \
+ : "=r" (__v) : "rK" (__v) \
+ : "memory"); \
+ __v; \
+})
+
+#define csr_clear(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrc " #csr ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_CSR_H */
diff --git a/arch/riscv/include/asm/encoding.h b/arch/riscv/include/asm/encoding.h
index f237a72..9ea50ce 100644
--- a/arch/riscv/include/asm/encoding.h
+++ b/arch/riscv/include/asm/encoding.h
@@ -128,6 +128,7 @@
((SUPERVISOR) ? PTE_SR(PTE) : PTE_UR(PTE)))
#ifdef __riscv
+
#ifdef CONFIG_64BIT
# define MSTATUS_SD MSTATUS64_SD
# define SSTATUS_SD SSTATUS64_SD
@@ -141,53 +142,10 @@
# define MCAUSE_INT MCAUSE32_INT
# define MCAUSE_CAUSE MCAUSE32_CAUSE
#endif
+
#define RISCV_PGSHIFT 12
#define RISCV_PGSIZE BIT(RISCV_PGSHIFT)
-#ifndef __ASSEMBLER__
-
-#ifdef __GNUC__
-
-#define read_csr(reg) ({ unsigned long __tmp; \
- asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
- __tmp; })
-
-#define write_csr(reg, _val) ({ \
-typeof(_val) (val) = (_val); \
-if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
- asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
-else \
- asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
-
-#define swap_csr(reg, _val) ({ unsigned long __tmp; \
-typeof(_val) (val) = (_val); \
-if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
- asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \
-else \
- asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \
- __tmp; })
-
-#define set_csr(reg, _bit) ({ unsigned long __tmp; \
-typeof(_bit) (bit) = (_bit); \
-if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
- asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
-else \
- asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
- __tmp; })
-
-#define clear_csr(reg, _bit) ({ unsigned long __tmp; \
-typeof(_bit) (bit) = (_bit); \
-if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
- asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
-else \
- asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
- __tmp; })
-
-#define rdtime() read_csr(time)
-#define rdcycle() read_csr(cycle)
-#define rdinstret() read_csr(instret)
+#endif /* __riscv */
-#endif
-#endif
-#endif
-#endif
+#endif /* RISCV_CSR_ENCODING_H */
diff --git a/arch/riscv/include/asm/mach-types.h b/arch/riscv/include/asm/mach-types.h
deleted file mode 100644
index f219ced..0000000
--- a/arch/riscv/include/asm/mach-types.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2017 Andes Technology Corporation
- * Rick Chen, Andes Technology Corporation <rick@andestech.com>
- */
-
-#ifndef __ASM_RISCV_MACH_TYPE_H
-#define __ASM_RISCV_MACH_TYPE_H
-
-#ifndef __ASSEMBLY__
-/* The type of machine we're running on */
-extern unsigned int __machine_arch_type;
-#endif
-
-#define MACH_TYPE_AE350 1
-
-#ifdef CONFIG_ARCH_AE350
-# ifdef machine_arch_type
-# undef machine_arch_type
-# define machine_arch_type __machine_arch_type
-# else
-# define machine_arch_type MACH_TYPE_AE350
-# endif
-# define machine_is_ae350() (machine_arch_type == MACH_TYPE_AE350)
-#else
-# define machine_is_ae350() (1)
-#endif
-
-#endif /* __ASM_RISCV_MACH_TYPE_H */
diff --git a/arch/riscv/include/asm/setup.h b/arch/riscv/include/asm/setup.h
deleted file mode 100644
index ff8de16..0000000
--- a/arch/riscv/include/asm/setup.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * linux/arch/nds32/include/asm/setup.h
- *
- * Copyright (C) 1997-1999 Russell King
- * Copyright (C) 2008 Andes Technology Corporation
- * Copyright (C) 2013 Ken Kuo (ken_kuo@andestech.com)
- * Copyright (C) 2017 Rick Chen (rick@andestech.com)
- *
- * Structure passed to kernel to tell it about the
- * hardware it's running on. See Documentation/arm/Setup
- * for more info.
- */
-#ifndef __RISCV_SETUP_H
-#define __RISCV_SETUP_H
-
-#define COMMAND_LINE_SIZE 256
-
-/* The list ends with an ATAG_NONE node. */
-#define ATAG_NONE 0x00000000
-
-struct tag_header {
- u32 size;
- u32 tag;
-};
-
-/* The list must start with an ATAG_CORE node */
-#define ATAG_CORE 0x54410001
-
-struct tag_core {
- u32 flags; /* bit 0 = read-only */
- u32 pagesize;
- u32 rootdev;
-};
-
-/* it is allowed to have multiple ATAG_MEM nodes */
-#define ATAG_MEM 0x54410002
-
-struct tag_mem32 {
- u32 size;
- u32 start; /* physical start address */
-};
-
-/* VGA text type displays */
-#define ATAG_VIDEOTEXT 0x54410003
-
-struct tag_videotext {
- u8 x;
- u8 y;
- u16 video_page;
- u8 video_mode;
- u8 video_cols;
- u16 video_ega_bx;
- u8 video_lines;
- u8 video_isvga;
- u16 video_points;
-};
-
-/* describes how the ramdisk will be used in kernel */
-#define ATAG_RAMDISK 0x54410004
-
-struct tag_ramdisk {
- u32 flags; /* bit 0 = load, bit 1 = prompt */
- u32 size; /* decompressed ramdisk size in _kilo_ bytes */
- u32 start; /* starting block of floppy-based RAM disk image */
-};
-
-/*
- * this one accidentally used virtual addresses - as such,
- * it's deprecated.
- * describes where the compressed ramdisk image lives (virtual address)
- */
-#define ATAG_INITRD 0x54410005
-
-/* describes where the compressed ramdisk image lives (physical address) */
-#define ATAG_INITRD2 0x54420005
-
-struct tag_initrd {
- u32 start; /* physical start address */
- u32 size; /* size of compressed ramdisk image in bytes */
-};
-
-/* board serial number. "64 bits should be enough for everybody" */
-#define ATAG_SERIAL 0x54410006
-
-struct tag_serialnr {
- u32 low;
- u32 high;
-};
-
-/* board revision */
-#define ATAG_REVISION 0x54410007
-
-struct tag_revision {
- u32 rev;
-};
-
-/* initial values for vesafb-type framebuffers. see struct screen_info
- * in include/linux/tty.h
- */
-#define ATAG_VIDEOLFB 0x54410008
-
-struct tag_videolfb {
- u16 lfb_width;
- u16 lfb_height;
- u16 lfb_depth;
- u16 lfb_linelength;
- u32 lfb_base;
- u32 lfb_size;
- u8 red_size;
- u8 red_pos;
- u8 green_size;
- u8 green_pos;
- u8 blue_size;
- u8 blue_pos;
- u8 rsvd_size;
- u8 rsvd_pos;
-};
-
-/* command line: \0 terminated string */
-#define ATAG_CMDLINE 0x54410009
-
-struct tag_cmdline {
- char cmdline[COMMAND_LINE_SIZE];
-};
-
-struct tag {
- struct tag_header hdr;
- union {
- struct tag_core core;
- struct tag_mem32 mem;
- struct tag_videotext videotext;
- struct tag_ramdisk ramdisk;
- struct tag_initrd initrd;
- struct tag_serialnr serialnr;
- struct tag_revision revision;
- struct tag_videolfb videolfb;
- struct tag_cmdline cmdline;
- } u;
-};
-
-struct tagtable {
- u32 tag;
- int (*parse)(const struct tag *);
-};
-
-#define tag_member_present(_tag, member) \
- typeof(_tag) (tag) = (_tag); \
- ((unsigned long)(&((struct tag *)0L)->member + 1) \
- <= (tag)->hdr.size * 4)
-
-#define tag_next(_t) \
- typeof(_t) (t) = (_t); \
- ((struct tag *)((u32 *)(t) + (t)->hdr.size))
-#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
-
-#define for_each_tag(_t, base) \
- typeof(_t) (t) = (_t); \
- for (t = base; t->hdr.size; t = tag_next(t))
-
-#ifdef __KERNEL__
-
-#define __tag __used __attribute__((__section__(".taglist")))
-#define __tagtable(tag, fn) \
-static struct tagtable __tagtable_##fn __tag = { tag, fn }
-
-/*
- * Memory map description
- */
-#define NR_BANKS 8
-
-struct meminfo {
- int nr_banks;
- struct {
- unsigned long start;
- unsigned long size;
- int node;
- } bank[NR_BANKS];
-};
-
-/*
- * Early command line parameters.
- */
-struct early_params {
- const char *arg;
- void (*fn)(char **p);
-};
-
-#define __early_param(name, fn) \
-static struct early_params __early_##fn __used \
-__attribute__((__section__("__early_param"))) = { name, fn }
-
-#endif
-#endif
diff --git a/arch/riscv/include/asm/u-boot.h b/arch/riscv/include/asm/u-boot.h
index 9e5b32d..3186835 100644
--- a/arch/riscv/include/asm/u-boot.h
+++ b/arch/riscv/include/asm/u-boot.h
@@ -23,7 +23,6 @@
#include <environment.h>
typedef struct bd_info {
- unsigned long bi_arch_number; /* unique id for this board */
unsigned long bi_boot_params; /* where this board expects params */
unsigned long bi_memstart; /* start of DRAM memory */
unsigned long bi_memsize; /* size of DRAM memory in bytes */
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index cc562f9..b58db89 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o
obj-$(CONFIG_CMD_GO) += boot.o
obj-y += cache.o
obj-y += interrupts.o
+obj-y += reset.o
obj-y += setjmp.o
# For building EFI apps
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index 2610a57..a7a9fb9 100644
--- a/arch/riscv/lib/bootm.c
+++ b/arch/riscv/lib/bootm.c
@@ -11,7 +11,7 @@
#include <image.h>
#include <u-boot/zlib.h>
#include <asm/byteorder.h>
-#include <asm/bootm.h>
+#include <asm/csr.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -26,10 +26,7 @@ int arch_fixup_fdt(void *blob)
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
{
- bd_t *bd = gd->bd;
- char *s;
- int machid = bd->bi_arch_number;
- void (*theKernel)(int arch, uint params);
+ void (*kernel)(ulong hart, void *dtb);
/*
* allow the PREP bootm subcommand, it is required for bootm to work
@@ -40,18 +37,12 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
return 1;
- theKernel = (void (*)(int, uint))images->ep;
-
- s = env_get("machid");
- if (s) {
- machid = simple_strtoul(s, NULL, 16);
- printf("Using machid 0x%x from environment\n", machid);
- }
+ kernel = (void (*)(ulong, void *))images->ep;
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
debug("## Transferring control to Linux (at address %08lx) ...\n",
- (ulong)theKernel);
+ (ulong)kernel);
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
#ifdef CONFIG_OF_LIBFDT
@@ -67,8 +58,9 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
printf("\nStarting kernel ...\n\n");
cleanup_before_linux();
+
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
- theKernel(machid, (unsigned long)images->ft_addr);
+ kernel(csr_read(mhartid), images->ft_addr);
/* does not return */
diff --git a/arch/riscv/lib/reset.c b/arch/riscv/lib/reset.c
new file mode 100644
index 0000000..b8cecb3
--- /dev/null
+++ b/arch/riscv/lib/reset.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+#include <command.h>
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ printf("resetting ...\n");
+
+ printf("reset not supported yet\n");
+ hang();
+
+ return 0;
+}
diff --git a/board/AndesTech/ax25-ae350/ax25-ae350.c b/board/AndesTech/ax25-ae350/ax25-ae350.c
index fd5aaa1..5f4ca0f 100644
--- a/board/AndesTech/ax25-ae350/ax25-ae350.c
+++ b/board/AndesTech/ax25-ae350/ax25-ae350.c
@@ -4,7 +4,6 @@
* Rick Chen, Andes Technology Corporation <rick@andestech.com>
*/
-#include <asm/mach-types.h>
#include <common.h>
#if defined(CONFIG_FTMAC100) && !defined(CONFIG_DM_ETH)
#include <netdev.h>
@@ -21,7 +20,6 @@ DECLARE_GLOBAL_DATA_PTR;
int board_init(void)
{
- gd->bd->bi_arch_number = MACH_TYPE_AE350;
gd->bd->bi_boot_params = PHYS_SDRAM_0 + 0x400;
return 0;
diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig
new file mode 100644
index 0000000..af23363
--- /dev/null
+++ b/board/emulation/qemu-riscv/Kconfig
@@ -0,0 +1,22 @@
+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
+ imply SYS_NS16550
+
+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
+
+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/cmd/bdinfo.c b/cmd/bdinfo.c
index 397dd15..60b4387 100644
--- a/cmd/bdinfo.c
+++ b/cmd/bdinfo.c
@@ -424,9 +424,10 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
bd_t *bd = gd->bd;
- print_num("arch_number", bd->bi_arch_number);
print_bi_boot_params(bd);
print_bi_dram(bd);
+ print_num("relocaddr", gd->relocaddr);
+ print_num("reloc off", gd->reloc_off);
print_eth_ip_addr();
print_baudrate();
diff --git a/configs/ax25-ae350_defconfig b/configs/ax25-ae350_defconfig
index d64f078..614ef15 100644
--- a/configs/ax25-ae350_defconfig
+++ b/configs/ax25-ae350_defconfig
@@ -15,30 +15,20 @@ CONFIG_CMD_SF_TEST=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
CONFIG_CMD_CACHE=y
-CONFIG_OF_CONTROL=y
CONFIG_OF_BOARD=y
CONFIG_DEFAULT_DEVICE_TREE="ae350"
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_DM=y
-CONFIG_CLK=y
CONFIG_MMC=y
-CONFIG_DM_MMC=y
CONFIG_FTSDC010=y
CONFIG_FTSDC010_SDIO=y
-CONFIG_MTD=y
CONFIG_MTD_NOR_FLASH=y
CONFIG_CFI_FLASH=y
-CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_DM_ETH=y
CONFIG_FTMAC100=y
CONFIG_BAUDRATE=38400
-CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
-CONFIG_DM_SPI=y
CONFIG_ATCSPI200_SPI=y
-CONFIG_TIMER=y
CONFIG_ATCPIT100_TIMER=y
diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-riscv32_defconfig
new file mode 100644
index 0000000..ff1fb1f
--- /dev/null
+++ b/configs/qemu-riscv32_defconfig
@@ -0,0 +1,6 @@
+CONFIG_RISCV=y
+CONFIG_TARGET_QEMU_VIRT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_OF_BOARD=y
diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-riscv64_defconfig
new file mode 100644
index 0000000..d6c1a5d
--- /dev/null
+++ b/configs/qemu-riscv64_defconfig
@@ -0,0 +1,7 @@
+CONFIG_RISCV=y
+CONFIG_TARGET_QEMU_VIRT=y
+CONFIG_CPU_RISCV_64=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_OF_BOARD=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 */