Explorar o código

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

Tom Rini %!s(int64=5) %!d(string=hai) anos
pai
achega
ef0b75d3d8

+ 0 - 51
arch/nds32/cpu/n1213/start.S

@@ -200,14 +200,6 @@ update_gp:
 	jal	turnoff_watchdog
 #endif
 
-/*
- * Do CPU critical regs init only at reboot,
- * not when booting from ram
- */
-#ifdef CONFIG_INIT_CRITICAL
-	jal	cpu_init_crit		! Do CPU critical regs init
-#endif
-
 /*
  * Set stackpointer in internal RAM to call board_init_f
  * $sp must be 8-byte alignment for ABI compliance.
@@ -318,49 +310,6 @@ call_board_init_r:
 	/* jump to it ... */
 	jr	$lp			/* jump to board_init_r() */
 
-/*
- * Initialize CPU critical registers
- *
- *	1.	Setup control registers
- *		1.1 Mask all IRQs
- *		1.2 Flush cache and TLB
- *		1.3 Disable MMU and cache
- *	2.	Setup memory timing
- */
-
-cpu_init_crit:
-
-	move	$r0, $lp		/* push	ra */
-
-	/* Disable Interrupts by clear GIE in $PSW reg */
-	setgie.d
-
-	/* Flush caches and TLB */
-	/* Invalidate caches */
-	jal	invalidate_icac
-	jal	invalidate_dcac
-
-	/* Flush TLB */
-	mfsr	$p0, $MMU_CFG
-	andi	$p0, $p0, 0x3			! MMPS
-	li	$p1, 0x2			! TLB MMU
-	bne	$p0, $p1, 1f
-	tlbop	flushall			! Flush TLB
-
-1:
-	! Disable MMU, Dcache
-	! Whitiger is MMU disabled when reset
-	! Disable the D$
-	mfsr	$p0, MR_CAC_CTL			! Get the $CACHE_CTL reg
-	li	$p1, DIS_DCAC
-	and	$p0, $p0, $p1			! Set DC_EN bit
-	mtsr	$p0, MR_CAC_CTL			! write back the $CACHE_CTL reg
-	isb
-
-	move	$lp, $r0
-2:
-	ret
-
 /*
  * Invalidate I$
  */

+ 26 - 8
arch/riscv/Kconfig

@@ -16,27 +16,45 @@ config TARGET_QEMU_VIRT
 
 endchoice
 
+# board-specific options below
 source "board/AndesTech/ax25-ae350/Kconfig"
 source "board/emulation/qemu-riscv/Kconfig"
 
+# platform-specific options below
+source "arch/riscv/cpu/ax25/Kconfig"
+
+# architecture-specific options below
+
 choice
-	prompt "CPU selection"
-	default CPU_RISCV_32
+	prompt "Base ISA"
+	default ARCH_RV32I
 
-config CPU_RISCV_32
-	bool "RISC-V 32-bit"
+config ARCH_RV32I
+	bool "RV32I"
 	select 32BIT
 	help
-	  Choose this option to build an U-Boot for RISCV32 architecture.
+	  Choose this option to target the RV32I base integer instruction set.
 
-config CPU_RISCV_64
-	bool "RISC-V 64-bit"
+config ARCH_RV64I
+	bool "RV64I"
 	select 64BIT
+	select PHYS_64BIT
 	help
-	  Choose this option to build an U-Boot for RISCV64 architecture.
+	  Choose this option to target the RV64I base integer instruction set.
 
 endchoice
 
+config RISCV_ISA_C
+	bool "Emit compressed instructions"
+	default y
+	help
+	  Adds "C" to the ISA subsets that the toolchain is allowed to emit
+	  when building U-Boot, which results in compressed instructions in the
+	  U-Boot binary.
+
+config RISCV_ISA_A
+	def_bool y
+
 config 32BIT
 	bool
 

+ 20 - 0
arch/riscv/Makefile

@@ -3,6 +3,26 @@
 # Copyright (C) 2017 Andes Technology Corporation.
 # Rick Chen, Andes Technology Corporation <rick@andestech.com>
 
+ifeq ($(CONFIG_ARCH_RV64I),y)
+	ARCH_BASE = rv64im
+	ABI = lp64
+endif
+ifeq ($(CONFIG_ARCH_RV32I),y)
+	ARCH_BASE = rv32im
+	ABI = ilp32
+endif
+ifeq ($(CONFIG_RISCV_ISA_A),y)
+	ARCH_A = a
+endif
+ifeq ($(CONFIG_RISCV_ISA_C),y)
+	ARCH_C = c
+endif
+
+ARCH_FLAGS = -march=$(ARCH_BASE)$(ARCH_A)$(ARCH_C) -mabi=$(ABI)
+
+PLATFORM_CPPFLAGS	+= $(ARCH_FLAGS)
+CFLAGS_EFI		+= $(ARCH_FLAGS)
+
 head-y := arch/riscv/cpu/start.o
 
 libs-y += arch/riscv/cpu/

+ 2 - 5
arch/riscv/config.mk

@@ -14,16 +14,12 @@
 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,7 +27,8 @@ CONFIG_STANDALONE_LOAD_ADDR = 0x00000000
 LDFLAGS_STANDALONE += -T $(srctree)/examples/standalone/riscv.lds
 
 PLATFORM_CPPFLAGS	+= -ffixed-gp -fpic
-PLATFORM_RELFLAGS	+= -fno-common -gdwarf-2 -ffunction-sections
+PLATFORM_RELFLAGS	+= -fno-common -gdwarf-2 -ffunction-sections \
+			   -fdata-sections
 LDFLAGS_u-boot		+= --gc-sections -static -pie
 
 EFI_CRT0		:= crt0_riscv_efi.o

+ 7 - 0
arch/riscv/cpu/ax25/Kconfig

@@ -0,0 +1,7 @@
+config RISCV_NDS
+	bool "AndeStar V5 ISA support"
+	default n
+	help
+		Say Y here if you plan to run U-Boot on AndeStar v5
+		platforms and use some specific features which are
+		provided by Andes Technology AndeStar V5 Families.

+ 1 - 0
arch/riscv/cpu/ax25/Makefile

@@ -4,3 +4,4 @@
 # Rick Chen, Andes Technology Corporation <rick@andestech.com>
 
 obj-y	:= cpu.o
+obj-y	+= cache.o

+ 95 - 0
arch/riscv/cpu/ax25/cache.c

@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017 Andes Technology Corporation
+ * Rick Chen, Andes Technology Corporation <rick@andestech.com>
+ */
+
+#include <common.h>
+
+void icache_enable(void)
+{
+#ifndef CONFIG_SYS_ICACHE_OFF
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"csrr t1, mcache_ctl\n\t"
+		"ori t0, t1, 0x1\n\t"
+		"csrw mcache_ctl, t0\n\t"
+	);
+#endif
+#endif
+}
+
+void icache_disable(void)
+{
+#ifndef CONFIG_SYS_ICACHE_OFF
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"fence.i\n\t"
+		"csrr t1, mcache_ctl\n\t"
+		"andi t0, t1, ~0x1\n\t"
+		"csrw mcache_ctl, t0\n\t"
+	);
+#endif
+#endif
+}
+
+void dcache_enable(void)
+{
+#ifndef CONFIG_SYS_DCACHE_OFF
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"csrr t1, mcache_ctl\n\t"
+		"ori t0, t1, 0x2\n\t"
+		"csrw mcache_ctl, t0\n\t"
+	);
+#endif
+#endif
+}
+
+void dcache_disable(void)
+{
+#ifndef CONFIG_SYS_DCACHE_OFF
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"fence\n\t"
+		"csrr t1, mcache_ctl\n\t"
+		"andi t0, t1, ~0x2\n\t"
+		"csrw mcache_ctl, t0\n\t"
+	);
+#endif
+#endif
+}
+
+int icache_status(void)
+{
+	int ret = 0;
+
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"csrr t1, mcache_ctl\n\t"
+		"andi	%0, t1, 0x01\n\t"
+		: "=r" (ret)
+		:
+		: "memory"
+	);
+#endif
+
+	return ret;
+}
+
+int dcache_status(void)
+{
+	int ret = 0;
+
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"csrr t1, mcache_ctl\n\t"
+		"andi	%0, t1, 0x02\n\t"
+		: "=r" (ret)
+		:
+		: "memory"
+	);
+#endif
+
+	return ret;
+}

+ 4 - 0
arch/riscv/cpu/ax25/cpu.c

@@ -6,6 +6,7 @@
 
 /* CPU specific code */
 #include <common.h>
+#include <asm/cache.h>
 
 /*
  * cleanup_before_linux() is called just before we call linux
@@ -18,6 +19,9 @@ int cleanup_before_linux(void)
 	disable_interrupts();
 
 	/* turn off I/D-cache */
+	cache_flush();
+	icache_disable();
+	dcache_disable();
 
 	return 0;
 }

+ 6 - 0
arch/riscv/cpu/cpu.c

@@ -6,6 +6,12 @@
 #include <common.h>
 #include <asm/csr.h>
 
