Merge git://git.denx.de/u-boot-riscv

- QEMU support
lime2-spi
Tom Rini 6 years ago
commit 94228a9188
  1. 14
      arch/Kconfig
  2. 10
      arch/riscv/Kconfig
  3. 3
      arch/riscv/Makefile
  4. 12
      arch/riscv/config.mk
  5. 7
      arch/riscv/cpu/Makefile
  6. 2
      arch/riscv/cpu/ax25/Makefile
  7. 9
      arch/riscv/cpu/ax25/cpu.c
  8. 49
      arch/riscv/cpu/cpu.c
  9. 6
      arch/riscv/cpu/qemu/Makefile
  10. 21
      arch/riscv/cpu/qemu/cpu.c
  11. 17
      arch/riscv/cpu/qemu/dram.c
  12. 0
      arch/riscv/cpu/start.S
  13. 60
      arch/riscv/cpu/u-boot.lds
  14. 177
      arch/riscv/dts/ae350.dts
  15. 13
      arch/riscv/include/asm/bootm.h
  16. 124
      arch/riscv/include/asm/csr.h
  17. 50
      arch/riscv/include/asm/encoding.h
  18. 29
      arch/riscv/include/asm/mach-types.h
  19. 194
      arch/riscv/include/asm/setup.h
  20. 1
      arch/riscv/include/asm/u-boot.h
  21. 1
      arch/riscv/lib/Makefile
  22. 20
      arch/riscv/lib/bootm.c
  23. 17
      arch/riscv/lib/reset.c
  24. 2
      board/AndesTech/ax25-ae350/ax25-ae350.c
  25. 22
      board/emulation/qemu-riscv/Kconfig
  26. 7
      board/emulation/qemu-riscv/MAINTAINERS
  27. 5
      board/emulation/qemu-riscv/Makefile
  28. 23
      board/emulation/qemu-riscv/qemu-riscv.c
  29. 3
      cmd/bdinfo.c
  30. 10
      configs/ax25-ae350_defconfig
  31. 6
      configs/qemu-riscv32_defconfig
  32. 7
      configs/qemu-riscv64_defconfig
  33. 46
      doc/README.qemu-riscv
  34. 21
      include/configs/qemu-riscv.h

@ -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"

@ -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.

@ -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/

@ -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

@ -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

@ -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

@ -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");
}

@ -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;
}

@ -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

@ -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;
}

@ -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();
}

@ -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 = .;
}
}

@ -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>;

@ -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

@ -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 */

@ -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 */

@ -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 */

@ -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

@ -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 */

@ -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

@ -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 */

@ -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;
}

@ -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;

@ -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

@ -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

@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
obj-y += qemu-riscv.o

@ -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;
}

@ -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();

@ -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

@ -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

@ -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

@ -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.

@ -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 */
Loading…
Cancel
Save