diff options
34 files changed, 538 insertions, 450 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 9b4bcbf2fd..c988c17f37 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 20a43d88e3..168ca3de7c 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 084888ad8b..8fb6a889d8 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 c0b3858edd..ed9eb0c24c 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 0000000000..2cc6757fcf --- /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 c3f164c122..2ab0342fe8 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 ab05b57d4f..fddcc156c3 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 0000000000..ae57fb8313 --- /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 0000000000..258e4620dd --- /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 0000000000..6c7a32755a --- /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 0000000000..84d87d2a7f --- /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 7cd7755190..7cd7755190 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 c50b9642f1..11bc4a738b 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 2927e4151b..4717ae88bc 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 67863458ec..0000000000 --- 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 0000000000..50fccea5c8 --- /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 f237a72f06..9ea50ce640 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 f219cedfd3..0000000000 --- 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 ff8de167c6..0000000000 --- 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 9e5b32d33e..3186835e0a 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 cc562f935a..b58db89752 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 2610a57bbf..a7a9fb921b 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 0000000000..b8cecb309d --- /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 fd5aaa1579..5f4ca0f5a7 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 0000000000..af23363fcf --- /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 0000000000..3c6eb4f844 --- /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 0000000000..3f29b90a41 --- /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 0000000000..041e716c9b --- /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 397dd1595b..60b438766d 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 d64f078481..614ef15dc7 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 0000000000..ff1fb1f30e --- /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 0000000000..d6c1a5d646 --- /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 0000000000..e2e4804917 --- /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 0000000000..d279c233b2 --- /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 */ |