+/*
+ * prior_stage_fdt_address must be stored in the data section since it is used
+ * before the bss section is available.
+ */
+phys_addr_t prior_stage_fdt_address __attribute__((section(".data")));
+
 enum {
 	ISA_INVALID = 0,
 	ISA_32BIT,

+ 1 - 1
arch/riscv/cpu/qemu/cpu.c

@@ -15,7 +15,7 @@ int cleanup_before_linux(void)
 {
 	disable_interrupts();
 
-	/* turn off I/D-cache */
+	cache_flush();
 
 	return 0;
 }

+ 169 - 177
arch/riscv/cpu/start.S

@@ -16,56 +16,47 @@
 #include <asm/encoding.h>
 
 #ifdef CONFIG_32BIT
-#define LREG 			lw
-#define SREG 			sw
-#define REGBYTES 		4
+#define LREG			lw
+#define SREG			sw
+#define REGBYTES		4
 #define RELOC_TYPE		R_RISCV_32
 #define SYM_INDEX		0x8
 #define SYM_SIZE		0x10
 #else
-#define LREG 			ld
-#define SREG 			sd
-#define REGBYTES 		8
+#define LREG			ld
+#define SREG			sd
+#define REGBYTES		8
 #define RELOC_TYPE		R_RISCV_64
 #define SYM_INDEX		0x20
 #define SYM_SIZE		0x18
 #endif
 
-.section      .text
+.section .text
 .globl _start
 _start:
-	j handle_reset
+	/* save hart id and dtb pointer */
+	mv	s0, a0
+	mv	s1, a1
 
-nmi_vector:
-	j nmi_vector
+	li	t0, CONFIG_SYS_SDRAM_BASE
+	SREG	a2, 0(t0)
+	la	t0, trap_entry
+	csrw	mtvec, t0
 
-trap_vector:
-	j trap_entry
+	/* mask all interrupts */
+	csrw	mie, zero
 
-.global trap_entry
-handle_reset:
-	li t0, CONFIG_SYS_SDRAM_BASE
-	SREG a2, 0(t0)
-	la t0, trap_entry
-	csrw mtvec, t0
-	csrwi mstatus, 0
-	csrwi mie, 0
-
-/*
- * Do CPU critical regs init only at reboot,
- * not when booting from ram
- */
-#ifdef CONFIG_INIT_CRITICAL
-	jal cpu_init_crit	/* Do CPU critical regs init */
-#endif
+	/* Enable cache */
+	jal	icache_enable
+	jal	dcache_enable
 
 /*
  * Set stackpointer in internal/ex RAM to call board_init_f
  */
 call_board_init_f:
-	li  t0, -16
-	li  t1, CONFIG_SYS_INIT_SP_ADDR
-	and sp, t1, t0	/* force 16 byte alignment */
+	li	t0, -16
+	li	t1, CONFIG_SYS_INIT_SP_ADDR
+	and	sp, t1, t0		/* force 16 byte alignment */
 
 #ifdef CONFIG_DEBUG_UART
 	jal	debug_uart_init
@@ -75,11 +66,15 @@ call_board_init_f_0:
 	mv	a0, sp
 	jal	board_init_f_alloc_reserve
 	mv	sp, a0
+
+	la	t0, prior_stage_fdt_address
+	SREG	s1, 0(t0)
+
 	jal	board_init_f_init_reserve
 
-	mv  a0, zero	/* a0 <-- boot_flags = 0 */
-	la t5, board_init_f
-	jr t5		/* jump to board_init_f() */
+	mv	a0, zero		/* a0 <-- boot_flags = 0 */
+	la	t5, board_init_f
+	jr	t5			/* jump to board_init_f() */
 
 /*
  * void relocate_code (addr_sp, gd, addr_moni)
@@ -90,203 +85,200 @@ call_board_init_f_0:
  */
 .globl relocate_code
 relocate_code:
-	mv  s2, a0	/* save addr_sp */
-	mv  s3, a1	/* save addr of gd */
-	mv  s4, a2	/* save addr of destination */
+	mv	s2, a0			/* save addr_sp */
+	mv	s3, a1			/* save addr of gd */
+	mv	s4, a2			/* save addr of destination */
 
 /*
  *Set up the stack
  */
 stack_setup:
-	mv sp, s2
-	la t0, _start
-	sub t6, s4, t0	/* t6 <- relocation offset */
-	beq t0, s4, clear_bss	/* skip relocation */
+	mv	sp, s2
+	la	t0, _start
+	sub	t6, s4, t0		/* t6 <- relocation offset */
+	beq	t0, s4, clear_bss	/* skip relocation */
 
-	mv t1, s4	/* t1 <- scratch for copy_loop */
-	la t3, __bss_start
-	sub t3, t3, t0	/* t3 <- __bss_start_ofs */
-	add t2, t0, t3	/* t2 <- source end address */
+	mv	t1, s4			/* t1 <- scratch for copy_loop */
+	la	t3, __bss_start
+	sub	t3, t3, t0		/* t3 <- __bss_start_ofs */
+	add	t2, t0, t3		/* t2 <- source end address */
 
 copy_loop:
-	LREG t5, 0(t0)
-	addi t0, t0, REGBYTES
-	SREG t5, 0(t1)
-	addi t1, t1, REGBYTES
-	blt t0, t2, copy_loop
+	LREG	t5, 0(t0)
+	addi	t0, t0, REGBYTES
+	SREG	t5, 0(t1)
+	addi	t1, t1, REGBYTES
+	blt	t0, t2, copy_loop
 
 /*
  * Update dynamic relocations after board_init_f
  */
 fix_rela_dyn:
-	la  t1, __rel_dyn_start
-	la  t2, __rel_dyn_end
-	beq t1, t2, clear_bss
-	add t1, t1, t6			/* t1 <- rela_dyn_start in RAM */
-	add t2, t2, t6			/* t2 <- rela_dyn_end in RAM */
+	la	t1, __rel_dyn_start
+	la	t2, __rel_dyn_end
+	beq	t1, t2, clear_bss
+	add	t1, t1, t6		/* t1 <- rela_dyn_start in RAM */
+	add	t2, t2, t6		/* t2 <- rela_dyn_end in RAM */
 
 /*
  * skip first reserved entry: address, type, addend
  */
-	bne t1, t2, 7f
+	bne	t1, t2, 7f
 
 6:
-	LREG  t5, -(REGBYTES*2)(t1)	/* t5 <-- relocation info:type */
-	li  t3, R_RISCV_RELATIVE	/* reloc type R_RISCV_RELATIVE */
-	bne t5, t3, 8f			/* skip non-RISCV_RELOC entries */
-	LREG t3, -(REGBYTES*3)(t1)
-	LREG t5, -(REGBYTES)(t1)	/* t5 <-- addend */
-	add t5, t5, t6			/* t5 <-- location to fix up in RAM */
-	add t3, t3, t6			/* t3 <-- location to fix up in RAM */
-	SREG t5, 0(t3)
+	LREG	t5, -(REGBYTES*2)(t1)	/* t5 <-- relocation info:type */
+	li	t3, R_RISCV_RELATIVE	/* reloc type R_RISCV_RELATIVE */
+	bne	t5, t3, 8f		/* skip non-RISCV_RELOC entries */
+	LREG	t3, -(REGBYTES*3)(t1)
+	LREG	t5, -(REGBYTES)(t1)	/* t5 <-- addend */
+	add	t5, t5, t6		/* t5 <-- location to fix up in RAM */
+	add	t3, t3, t6		/* t3 <-- location to fix up in RAM */
+	SREG	t5, 0(t3)
 7:
-	addi t1, t1, (REGBYTES*3)
-	ble t1, t2, 6b
+	addi	t1, t1, (REGBYTES*3)
+	ble	t1, t2, 6b
 
 8:
-	la  t4, __dyn_sym_start
-	add t4, t4, t6
+	la	t4, __dyn_sym_start
+	add	t4, t4, t6
 
 9:
-	LREG  t5, -(REGBYTES*2)(t1)	/* t5 <-- relocation info:type */
-	srli t0, t5, SYM_INDEX		/* t0 <--- sym table index */
-	andi t5, t5, 0xFF		/* t5 <--- relocation type */
-	li  t3, RELOC_TYPE
-	bne t5, t3, 10f 		/* skip non-addned entries */
+	LREG	t5, -(REGBYTES*2)(t1)	/* t5 <-- relocation info:type */
+	srli	t0, t5, SYM_INDEX	/* t0 <--- sym table index */
+	andi	t5, t5, 0xFF		/* t5 <--- relocation type */
+	li	t3, RELOC_TYPE
+	bne	t5, t3, 10f		/* skip non-addned entries */
 
-	LREG t3, -(REGBYTES*3)(t1)
-	li t5, SYM_SIZE
-	mul t0, t0, t5
-	add s1, t4, t0
-	LREG t5, REGBYTES(s1)
-	add t5, t5, t6			/* t5 <-- location to fix up in RAM */
-	add t3, t3, t6			/* t3 <-- location to fix up in RAM */
-	SREG t5, 0(t3)
+	LREG	t3, -(REGBYTES*3)(t1)
+	li	t5, SYM_SIZE
+	mul	t0, t0, t5
+	add	s5, t4, t0
+	LREG	t5, REGBYTES(s5)
+	add	t5, t5, t6		/* t5 <-- location to fix up in RAM */
+	add	t3, t3, t6		/* t3 <-- location to fix up in RAM */
+	SREG	t5, 0(t3)
 10:
-	addi t1, t1, (REGBYTES*3)
-	ble t1, t2, 9b
+	addi	t1, t1, (REGBYTES*3)
+	ble	t1, t2, 9b
 
 /*
  * trap update
 */
-	la t0, trap_entry
-	add t0, t0, t6
-	csrw mtvec, t0
+	la	t0, trap_entry
+	add	t0, t0, t6
+	csrw	mtvec, t0
 
 clear_bss:
-	la t0, __bss_start		/* t0 <- rel __bss_start in FLASH */
-	add t0, t0, t6			/* t0 <- rel __bss_start in RAM */
-	la t1, __bss_end		/* t1 <- rel __bss_end in FLASH */
-	add t1, t1, t6			/* t1 <- rel __bss_end in RAM */
-	li t2, 0x00000000		/* clear */
-	beq t0, t1, call_board_init_r
+	la	t0, __bss_start		/* t0 <- rel __bss_start in FLASH */
+	add	t0, t0, t6		/* t0 <- rel __bss_start in RAM */
+	la	t1, __bss_end		/* t1 <- rel __bss_end in FLASH */
+	add	t1, t1, t6		/* t1 <- rel __bss_end in RAM */
+	beq	t0, t1, call_board_init_r
 
 clbss_l:
-	SREG t2, 0(t0)			/* clear loop... */
-	addi t0, t0, REGBYTES
-	bne t0, t1, clbss_l
+	SREG	zero, 0(t0)		/* clear loop... */
+	addi	t0, t0, REGBYTES
+	bne	t0, t1, clbss_l
 
 /*
  * We are done. Do not return, instead branch to second part of board
  * initialization, now running from RAM.
  */
 call_board_init_r:
-	la t0, board_init_r
-	mv t4, t0			/* offset of board_init_r() */
-	add t4, t4, t6			/* real address of board_init_r() */
+	jal	invalidate_icache_all
+	jal	flush_dcache_all
+	la	t0, board_init_r
+	mv	t4, t0			/* offset of board_init_r() */
+	add	t4, t4, t6		/* real address of board_init_r() */
 /*
  * setup parameters for board_init_r
  */
-	mv a0, s3			/* gd_t */
-	mv a1, s4			/* dest_addr */
+	mv	a0, s3			/* gd_t */
+	mv	a1, s4			/* dest_addr */
 
 /*
  * jump to it ...
  */
-	jr t4				/* jump to board_init_r() */
+	jr	t4			/* jump to board_init_r() */
 
 /*
  * trap entry
  */
+.align 2
 trap_entry:
-	addi sp, sp, -32*REGBYTES
-	SREG x1, 1*REGBYTES(sp)
-	SREG x2, 2*REGBYTES(sp)
-	SREG x3, 3*REGBYTES(sp)
-	SREG x4, 4*REGBYTES(sp)
-	SREG x5, 5*REGBYTES(sp)
-	SREG x6, 6*REGBYTES(sp)
-	SREG x7, 7*REGBYTES(sp)
-	SREG x8, 8*REGBYTES(sp)
-	SREG x9, 9*REGBYTES(sp)
-	SREG x10, 10*REGBYTES(sp)
-	SREG x11, 11*REGBYTES(sp)
-	SREG x12, 12*REGBYTES(sp)
-	SREG x13, 13*REGBYTES(sp)
-	SREG x14, 14*REGBYTES(sp)
-	SREG x15, 15*REGBYTES(sp)
-	SREG x16, 16*REGBYTES(sp)
-	SREG x17, 17*REGBYTES(sp)
-	SREG x18, 18*REGBYTES(sp)
-	SREG x19, 19*REGBYTES(sp)
-	SREG x20, 20*REGBYTES(sp)
-	SREG x21, 21*REGBYTES(sp)
-	SREG x22, 22*REGBYTES(sp)
-	SREG x23, 23*REGBYTES(sp)
-	SREG x24, 24*REGBYTES(sp)
-	SREG x25, 25*REGBYTES(sp)
-	SREG x26, 26*REGBYTES(sp)
-	SREG x27, 27*REGBYTES(sp)
-	SREG x28, 28*REGBYTES(sp)
-	SREG x29, 29*REGBYTES(sp)
-	SREG x30, 30*REGBYTES(sp)
-	SREG x31, 31*REGBYTES(sp)
-	csrr a0, mcause
-	csrr a1, mepc
-	mv a2, sp
-	jal handle_trap
-	csrw mepc, a0
+	addi	sp, sp, -32*REGBYTES
+	SREG	x1, 1*REGBYTES(sp)
+	SREG	x2, 2*REGBYTES(sp)
+	SREG	x3, 3*REGBYTES(sp)
+	SREG	x4, 4*REGBYTES(sp)
+	SREG	x5, 5*REGBYTES(sp)
+	SREG	x6, 6*REGBYTES(sp)
+	SREG	x7, 7*REGBYTES(sp)
+	SREG	x8, 8*REGBYTES(sp)
+	SREG	x9, 9*REGBYTES(sp)
+	SREG	x10, 10*REGBYTES(sp)
+	SREG	x11, 11*REGBYTES(sp)
+	SREG	x12, 12*REGBYTES(sp)
+	SREG	x13, 13*REGBYTES(sp)
+	SREG	x14, 14*REGBYTES(sp)
+	SREG	x15, 15*REGBYTES(sp)
+	SREG	x16, 16*REGBYTES(sp)
+	SREG	x17, 17*REGBYTES(sp)
+	SREG	x18, 18*REGBYTES(sp)
+	SREG	x19, 19*REGBYTES(sp)
+	SREG	x20, 20*REGBYTES(sp)
+	SREG	x21, 21*REGBYTES(sp)
+	SREG	x22, 22*REGBYTES(sp)
+	SREG	x23, 23*REGBYTES(sp)
+	SREG	x24, 24*REGBYTES(sp)
+	SREG	x25, 25*REGBYTES(sp)
+	SREG	x26, 26*REGBYTES(sp)
+	SREG	x27, 27*REGBYTES(sp)
+	SREG	x28, 28*REGBYTES(sp)
+	SREG	x29, 29*REGBYTES(sp)
+	SREG	x30, 30*REGBYTES(sp)
+	SREG	x31, 31*REGBYTES(sp)
+	csrr	a0, mcause
+	csrr	a1, mepc
+	mv	a2, sp
+	jal	handle_trap
+	csrw	mepc, a0
 
 /*
  * Remain in M-mode after mret
  */
-	li t0, MSTATUS_MPP
-	csrs mstatus, t0
-	LREG x1, 1*REGBYTES(sp)
-	LREG x2, 2*REGBYTES(sp)
-	LREG x3, 3*REGBYTES(sp)
-	LREG x4, 4*REGBYTES(sp)
-	LREG x5, 5*REGBYTES(sp)
-	LREG x6, 6*REGBYTES(sp)
-	LREG x7, 7*REGBYTES(sp)
-	LREG x8, 8*REGBYTES(sp)
-	LREG x9, 9*REGBYTES(sp)
-	LREG x10, 10*REGBYTES(sp)
-	LREG x11, 11*REGBYTES(sp)
-	LREG x12, 12*REGBYTES(sp)
-	LREG x13, 13*REGBYTES(sp)
-	LREG x14, 14*REGBYTES(sp)
-	LREG x15, 15*REGBYTES(sp)
-	LREG x16, 16*REGBYTES(sp)
-	LREG x17, 17*REGBYTES(sp)
-	LREG x18, 18*REGBYTES(sp)
-	LREG x19, 19*REGBYTES(sp)
-	LREG x20, 20*REGBYTES(sp)
-	LREG x21, 21*REGBYTES(sp)
-	LREG x22, 22*REGBYTES(sp)
-	LREG x23, 23*REGBYTES(sp)
-	LREG x24, 24*REGBYTES(sp)
-	LREG x25, 25*REGBYTES(sp)
-	LREG x26, 26*REGBYTES(sp)
-	LREG x27, 27*REGBYTES(sp)
-	LREG x28, 28*REGBYTES(sp)
-	LREG x29, 29*REGBYTES(sp)
-	LREG x30, 30*REGBYTES(sp)
-	LREG x31, 31*REGBYTES(sp)
-	addi sp, sp, 32*REGBYTES
+	li	t0, MSTATUS_MPP
+	csrs	mstatus, t0
+	LREG	x1, 1*REGBYTES(sp)
+	LREG	x2, 2*REGBYTES(sp)
+	LREG	x3, 3*REGBYTES(sp)
+	LREG	x4, 4*REGBYTES(sp)
+	LREG	x5, 5*REGBYTES(sp)
+	LREG	x6, 6*REGBYTES(sp)
+	LREG	x7, 7*REGBYTES(sp)
+	LREG	x8, 8*REGBYTES(sp)
+	LREG	x9, 9*REGBYTES(sp)
+	LREG	x10, 10*REGBYTES(sp)
+	LREG	x11, 11*REGBYTES(sp)
+	LREG	x12, 12*REGBYTES(sp)
+	LREG	x13, 13*REGBYTES(sp)
+	LREG	x14, 14*REGBYTES(sp)
+	LREG	x15, 15*REGBYTES(sp)
+	LREG	x16, 16*REGBYTES(sp)
+	LREG	x17, 17*REGBYTES(sp)
+	LREG	x18, 18*REGBYTES(sp)
+	LREG	x19, 19*REGBYTES(sp)
+	LREG	x20, 20*REGBYTES(sp)
+	LREG	x21, 21*REGBYTES(sp)
+	LREG	x22, 22*REGBYTES(sp)
+	LREG	x23, 23*REGBYTES(sp)
+	LREG	x24, 24*REGBYTES(sp)
+	LREG	x25, 25*REGBYTES(sp)
+	LREG	x26, 26*REGBYTES(sp)
+	LREG	x27, 27*REGBYTES(sp)
+	LREG	x28, 28*REGBYTES(sp)
+	LREG	x29, 29*REGBYTES(sp)
+	LREG	x30, 30*REGBYTES(sp)
+	LREG	x31, 31*REGBYTES(sp)
+	addi	sp, sp, 32*REGBYTES
 	mret
-
-#ifdef CONFIG_INIT_CRITICAL
-cpu_init_crit:
-    ret
-#endif

+ 0 - 1
arch/riscv/dts/Makefile

@@ -1,6 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0+
 
-dtb-$(CONFIG_TARGET_AX25_AE350) += ae350.dtb
 targets += $(dtb-y)
 
 DTC_FLAGS += -R 4 -p 0x1000

+ 92 - 15
arch/riscv/dts/ae350.dts

@@ -12,15 +12,14 @@
 	};
 
 	chosen {
-		bootargs = "console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0xf0300000 debug loglevel=7";
+		bootargs = "console=ttyS0,38400n8  debug loglevel=7";
 		stdout-path = "uart0:38400n8";
 	};
 
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
-		timebase-frequency = <10000000>;
-
+		timebase-frequency = <60000000>;
 		CPU0: cpu@0 {
 			device_type = "cpu";
 			reg = <0>;
@@ -29,7 +28,8 @@
 			riscv,isa = "rv64imafdc";
 			mmu-type = "riscv,sv39";
 			clock-frequency = <60000000>;
-
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <32>;
 			CPU0_intc: interrupt-controller {
 				#interrupt-cells = <1>;
 				interrupt-controller;
@@ -48,13 +48,6 @@
 		#size-cells = <2>;
 		compatible = "andestech,riscv-ae350-soc";
 		ranges;
-	};
-
-	plmt0@e6000000 {
-		compatible = "riscv,plmt0";
-		interrupts-extended = <&CPU0_intc 7>;
-		reg = <0x0 0xe6000000 0x0 0x100000>;
-	};
 
 	plic0: interrupt-controller@e4000000 {
 		compatible = "riscv,plic0";
@@ -62,7 +55,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		reg = <0x0 0xe4000000 0x0 0x2000000>;
-		riscv,ndev=<31>;
+		riscv,ndev=<71>;
 		interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
 	};
 
@@ -76,6 +69,13 @@
 		interrupts-extended = <&CPU0_intc 3>;
 	};
 
+	plmt0@e6000000 {
+		compatible = "riscv,plmt0";
+			interrupts-extended = <&CPU0_intc 7>;
+			reg = <0x0 0xe6000000 0x0 0x100000>;
+		};
+	};
+
 	spiclk: virt_100mhz {
 		#clock-cells = <0>;
 		compatible = "fixed-clock";
@@ -85,7 +85,7 @@
 	timer0: timer@f0400000 {
 		compatible = "andestech,atcpit100";
 		reg = <0x0 0xf0400000 0x0 0x1000>;
-		clock-frequency = <40000000>;
+		clock-frequency = <60000000>;
 		interrupts = <3 4>;
 		interrupt-parent = <&plic0>;
 	};
@@ -119,11 +119,89 @@
 		interrupt-parent = <&plic0>;
 	};
 
+	dma0: dma@f0c00000 {
+		compatible = "andestech,atcdmac300";
+		reg = <0x0 0xf0c00000 0x0 0x1000>;
+		interrupts = <10 4 64 4 65 4 66 4 67 4 68 4 69 4 70 4 71 4>;
+		dma-channels = <8>;
+		interrupt-parent = <&plic0>;
+	};
+
+	lcd0: lcd@e0200000 {
+		compatible = "andestech,atflcdc100";
+		reg = <0x0 0xe0200000 0x0 0x1000>;
+		interrupts = <20 4>;
+		interrupt-parent = <&plic0>;
+	};
+
 	smc0: smc@e0400000 {
 		compatible = "andestech,atfsmc020";
 		reg = <0x0 0xe0400000 0x0 0x1000>;
 	};
 
+	snd0: snd@f0d00000 {
+		compatible = "andestech,atfac97";
+		reg = <0x0 0xf0d00000 0x0 0x1000>;
+		interrupts = <17 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	virtio_mmio@fe007000 {
+		interrupts = <0x17 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe007000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe006000 {
+		interrupts = <0x16 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe006000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe005000 {
+		interrupts = <0x15 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe005000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe004000 {
+		interrupts = <0x14 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe004000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe003000 {
+		interrupts = <0x13 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe003000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe002000 {
+		interrupts = <0x12 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe002000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe001000 {
+		interrupts = <0x11 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe001000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe000000 {
+		interrupts = <0x10 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe000000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
 	nor@0,0 {
 		compatible = "cfi-flash";
 		reg = <0x0 0x88000000 0x0 0x1000>;
@@ -138,9 +216,8 @@
 		#size-cells = <0>;
 		num-cs = <1>;
 		clocks = <&spiclk>;
-		interrupts = <3 4>;
+		interrupts = <4 4>;
 		interrupt-parent = <&plic0>;
-
 		flash@0 {
 			compatible = "spi-flash";
 			spi-max-frequency = <50000000>;

+ 229 - 0
arch/riscv/dts/ae350_32.dts

@@ -0,0 +1,229 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "andestech,a25";
+	model = "andestech,a25";
+
+	aliases {
+		uart0 = &serial0;
+		spi0 = &spi;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,38400n8  debug loglevel=7";
+		stdout-path = "uart0:38400n8";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		timebase-frequency = <60000000>;
+		CPU0: cpu@0 {
+			device_type = "cpu";
+			reg = <0>;
+			status = "okay";
+			compatible = "riscv";
+			riscv,isa = "rv32imafdc";
+			mmu-type = "riscv,sv32";
+			clock-frequency = <60000000>;
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <32>;
+			CPU0_intc: interrupt-controller {
+				#interrupt-cells = <1>;
+				interrupt-controller;
+				compatible = "riscv,cpu-intc";
+			};
+		};
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x00000000 0x40000000>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "andestech,riscv-ae350-soc";
+		ranges;
+
+	plic0: interrupt-controller@e4000000 {
+		compatible = "riscv,plic0";
+		#address-cells = <1>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		reg = <0xe4000000 0x2000000>;
+		riscv,ndev=<71>;
+		interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
+	};
+
+	plic1: interrupt-controller@e6400000 {
+		compatible = "riscv,plic1";
+		#address-cells = <1>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		reg = <0xe6400000 0x400000>;
+		riscv,ndev=<1>;
+		interrupts-extended = <&CPU0_intc 3>;
+	};
+
+	plmt0@e6000000 {
+		compatible = "riscv,plmt0";
+			interrupts-extended = <&CPU0_intc 7>;
+			reg = <0xe6000000 0x100000>;
+		};
+	};
+
+	spiclk: virt_100mhz {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <100000000>;
+	};
+
+	timer0: timer@f0400000 {
+		compatible = "andestech,atcpit100";
+		reg = <0xf0400000 0x1000>;
+		clock-frequency = <60000000>;
+		interrupts = <3 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	serial0: serial@f0300000 {
+		compatible = "andestech,uart16550", "ns16550a";
+		reg = <0xf0300000 0x1000>;
+		interrupts = <9 4>;
+		clock-frequency = <19660800>;
+		reg-shift = <2>;
+		reg-offset = <32>;
+		no-loopback-test = <1>;
+		interrupt-parent = <&plic0>;
+	};
+
+	mac0: mac@e0100000 {
+		compatible = "andestech,atmac100";
+		reg = <0xe0100000 0x1000>;
+		interrupts = <19 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	mmc0: mmc@f0e00000 {
+		compatible = "andestech,atfsdc010";
+		max-frequency = <100000000>;
+		clock-freq-min-max = <400000 100000000>;
+		fifo-depth = <0x10>;
+		reg = <0xf0e00000 0x1000>;
+		interrupts = <18 4>;
+		cap-sd-highspeed;
+		interrupt-parent = <&plic0>;
+	};
+
+	dma0: dma@f0c00000 {
+		compatible = "andestech,atcdmac300";
+		reg = <0xf0c00000 0x1000>;
+		interrupts = <10 4 64 4 65 4 66 4 67 4 68 4 69 4 70 4 71 4>;
+		dma-channels = <8>;
+		interrupt-parent = <&plic0>;
+	};
+
+	lcd0: lcd@e0200000 {
+		compatible = "andestech,atflcdc100";
+		reg = <0xe0200000 0x1000>;
+		interrupts = <20 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	smc0: smc@e0400000 {
+		compatible = "andestech,atfsmc020";
+		reg = <0xe0400000 0x1000>;
+	};
+
+	snd0: snd@f0d00000 {
+		compatible = "andestech,atfac97";
+		reg = <0xf0d00000 0x1000>;
+		interrupts = <17 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	virtio_mmio@fe007000 {
+		interrupts = <0x17 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe007000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe006000 {
+		interrupts = <0x16 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe006000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe005000 {
+		interrupts = <0x15 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe005000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe004000 {
+		interrupts = <0x14 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe004000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe003000 {
+		interrupts = <0x13 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe003000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe002000 {
+		interrupts = <0x12 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe002000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe001000 {
+		interrupts = <0x11 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe001000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe000000 {
+		interrupts = <0x10 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0xfe000000 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	nor@0,0 {
+		compatible = "cfi-flash";
+		reg = <0x88000000 0x1000>;
+		bank-width = <2>;
+		device-width = <1>;
+	};
+
+	spi: spi@f0b00000 {
+		compatible = "andestech,atcspi200";
+		reg = <0xf0b00000 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		num-cs = <1>;
+		clocks = <&spiclk>;
+		interrupts = <4 4>;
+		interrupt-parent = <&plic0>;
+		flash@0 {
+			compatible = "spi-flash";
+			spi-max-frequency = <50000000>;
+			reg = <0>;
+			spi-cpol;
+			spi-cpha;
+		};
+	};
+};

+ 229 - 0
arch/riscv/dts/ae350_64.dts

@@ -0,0 +1,229 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	compatible = "andestech,ax25";
+	model = "andestech,ax25";
+
+	aliases {
+		uart0 = &serial0;
+		spi0 = &spi;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,38400n8  debug loglevel=7";
+		stdout-path = "uart0:38400n8";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		timebase-frequency = <60000000>;
+		CPU0: cpu@0 {
+			device_type = "cpu";
+			reg = <0>;
+			status = "okay";
+			compatible = "riscv";
+			riscv,isa = "rv64imafdc";
+			mmu-type = "riscv,sv39";
+			clock-frequency = <60000000>;
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <32>;
+			CPU0_intc: interrupt-controller {
+				#interrupt-cells = <1>;
+				interrupt-controller;
+				compatible = "riscv,cpu-intc";
+			};
+		};
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x00000000 0x0 0x40000000>;
+	};
+
+	soc {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "andestech,riscv-ae350-soc";
+		ranges;
+
+	plic0: interrupt-controller@e4000000 {
+		compatible = "riscv,plic0";
+		#address-cells = <2>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0x0 0xe4000000 0x0 0x2000000>;
+		riscv,ndev=<71>;
+		interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
+	};
+
+	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>;
+	};
+
+	plmt0@e6000000 {
+		compatible = "riscv,plmt0";
+			interrupts-extended = <&CPU0_intc 7>;
+			reg = <0x0 0xe6000000 0x0 0x100000>;
+		};
+	};
+
+	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 = <60000000>;
+		interrupts = <3 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	serial0: serial@f0300000 {
+		compatible = "andestech,uart16550", "ns16550a";
+		reg = <0x0 0xf0300000 0x0 0x1000>;
+		interrupts = <9 4>;
+		clock-frequency = <19660800>;
+		reg-shift = <2>;
+		reg-offset = <32>;
+		no-loopback-test = <1>;
+		interrupt-parent = <&plic0>;
+	};
+
+	mac0: mac@e0100000 {
+		compatible = "andestech,atmac100";
+		reg = <0x0 0xe0100000 0x0 0x1000>;
+		interrupts = <19 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	mmc0: mmc@f0e00000 {
+		compatible = "andestech,atfsdc010";
+		max-frequency = <100000000>;
+		clock-freq-min-max = <400000 100000000>;
+		fifo-depth = <0x10>;
+		reg = <0x0 0xf0e00000 0x0 0x1000>;
+		interrupts = <18 4>;
+		cap-sd-highspeed;
+		interrupt-parent = <&plic0>;
+	};
+
+	dma0: dma@f0c00000 {
+		compatible = "andestech,atcdmac300";
+		reg = <0x0 0xf0c00000 0x0 0x1000>;
+		interrupts = <10 4 64 4 65 4 66 4 67 4 68 4 69 4 70 4 71 4>;
+		dma-channels = <8>;
+		interrupt-parent = <&plic0>;
+	};
+
+	lcd0: lcd@e0200000 {
+		compatible = "andestech,atflcdc100";
+		reg = <0x0 0xe0200000 0x0 0x1000>;
+		interrupts = <20 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	smc0: smc@e0400000 {
+		compatible = "andestech,atfsmc020";
+		reg = <0x0 0xe0400000 0x0 0x1000>;
+	};
+
+	snd0: snd@f0d00000 {
+		compatible = "andestech,atfac97";
+		reg = <0x0 0xf0d00000 0x0 0x1000>;
+		interrupts = <17 4>;
+		interrupt-parent = <&plic0>;
+	};
+
+	virtio_mmio@fe007000 {
+		interrupts = <0x17 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe007000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe006000 {
+		interrupts = <0x16 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe006000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe005000 {
+		interrupts = <0x15 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe005000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe004000 {
+		interrupts = <0x14 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe004000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe003000 {
+		interrupts = <0x13 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe003000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe002000 {
+		interrupts = <0x12 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe002000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe001000 {
+		interrupts = <0x11 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe001000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@fe000000 {
+		interrupts = <0x10 0x4>;
+		interrupt-parent = <0x2>;
+		reg = <0x0 0xfe000000 0x0 0x1000>;
+		compatible = "virtio,mmio";
+	};
+
+	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>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		num-cs = <1>;
+		clocks = <&spiclk>;
+		interrupts = <4 4>;
+		interrupt-parent = <&plic0>;
+		flash@0 {
+			compatible = "spi-flash";
+			spi-max-frequency = <50000000>;
+			reg = <0>;
+			spi-cpol;
+			spi-cpha;
+		};
+	};
+};

+ 67 - 0
arch/riscv/include/asm/barrier.h

@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2013 Regents of the University of California
+ * Copyright (C) 2017 SiFive
+ *
+ * Taken from Linux arch/riscv/include/asm/barrier.h, which is based on
+ * arch/arm/include/asm/barrier.h
+ */
+
+#ifndef _ASM_RISCV_BARRIER_H
+#define _ASM_RISCV_BARRIER_H
+
+#ifndef __ASSEMBLY__
+
+#define nop()		__asm__ __volatile__ ("nop")
+
+#define RISCV_FENCE(p, s) \
+	__asm__ __volatile__ ("fence " #p "," #s : : : "memory")
+
+/* These barriers need to enforce ordering on both devices or memory. */
+#define mb()		RISCV_FENCE(iorw,iorw)
+#define rmb()		RISCV_FENCE(ir,ir)
+#define wmb()		RISCV_FENCE(ow,ow)
+
+/* These barriers do not need to enforce ordering on devices, just memory. */
+#define __smp_mb()	RISCV_FENCE(rw,rw)
+#define __smp_rmb()	RISCV_FENCE(r,r)
+#define __smp_wmb()	RISCV_FENCE(w,w)
+
+#define __smp_store_release(p, v)					\
+do {									\
+	compiletime_assert_atomic_type(*p);				\
+	RISCV_FENCE(rw,w);						\
+	WRITE_ONCE(*p, v);						\
+} while (0)
+
+#define __smp_load_acquire(p)						\
+({									\
+	typeof(*p) ___p1 = READ_ONCE(*p);				\
+	compiletime_assert_atomic_type(*p);				\
+	RISCV_FENCE(r,rw);						\
+	___p1;								\
+})
+
+/*
+ * This is a very specific barrier: it's currently only used in two places in
+ * the kernel, both in the scheduler.  See include/linux/spinlock.h for the two
+ * orderings it guarantees, but the "critical section is RCsc" guarantee
+ * mandates a barrier on RISC-V.  The sequence looks like:
+ *
+ *    lr.aq lock
+ *    sc    lock <= LOCKED
+ *    smp_mb__after_spinlock()
+ *    // critical section
+ *    lr    lock
+ *    sc.rl lock <= UNLOCKED
+ *
+ * The AQ/RL pair provides a RCpc critical section, but there's not really any
+ * way we can take advantage of that here because the ordering is only enforced
+ * on that one lock.  Thus, we're just doing a full fence.
+ */
+#define smp_mb__after_spinlock()	RISCV_FENCE(rw,rw)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_BARRIER_H */

+ 3 - 0
arch/riscv/include/asm/cache.h

@@ -7,6 +7,9 @@
 #ifndef _ASM_RISCV_CACHE_H
 #define _ASM_RISCV_CACHE_H
 
+/* cache */
+void	cache_flush(void);
+
 /*
  * The current upper bound for RISCV L1 data cache line sizes is 32 bytes.
  * We use that value for aligning DMA buffers unless the board config has

+ 10 - 38
arch/riscv/include/asm/io.h

@@ -10,22 +10,13 @@
 #ifdef __KERNEL__
 
 #include <linux/types.h>
+#include <asm/barrier.h>
 #include <asm/byteorder.h>
 
 static inline void sync(void)
 {
 }
 
-/*
- * Given a physical address and a length, return a virtual address
- * that can be used to access the memory range with the caching
- * properties specified by "flags".
- */
-#define MAP_NOCACHE	(0)
-#define MAP_WRCOMBINE	(0)
-#define MAP_WRBACK	(0)
-#define MAP_WRTHROUGH	(0)
-
 #ifdef CONFIG_ARCH_MAP_SYSMEM
 static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
 {
@@ -48,24 +39,6 @@ static inline phys_addr_t map_to_sysmem(const void *ptr)
 }
 #endif
 
-static inline void *
-map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
-{
-	return (void *)paddr;
-}
-
-/*
- * Take down a mapping set up by map_physmem().
- */
-static inline void unmap_physmem(void *vaddr, unsigned long flags)
-{
-}
-
-static inline phys_addr_t virt_to_phys(void *vaddr)
-{
-	return (phys_addr_t)(vaddr);
-}
-
 /*
  * Generic virtual read/write.  Note that we don't support half-word
  * read/writes.  We define __arch_*[bl] here, and leave __arch_*w
@@ -74,12 +47,12 @@ static inline phys_addr_t virt_to_phys(void *vaddr)
 #define __arch_getb(a)			(*(unsigned char *)(a))
 #define __arch_getw(a)			(*(unsigned short *)(a))
 #define __arch_getl(a)			(*(unsigned int *)(a))
-#define __arch_getq(a)			(*(unsigned long *)(a))
+#define __arch_getq(a)			(*(unsigned long long *)(a))
 
 #define __arch_putb(v, a)		(*(unsigned char *)(a) = (v))
 #define __arch_putw(v, a)		(*(unsigned short *)(a) = (v))
 #define __arch_putl(v, a)		(*(unsigned int *)(a) = (v))
-#define __arch_putq(v, a)		(*(unsigned long *)(a) = (v))
+#define __arch_putq(v, a)		(*(unsigned long long *)(a) = (v))
 
 #define __raw_writeb(v, a)		__arch_putb(v, a)
 #define __raw_writew(v, a)		__arch_putw(v, a)
@@ -91,13 +64,9 @@ static inline phys_addr_t virt_to_phys(void *vaddr)
 #define __raw_readl(a)			__arch_getl(a)
 #define __raw_readq(a)			__arch_getq(a)
 
-/*
- * TODO: The kernel offers some more advanced versions of barriers, it might
- * have some advantages to use them instead of the simple one here.
- */
-#define dmb()		__asm__ __volatile__ ("" : : : "memory")
-#define __iormb()	dmb()
-#define __iowmb()	dmb()
+#define dmb()		mb()
+#define __iormb()	rmb()
+#define __iowmb()	wmb()
 
 static inline void writeb(u8 val, volatile void __iomem *addr)
 {
@@ -152,7 +121,7 @@ static inline u32 readl(const volatile void __iomem *addr)
 
 static inline u64 readq(const volatile void __iomem *addr)
 {
-	u32	val;
+	u64	val;
 
 	val = __arch_getq(addr);
 	__iormb();
@@ -487,4 +456,7 @@ out:
 
 #endif	/* __mem_isa */
 #endif	/* __KERNEL__ */
+
+#include <asm-generic/io.h>
+
 #endif	/* __ASM_RISCV_IO_H */

+ 3 - 3
arch/riscv/include/asm/posix_types.h

@@ -37,10 +37,10 @@ typedef unsigned short		__kernel_gid_t;
 #ifdef __GNUC__
 typedef __SIZE_TYPE__		__kernel_size_t;
 #else
-typedef unsigned int		__kernel_size_t;
+typedef unsigned long		__kernel_size_t;
 #endif
-typedef int			__kernel_ssize_t;
-typedef int			__kernel_ptrdiff_t;
+typedef long			__kernel_ssize_t;
+typedef long			__kernel_ptrdiff_t;
 typedef long			__kernel_time_t;
 typedef long			__kernel_suseconds_t;
 typedef long			__kernel_clock_t;

+ 4 - 0
arch/riscv/include/asm/types.h

@@ -21,7 +21,11 @@ typedef unsigned short umode_t;
  */
 #ifdef __KERNEL__
 
+#ifdef CONFIG_ARCH_RV64I
+#define BITS_PER_LONG 64
+#else
 #define BITS_PER_LONG 32
+#endif
 
 #include <stddef.h>
 

+ 70 - 27
arch/riscv/lib/bootm.c

@@ -8,6 +8,8 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
+#include <dm/root.h>
 #include <image.h>
 #include <asm/byteorder.h>
 #include <asm/csr.h>
@@ -26,26 +28,41 @@ int arch_fixup_fdt(void *blob)
 	return 0;
 }
 
-int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
+/**
+ * announce_and_cleanup() - Print message and prepare for kernel boot
+ *
+ * @fake: non-zero to do everything except actually boot
+ */
+static void announce_and_cleanup(int fake)
 {
-	void	(*kernel)(ulong hart, void *dtb);
-
-	/*
-	 * allow the PREP bootm subcommand, it is required for bootm to work
-	 */
-	if (flag & BOOTM_STATE_OS_PREP)
-		return 0;
+	printf("\nStarting kernel ...%s\n\n", fake ?
+		"(fake run for tracing)" : "");
+	bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
+#ifdef CONFIG_BOOTSTAGE_FDT
+	bootstage_fdt_add_report();
+#endif
+#ifdef CONFIG_BOOTSTAGE_REPORT
+	bootstage_report();
+#endif
 
-	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
-		return 1;
+#ifdef CONFIG_USB_DEVICE
+	udc_disconnect();
+#endif
 
-	kernel = (void (*)(ulong, void *))images->ep;
+	board_quiesce_devices();
 
-	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+	/*
+	 * Call remove function of all devices with a removal flag set.
+	 * This may be useful for last-stage operations, like cancelling
+	 * of DMA operation or releasing device internal buffers.
+	 */
+	dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
 
-	debug("## Transferring control to Linux (at address %08lx) ...\n",
-	       (ulong)kernel);
+	cleanup_before_linux();
+}
 
+static void boot_prep_linux(bootm_headers_t *images)
+{
 	if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
 #ifdef CONFIG_OF_LIBFDT
 		debug("using: FDT\n");
@@ -54,24 +71,50 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
 			hang();
 		}
 #endif
+	} else {
+		printf("Device tree not found or missing FDT support\n");
+		hang();
 	}
+}
 
-	/* we assume that the kernel is in place */
-	printf("\nStarting kernel ...\n\n");
+static void boot_jump_linux(bootm_headers_t *images, int flag)
+{
+	void (*kernel)(ulong hart, void *dtb);
+	int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
 
-	/*
-	 * Call remove function of all devices with a removal flag set.
-	 * This may be useful for last-stage operations, like cancelling
-	 * of DMA operation or releasing device internal buffers.
-	 */
-	dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
+	kernel = (void (*)(ulong, void *))images->ep;
 
-	cleanup_before_linux();
+	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+	debug("## Transferring control to Linux (at address %08lx) ...\n",
+	      (ulong)kernel);
 
-	if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
-		kernel(csr_read(mhartid), images->ft_addr);
+	announce_and_cleanup(fake);
 
-	/* does not return */
+	if (!fake) {
+		if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
+			kernel(csr_read(mhartid), images->ft_addr);
+	}
+}
+
+int do_bootm_linux(int flag, int argc, char * const argv[],
+		   bootm_headers_t *images)
+{
+	/* No need for those on RISC-V */
+	if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE)
+		return -1;
 
-	return 1;
+	if (flag & BOOTM_STATE_OS_PREP) {
+		boot_prep_linux(images);
+		return 0;
+	}
+
+	if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {
+		boot_jump_linux(images, flag);
+		return 0;
+	}
+
+	boot_prep_linux(images);
+	boot_jump_linux(images, flag);
+	return 0;
 }

+ 30 - 6
arch/riscv/lib/cache.c

@@ -6,44 +6,68 @@
 
 #include <common.h>
 
+void invalidate_icache_all(void)
+{
+	asm volatile ("fence.i" ::: "memory");
+}
+
+void flush_dcache_all(void)
+{
+	asm volatile ("fence" :::"memory");
+}
 void flush_dcache_range(unsigned long start, unsigned long end)
 {
+	flush_dcache_all();
 }
 
 void invalidate_icache_range(unsigned long start, unsigned long end)
 {
+	/*
+	 * RISC-V does not have an instruction for invalidating parts of the
+	 * instruction cache. Invalidate all of it instead.
+	 */
+	invalidate_icache_all();
 }
 
 void invalidate_dcache_range(unsigned long start, unsigned long end)
 {
+	flush_dcache_all();
+}
+
+void cache_flush(void)
+{
+	invalidate_icache_all();
+	flush_dcache_all();
 }
 
 void flush_cache(unsigned long addr, unsigned long size)
 {
+	invalidate_icache_all();
+	flush_dcache_all();
 }
 
-void icache_enable(void)
+__weak void icache_enable(void)
 {
 }
 
-void icache_disable(void)
+__weak void icache_disable(void)
 {
 }
 
-int icache_status(void)
+__weak int icache_status(void)
 {
 	return 0;
 }
 
-void dcache_enable(void)
+__weak void dcache_enable(void)
 {
 }
 
-void dcache_disable(void)
+__weak void dcache_disable(void)
 {
 }
 
-int dcache_status(void)
+__weak int dcache_status(void)
 {
 	return 0;
 }

+ 24 - 7
arch/riscv/lib/interrupts.c

@@ -12,7 +12,7 @@
 #include <asm/system.h>
 #include <asm/encoding.h>
 
-static void _exit_trap(int code, uint epc, struct pt_regs *regs);
+static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs);
 
 int interrupt_init(void)
 {
@@ -34,9 +34,9 @@ int disable_interrupts(void)
 	return 0;
 }
 
-uint handle_trap(uint mcause, uint epc, struct pt_regs *regs)
+ulong handle_trap(ulong mcause, ulong epc, struct pt_regs *regs)
 {
-	uint is_int;
+	ulong is_int;
 
 	is_int = (mcause & MCAUSE_INT);
 	if ((is_int) && ((mcause & MCAUSE_CAUSE)  == IRQ_M_EXT))
@@ -60,16 +60,33 @@ __attribute__((weak)) void timer_interrupt(struct pt_regs *regs)
 {
 }
 
-static void _exit_trap(int code, uint epc, struct pt_regs *regs)
+static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs)
 {
 	static const char * const exception_code[] = {
 		"Instruction address misaligned",
 		"Instruction access fault",
 		"Illegal instruction",
 		"Breakpoint",
-		"Load address misaligned"
+		"Load address misaligned",
+		"Load access fault",
+		"Store/AMO address misaligned",
+		"Store/AMO access fault",
+		"Environment call from U-mode",
+		"Environment call from S-mode",
+		"Reserved",
+		"Environment call from M-mode",
+		"Instruction page fault",
+		"Load page fault",
+		"Reserved",
+		"Store/AMO page fault",
 	};
 
-	printf("exception code: %d , %s , epc %08x , ra %08lx\n",
-		code, exception_code[code], epc, regs->ra);
+	if (code < ARRAY_SIZE(exception_code)) {
+		printf("exception code: %ld , %s , epc %lx , ra %lx\n",
+		       code, exception_code[code], epc, regs->ra);
+	} else {
+		printf("Reserved\n");
+	}
+
+	hang();
 }

+ 1 - 1
arch/riscv/lib/setjmp.S

@@ -6,7 +6,7 @@
 #include <config.h>
 #include <linux/linkage.h>
 
-#ifdef CONFIG_CPU_RISCV_64
+#ifdef CONFIG_ARCH_RV64I
 #define STORE_IDX(reg, idx)	sd reg, (idx*8)(a0)
 #define LOAD_IDX(reg, idx)	ld reg, (idx*8)(a0)
 #else

+ 2 - 0
board/AndesTech/ax25-ae350/MAINTAINERS

@@ -3,4 +3,6 @@ M:	Rick Chen <rick@andestech.com>
 S:	Maintained
 F:	board/AndesTech/ax25-ae350/
 F:	include/configs/ax25-ae350.h
+F:	configs/a25-ae350_32_defconfig
+F:	configs/ax25-ae350_64_defconfig
 F:	configs/ax25-ae350_defconfig

+ 1 - 3
board/armltd/integrator/README

@@ -36,9 +36,7 @@ In case c) it may be necessary for U-Boot to perform CM dependent initialization
 Configuring U-Boot :
 ------------------
 	The makefile contains targets for Integrator platforms of both types
-fitted with all current variants of CM. If these targets are to be used with
-boot process c) above then CONFIG_INIT_CRITICAL may need to be defined to ensure
-that the CM is correctly configured.
+fitted with all current variants of CM.
 
 	There are also targets independent of CM. These may not be suitable for
 boot process c) above. They have been preserved for backward compatibility with

+ 2 - 0
board/emulation/qemu-riscv/Kconfig

@@ -29,5 +29,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
 	imply CMD_EXT2
 	imply CMD_EXT4
 	imply CMD_FAT
+	imply BOARD_LATE_INIT
+	imply OF_BOARD_SETUP
 
 endif

+ 65 - 8
board/emulation/qemu-riscv/qemu-riscv.c

@@ -9,8 +9,6 @@
 #include <virtio_types.h>
 #include <virtio.h>
 
-#define MROM_FDT_ADDR	0x1020
-
 int board_init(void)
 {
 	/*
@@ -22,11 +20,70 @@ int board_init(void)
 	return 0;
 }
 
-void *board_fdt_blob_setup(void)
+int board_late_init(void)
 {
-	/*
-	 * QEMU loads a generated DTB for us immediately
-	 * after the reset vectors in the MROM
-	 */
-	return (void *)MROM_FDT_ADDR;
+	ulong kernel_start;
+	ofnode chosen_node;
+	int ret;
+
+	chosen_node = ofnode_path("/chosen");
+	if (!ofnode_valid(chosen_node)) {
+		debug("No chosen node found, can't get kernel start address\n");
+		return 0;
+	}
+
+#ifdef CONFIG_ARCH_RV64I
+	ret = ofnode_read_u64(chosen_node, "riscv,kernel-start",
+			      (u64 *)&kernel_start);
+#else
+	ret = ofnode_read_u32(chosen_node, "riscv,kernel-start",
+			      (u32 *)&kernel_start);
+#endif
+	if (ret) {
+		debug("Can't find kernel start address in device tree\n");
+		return 0;
+	}
+
+	env_set_hex("kernel_start", kernel_start);
+
+	return 0;
+}
+
+/*
+ * QEMU specifies the location of Linux (supplied with the -kernel argument)
+ * in the device tree using the riscv,kernel-start and riscv,kernel-end
+ * properties. We currently rely on the SBI implementation of BBL to run
+ * Linux and therefore embed Linux as payload in BBL. This causes an issue,
+ * because BBL detects the kernel properties in the device tree and ignores
+ * the Linux payload as a result. To work around this issue, we clear the
+ * kernel properties before booting Linux.
+ *
+ * This workaround can be removed, once we do not require BBL for its SBI
+ * implementation anymore.
+ */
+int ft_board_setup(void *blob, bd_t *bd)
+{
+	int chosen_offset, ret;
+
+	chosen_offset = fdt_path_offset(blob, "/chosen");
+	if (chosen_offset < 0)
+		return 0;
+
+#ifdef CONFIG_ARCH_RV64I
+	ret = fdt_setprop_u64(blob, chosen_offset, "riscv,kernel-start", 0);
+#else
+	ret = fdt_setprop_u32(blob, chosen_offset, "riscv,kernel-start", 0);
+#endif
+	if (ret)
+		return ret;
+
+#ifdef CONFIG_ARCH_RV64I
+	ret = fdt_setprop_u64(blob, chosen_offset, "riscv,kernel-end", 0);
+#else
+	ret = fdt_setprop_u32(blob, chosen_offset, "riscv,kernel-end", 0);
+#endif
+	if (ret)
+		return ret;
+
+	return 0;
 }

+ 1 - 2
configs/ax25-ae350_defconfig → configs/a25-ae350_32_defconfig

@@ -1,7 +1,6 @@
 CONFIG_RISCV=y
 CONFIG_SYS_TEXT_BASE=0x00000000
 CONFIG_TARGET_AX25_AE350=y
-CONFIG_CPU_RISCV_64=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_NR_DRAM_BANKS=2
 CONFIG_FIT=y
@@ -16,7 +15,7 @@ CONFIG_CMD_SF_TEST=y
 CONFIG_BOOTP_PREFER_SERVERIP=y
 CONFIG_CMD_CACHE=y
 CONFIG_OF_BOARD=y
-CONFIG_DEFAULT_DEVICE_TREE="ae350"
+CONFIG_DEFAULT_DEVICE_TREE="ae350_32"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_MMC=y

+ 37 - 0
configs/ax25-ae350_64_defconfig

@@ -0,0 +1,37 @@
+CONFIG_RISCV=y
+CONFIG_SYS_TEXT_BASE=0x00000000
+CONFIG_TARGET_AX25_AE350=y
+CONFIG_ARCH_RV64I=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_FIT=y
+CONFIG_BOOTDELAY=3
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_SYS_PROMPT="RISC-V # "
+CONFIG_CMD_IMLS=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SF_TEST=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_BOOTP_PREFER_SERVERIP=y
+CONFIG_CMD_CACHE=y
+CONFIG_OF_BOARD=y
+CONFIG_DEFAULT_DEVICE_TREE="ae350_64"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_MMC=y
+CONFIG_FTSDC010=y
+CONFIG_FTSDC010_SDIO=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_FLASH_CFI_DRIVER=y
+CONFIG_CFI_FLASH=y
+CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_FTMAC100=y
+CONFIG_BAUDRATE=38400
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_ATCSPI200_SPI=y
+CONFIG_ATCPIT100_TIMER=y

+ 4 - 1
configs/qemu-riscv32_defconfig

@@ -1,6 +1,9 @@
 CONFIG_RISCV=y
 CONFIG_TARGET_QEMU_VIRT=y
+CONFIG_DISTRO_DEFAULTS=y
 CONFIG_NR_DRAM_BANKS=1
+CONFIG_FIT=y
 CONFIG_DISPLAY_CPUINFO=y
 CONFIG_DISPLAY_BOARDINFO=y
-CONFIG_OF_BOARD=y
+# CONFIG_CMD_MII is not set
+CONFIG_OF_PRIOR_STAGE=y

+ 5 - 2
configs/qemu-riscv64_defconfig

@@ -1,7 +1,10 @@
 CONFIG_RISCV=y
 CONFIG_TARGET_QEMU_VIRT=y
-CONFIG_CPU_RISCV_64=y
+CONFIG_ARCH_RV64I=y
+CONFIG_DISTRO_DEFAULTS=y
 CONFIG_NR_DRAM_BANKS=1
+CONFIG_FIT=y
 CONFIG_DISPLAY_CPUINFO=y
 CONFIG_DISPLAY_BOARDINFO=y
-CONFIG_OF_BOARD=y
+# CONFIG_CMD_MII is not set
+CONFIG_OF_PRIOR_STAGE=y

+ 2 - 1
doc/README.distro

@@ -292,7 +292,7 @@ Each entry in the macro defines a single boot device (e.g. a specific eMMC
 device or SD card) or type of boot device (e.g. USB disk). The parameters to
 the func macro (passed in by the internal implementation of the header) are:
 
-- Upper-case disk type (MMC, SATA, SCSI, IDE, USB, DHCP, PXE).
+- Upper-case disk type (MMC, SATA, SCSI, IDE, USB, DHCP, PXE, VIRTIO).
 - Lower-case disk type (same options as above).
 - ID of the specific disk (MMC only) or ignored for other types.
 
@@ -398,6 +398,7 @@ The list of possible targets consists of:
   * scsi
   * ide
   * usb
+  * virtio
 
 Other *boot* variables than the ones defined above are only for internal use
 of the boot environment and are not guaranteed to exist or work in the same

+ 1 - 1
dts/Makefile

@@ -61,4 +61,4 @@ dtbs: $(obj)/dt.dtb $(obj)/dt-spl.dtb
 clean-files := dt.dtb.S dt-spl.dtb.S
 
 # Let clean descend into dts directories
-subdir- += ../arch/arm/dts ../arch/microblaze/dts ../arch/mips/dts ../arch/sandbox/dts ../arch/x86/dts ../arch/powerpc/dts
+subdir- += ../arch/arm/dts ../arch/microblaze/dts ../arch/mips/dts ../arch/sandbox/dts ../arch/x86/dts ../arch/powerpc/dts ../arch/riscv/dts

+ 0 - 5
include/common.h

@@ -549,11 +549,6 @@ int cpu_release(u32 nr, int argc, char * const argv[]);
 #endif
 #endif
 
-#ifdef CONFIG_INIT_CRITICAL
-#error CONFIG_INIT_CRITICAL is deprecated!
-#error Read section CONFIG_SKIP_LOWLEVEL_INIT in README.
-#endif
-
 #define ROUND(a,b)		(((a) + (b) - 1) & ~((b) - 1))
 
 /*

+ 17 - 4
include/config_distro_bootcmd.h

@@ -99,9 +99,9 @@
 #define BOOTEFI_NAME "bootia32.efi"
 #elif defined(CONFIG_X86_RUN_64BIT)
 #define BOOTEFI_NAME "bootx64.efi"
-#elif defined(CONFIG_CPU_RISCV_32)
+#elif defined(CONFIG_ARCH_RV32I)
 #define BOOTEFI_NAME "bootriscv32.efi"
-#elif defined(CONFIG_CPU_RISCV_64)
+#elif defined(CONFIG_ARCH_RV64I)
 #define BOOTEFI_NAME "bootriscv64.efi"
 #endif
 #endif
@@ -242,6 +242,18 @@
 	BOOT_TARGET_DEVICES_references_USB_without_CONFIG_CMD_USB
 #endif
 
+#ifdef CONFIG_CMD_VIRTIO
+#define BOOTENV_SHARED_VIRTIO	BOOTENV_SHARED_BLKDEV(virtio)
+#define BOOTENV_DEV_VIRTIO	BOOTENV_DEV_BLKDEV
+#define BOOTENV_DEV_NAME_VIRTIO	BOOTENV_DEV_NAME_BLKDEV
+#else
+#define BOOTENV_SHARED_VIRTIO
+#define BOOTENV_DEV_VIRTIO \
+	BOOT_TARGET_DEVICES_references_VIRTIO_without_CONFIG_CMD_VIRTIO
+#define BOOTENV_DEV_NAME_VIRTIO \
+	BOOT_TARGET_DEVICES_references_VIRTIO_without_CONFIG_CMD_VIRTIO
+#endif
+
 #if defined(CONFIG_CMD_DHCP)
 #if defined(CONFIG_EFI_LOADER)
 /* http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xml */
@@ -257,10 +269,10 @@
 #elif defined(__i386__)
 #define BOOTENV_EFI_PXE_ARCH "0x6"
 #define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00006:UNDI:003000"
-#elif defined(CONFIG_CPU_RISCV_32) || ((defined(__riscv) && __riscv_xlen == 32))
+#elif defined(CONFIG_ARCH_RV32I) || ((defined(__riscv) && __riscv_xlen == 32))
 #define BOOTENV_EFI_PXE_ARCH "0x19"
 #define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00025:UNDI:003000"
-#elif defined(CONFIG_CPU_RISCV_64) || ((defined(__riscv) && __riscv_xlen == 64))
+#elif defined(CONFIG_ARCH_RV64I) || ((defined(__riscv) && __riscv_xlen == 64))
 #define BOOTENV_EFI_PXE_ARCH "0x1b"
 #define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00027:UNDI:003000"
 #elif defined(CONFIG_SANDBOX)
@@ -350,6 +362,7 @@
 	BOOTENV_SHARED_IDE \
 	BOOTENV_SHARED_UBIFS \
 	BOOTENV_SHARED_EFI \
+	BOOTENV_SHARED_VIRTIO \
 	"boot_prefixes=/ /boot/\0" \
 	"boot_scripts=boot.scr.uimg boot.scr\0" \
 	"boot_script_dhcp=boot.scr.uimg\0" \

+ 28 - 0
include/configs/qemu-riscv.h

@@ -15,7 +15,35 @@
 
 #define CONFIG_SYS_MALLOC_LEN		SZ_8M
 
+#define CONFIG_SYS_BOOTM_LEN		SZ_16M
+
 /* Environment options */
 #define CONFIG_ENV_SIZE			SZ_4K
 
+#define BOOT_TARGET_DEVICES(func) \
+	func(QEMU, qemu, na) \
+	func(VIRTIO, virtio, 0) \
+	func(DHCP, dhcp, na)
+
+#include <config_distro_bootcmd.h>
+
+#define BOOTENV_DEV_QEMU(devtypeu, devtypel, instance) \
+	"bootcmd_qemu=" \
+		"if env exists kernel_start; then " \
+			"bootm ${kernel_start} - ${fdtcontroladdr};" \
+		"fi;\0"
+
+#define BOOTENV_DEV_NAME_QEMU(devtypeu, devtypel, instance) \
+	"qemu "
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"fdt_high=0xffffffffffffffff\0" \
+	"initrd_high=0xffffffffffffffff\0" \
+	"kernel_addr_r=0x81000000\0" \
+	"fdt_addr_r=0x82000000\0" \
+	"scriptaddr=0x82100000\0" \
+	"pxefile_addr_r=0x82200000\0" \
+	"ramdisk_addr_r=0x82300000\0" \
+	BOOTENV
+
 #endif /* __CONFIG_H */

+ 10 - 0
include/dm/ofnode.h

@@ -236,6 +236,16 @@ int ofnode_read_u32_default(ofnode ref, const char *propname, u32 def);
  */
 int ofnode_read_s32_default(ofnode node, const char *propname, s32 def);
 
+/**
+ * ofnode_read_u64() - Read a 64-bit integer from a property
+ *
+ * @node:	valid node reference to read property from
+ * @propname:	name of the property to read from
+ * @outp:	place to put value (if found)
+ * @return 0 if OK, -ve on error
+ */
+int ofnode_read_u64(ofnode node, const char *propname, u64 *outp);
+
 /**
  * ofnode_read_u64_default() - Read a 64-bit integer from a property
  *

+ 0 - 1
scripts/config_whitelist.txt

@@ -961,7 +961,6 @@ CONFIG_IMX_OTP
 CONFIG_IMX_VIDEO_SKIP
 CONFIG_INETSPACE_V2
 CONFIG_INITRD_TAG
-CONFIG_INIT_CRITICAL
 CONFIG_INIT_IGNORE_ERROR
 CONFIG_INI_ALLOW_MULTILINE
 CONFIG_INI_CASE_INSENSITIVE

+ 1 - 0
tools/.gitignore

@@ -24,6 +24,7 @@
 /mksunxiboot
 /mxsboot
 /ncb
+/prelink-riscv
 /proftool
 /relocate-rela
 /sunxi-spl-image-builder