Merge branch 'master' of git://git.denx.de/u-boot-usb

- Introduce CONFIG_SPL_DM_USB
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 81edec0..0cb6dd3 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -205,6 +205,15 @@
 	mov	r2, r3, lsl #4		@ shift variant field for combined value
 	orr	r2, r4, r2		@ r2 has combined CPU variant + revision
 
+/* Early stack for ERRATA that needs into call C code */
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
+	ldr	r0, =(CONFIG_SPL_STACK)
+#else
+	ldr	r0, =(CONFIG_SYS_INIT_SP_ADDR)
+#endif
+	bic	r0, r0, #7	/* 8-byte alignment for ABI compliance */
+	mov	sp, r0
+
 #ifdef CONFIG_ARM_ERRATA_798870
 	cmp	r2, #0x30		@ Applies to lower than R3p0
 	bge	skip_errata_798870      @ skip if not affected rev
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 84b7e53..55f3fd1 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -187,7 +187,8 @@
 	am335x-icev2.dtb \
 	am335x-pxm50.dtb \
 	am335x-rut.dtb \
-	am335x-pdu001.dtb
+	am335x-pdu001.dtb \
+	am335x-chiliboard.dtb
 dtb-$(CONFIG_AM43XX) += am437x-gp-evm.dtb am437x-sk-evm.dtb	\
 	am43x-epos-evm.dtb \
 	am437x-idk-evm.dtb \
diff --git a/arch/arm/dts/am335x-chiliboard-u-boot.dtsi b/arch/arm/dts/am335x-chiliboard-u-boot.dtsi
new file mode 100644
index 0000000..4f9d308
--- /dev/null
+++ b/arch/arm/dts/am335x-chiliboard-u-boot.dtsi
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0+ or X11
+/*
+ * Copyright (C) 2018 Grinn Sp. z o.o. -- http://www.grinn-global.com/
+ * Author: Marcin Niestroj <m.niestroj@grinn-global.com>
+ */
+
+/ {
+	chosen {
+		stdout-path = &uart0;
+	};
+};
diff --git a/arch/arm/dts/am335x-chiliboard.dts b/arch/arm/dts/am335x-chiliboard.dts
new file mode 100644
index 0000000..59431b2
--- /dev/null
+++ b/arch/arm/dts/am335x-chiliboard.dts
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2015 Jablotron s.r.o. -- http://www.jablotron.com/
+ * Author: Rostislav Lisovy <lisovy@jablotron.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "am335x-chilisom.dtsi"
+
+/ {
+	model = "AM335x Chiliboard";
+	compatible = "grinn,am335x-chiliboard", "grinn,am335x-chilisom",
+		     "ti,am33xx";
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_gpio_pins>;
+
+		led0 {
+			label = "led0";
+			gpios = <&gpio3 7 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+			linux,default-trigger = "heartbeat";
+		};
+
+		led1 {
+			label = "led1";
+			gpios = <&gpio3 8 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+		};
+	};
+};
+
+&am33xx_pinmux {
+	uart0_pins: pinmux_uart0_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)	/* uart0_rxd.uart0_rxd */
+			AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* uart0_txd.uart0_txd */
+		>;
+	};
+
+	cpsw_default: cpsw_default {
+		pinctrl-single,pins = <
+			/* Slave 1 */
+			AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_crs.rmii1_crs */
+			AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE1)	/* mii1_rxerr.rmii1_rxerr */
+			AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE1)	/* mii1_txen.rmii1_txen */
+			AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE1)	/* mii1_txd1.rmii1_txd1 */
+			AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE1)	/* mii1_txd0.rmii1_txd0 */
+			AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE1)	/* mii1_rxd1.rmii1_rxd1 */
+			AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE1)	/* mii1_rxd0.rmii1_rxd0 */
+			AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* rmii1_ref_clk.rmii_ref_clk */
+		>;
+	};
+
+	cpsw_sleep: cpsw_sleep {
+		pinctrl-single,pins = <
+			/* Slave 1 reset value */
+			AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
+		>;
+	};
+
+	davinci_mdio_default: davinci_mdio_default {
+		pinctrl-single,pins = <
+			/* mdio_data.mdio_data */
+			AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)
+			/* mdio_clk.mdio_clk */
+			AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)
+		>;
+	};
+
+	davinci_mdio_sleep: davinci_mdio_sleep {
+		pinctrl-single,pins = <
+			/* MDIO reset value */
+			AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+			AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+		>;
+	};
+
+	usb1_drvvbus: usb1_drvvbus {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0xa34, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* usb1_drvvbus.usb1_drvvbus */
+		>;
+	};
+
+	sd_pins: pinmux_sd_card {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x8f0, PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+			AM33XX_IOPAD(0x8f4, PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+			AM33XX_IOPAD(0x8f8, PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+			AM33XX_IOPAD(0x8fc, PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+			AM33XX_IOPAD(0x900, PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+			AM33XX_IOPAD(0x904, PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+			AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+		>;
+	};
+
+	led_gpio_pins: led_gpio_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x9e4, PIN_OUTPUT | MUX_MODE7) /* emu0.gpio3_7 */
+			AM33XX_IOPAD(0x9e8, PIN_OUTPUT | MUX_MODE7) /* emu1.gpio3_8 */
+		>;
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins>;
+
+	status = "okay";
+};
+
+&ldo4_reg {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+};
+
+/* Ethernet */
+&mac {
+	slaves = <1>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&cpsw_default>;
+	pinctrl-1 = <&cpsw_sleep>;
+	status = "okay";
+};
+
+&davinci_mdio {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&davinci_mdio_default>;
+	pinctrl-1 = <&davinci_mdio_sleep>;
+	status = "okay";
+};
+
+&cpsw_emac0 {
+	phy_id = <&davinci_mdio>, <0>;
+	phy-mode = "rmii";
+};
+
+&phy_sel {
+	rmii-clock-ext;
+};
+
+/* USB */
+&usb {
+	status = "okay";
+};
+
+&usb_ctrl_mod {
+	status = "okay";
+};
+
+&usb1_phy {
+	status = "okay";
+};
+
+&usb1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb1_drvvbus>;
+
+	status = "okay";
+	dr_mode = "host";
+};
+
+&cppi41dma  {
+	status = "okay";
+};
+
+/* microSD */
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd_pins>;
+	vmmc-supply = <&ldo4_reg>;
+	bus-width = <0x4>;
+	cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&tps {
+	interrupt-parent = <&intc>;
+	interrupts = <7>; /* NNMI */
+
+	charger {
+		status = "okay";
+	};
+
+	pwrbutton {
+		status = "okay";
+	};
+};
diff --git a/arch/arm/dts/am335x-chilisom.dtsi b/arch/arm/dts/am335x-chilisom.dtsi
new file mode 100644
index 0000000..1b43ebd
--- /dev/null
+++ b/arch/arm/dts/am335x-chilisom.dtsi
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2015 Jablotron s.r.o. -- http://www.jablotron.com/
+ * Author: Rostislav Lisovy <lisovy@jablotron.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include "am33xx.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	model = "Grinn AM335x ChiliSOM";
+	compatible = "grinn,am335x-chilisom", "ti,am33xx";
+
+	cpus {
+		cpu@0 {
+			cpu0-supply = <&dcdc2_reg>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>; /* 512 MB */
+	};
+};
+
+&am33xx_pinmux {
+	pinctrl-names = "default";
+
+	i2c0_pins: pinmux_i2c0_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_sda.i2c0_sda */
+			AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_scl.i2c0_scl */
+		>;
+	};
+
+	nandflash_pins: nandflash_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x800, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad0.gpmc_ad0 */
+			AM33XX_IOPAD(0x804, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad1.gpmc_ad1 */
+			AM33XX_IOPAD(0x808, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad2.gpmc_ad2 */
+			AM33XX_IOPAD(0x80c, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad3.gpmc_ad3 */
+			AM33XX_IOPAD(0x810, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad4.gpmc_ad4 */
+			AM33XX_IOPAD(0x814, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad5.gpmc_ad5 */
+			AM33XX_IOPAD(0x818, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad6.gpmc_ad6 */
+			AM33XX_IOPAD(0x81c, PIN_INPUT_PULLDOWN | MUX_MODE0)	/* gpmc_ad7.gpmc_ad7 */
+
+			AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_wait0.gpmc_wait0 */
+			AM33XX_IOPAD(0x87c, PIN_OUTPUT_PULLUP | MUX_MODE0)	/* gpmc_csn0.gpmc_csn0 */
+			AM33XX_IOPAD(0x890, PIN_OUTPUT_PULLUP | MUX_MODE0)	/* gpmc_advn_ale.gpmc_advn_ale */
+			AM33XX_IOPAD(0x894, PIN_OUTPUT_PULLUP | MUX_MODE0)	/* gpmc_oen_ren.gpmc_oen_ren */
+			AM33XX_IOPAD(0x898, PIN_OUTPUT_PULLUP | MUX_MODE0)	/* gpmc_wen.gpmc_wen */
+			AM33XX_IOPAD(0x89c, PIN_OUTPUT_PULLUP | MUX_MODE0)	/* gpmc_be0n_cle.gpmc_be0n_cle */
+		>;
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+
+	status = "okay";
+	clock-frequency = <400000>;
+
+	tps: tps@24 {
+		reg = <0x24>;
+	};
+
+};
+
+/include/ "tps65217.dtsi"
+
+&tps {
+	regulators {
+		dcdc1_reg: regulator@0 {
+			regulator-name = "vdds_dpr";
+			regulator-always-on;
+		};
+
+		dcdc2_reg: regulator@1 {
+			/* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
+			regulator-name = "vdd_mpu";
+			regulator-min-microvolt = <925000>;
+			regulator-max-microvolt = <1325000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		dcdc3_reg: regulator@2 {
+			/* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
+			regulator-name = "vdd_core";
+			regulator-min-microvolt = <925000>;
+			regulator-max-microvolt = <1150000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		ldo1_reg: regulator@3 {
+			regulator-name = "vio,vrtc,vdds";
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		ldo2_reg: regulator@4 {
+			regulator-name = "vdd_3v3aux";
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		ldo3_reg: regulator@5 {
+			regulator-name = "vdd_1v8";
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		ldo4_reg: regulator@6 {
+			regulator-name = "vdd_3v3d";
+			regulator-boot-on;
+			regulator-always-on;
+		};
+	};
+};
+
+&rtc {
+	system-power-controller;
+
+	pinctrl-0 = <&ext_wakeup>;
+	pinctrl-names = "default";
+
+	ext_wakeup: ext-wakeup {
+		pins = "ext_wakeup0";
+		input-enable;
+	};
+};
+
+/* NAND Flash */
+&elm {
+	status = "okay";
+};
+
+&gpmc {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&nandflash_pins>;
+	ranges = <0 0 0x08000000 0x01000000>; /* CS0 0 @addr 0x08000000, size 0x01000000 */
+	nand@0,0 {
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
+		rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
+		ti,nand-ecc-opt = "bch8";
+		ti,elm-id = <&elm>;
+		nand-bus-width = <8>;
+		gpmc,device-width = <1>;
+		gpmc,sync-clk-ps = <0>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <44>;
+		gpmc,cs-wr-off-ns = <44>;
+		gpmc,adv-on-ns = <6>;
+		gpmc,adv-rd-off-ns = <34>;
+		gpmc,adv-wr-off-ns = <44>;
+		gpmc,we-on-ns = <0>;
+		gpmc,we-off-ns = <40>;
+		gpmc,oe-on-ns = <0>;
+		gpmc,oe-off-ns = <54>;
+		gpmc,access-ns = <64>;
+		gpmc,rd-cycle-ns = <82>;
+		gpmc,wr-cycle-ns = <82>;
+		gpmc,bus-turnaround-ns = <0>;
+		gpmc,cycle2cycle-delay-ns = <0>;
+		gpmc,clk-activation-ns = <0>;
+		gpmc,wr-access-ns = <40>;
+		gpmc,wr-data-mux-bus-ns = <0>;
+	};
+};
diff --git a/arch/arm/mach-k3/Makefile b/arch/arm/mach-k3/Makefile
index 406dda3..bd4ab36 100644
--- a/arch/arm/mach-k3/Makefile
+++ b/arch/arm/mach-k3/Makefile
@@ -5,5 +5,5 @@
 
 obj-$(CONFIG_SOC_K3_AM6) += am6_init.o
 obj-$(CONFIG_ARM64) += arm64-mmu.o
-obj-$(CONFIG_CPU_V7R) += r5_mpu.o
+obj-$(CONFIG_CPU_V7R) += r5_mpu.o lowlevel_init.o
 obj-y += common.o
diff --git a/arch/arm/mach-k3/lowlevel_init.S b/arch/arm/mach-k3/lowlevel_init.S
new file mode 100644
index 0000000..70c5d1c
--- /dev/null
+++ b/arch/arm/mach-k3/lowlevel_init.S
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ *	Lokesh Vutla <lokeshvutla@ti.com>
+ */
+
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+
+	mrc	p15, 0, r0, c0, c0, 5		@ Read MPIDR
+	and	r0, #0xff
+	cmp	r0, #0x0
+	bne	park_cpu
+	bx	lr
+park_cpu:
+	wfi
+	b	park_cpu
+
+ENDPROC(lowlevel_init)
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 560dc9b..3c54f51 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -230,6 +230,7 @@
 	select PHY_SUN4I_USB
 	select SUNXI_GEN_SUN6I
 	select MMC_SUNXI_HAS_NEW_MODE
+	select MMC_SUNXI_HAS_MODE_SWITCH
 	select SUPPORT_SPL
 
 config MACH_SUN8I_H3
@@ -281,6 +282,7 @@
 	select SUN6I_PRCM
 	select SUNXI_DE2
 	select SUNXI_GEN_SUN6I
+	select MMC_SUNXI_HAS_NEW_MODE
 	select SUPPORT_SPL
 	select SUNXI_DRAM_DW
 	select SUNXI_DRAM_DW_32BIT
diff --git a/arch/arm/mach-sunxi/dram_sun8i_a33.c b/arch/arm/mach-sunxi/dram_sun8i_a33.c
index d9aa0c6..1da2727 100644
--- a/arch/arm/mach-sunxi/dram_sun8i_a33.c
+++ b/arch/arm/mach-sunxi/dram_sun8i_a33.c
@@ -334,7 +334,7 @@
 	struct dram_para para = {
 		.cs1 = 0,
 		.bank = 1,
-		.rank = 1,
+		.rank = 2,
 		.rows = 15,
 		.bus_width = 16,
 		.page_size = 2048,
diff --git a/arch/nds32/cpu/n1213/start.S b/arch/nds32/cpu/n1213/start.S
index aa9457f..cf966e2 100644
--- a/arch/nds32/cpu/n1213/start.S
+++ b/arch/nds32/cpu/n1213/start.S
@@ -201,14 +201,6 @@
 #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.
  */
@@ -319,49 +311,6 @@
 	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$
  */
 invalidate_icac:
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 168ca3d..3e0af55 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -16,27 +16,45 @@
 
 endchoice
 
+# board-specific options below
 source "board/AndesTech/ax25-ae350/Kconfig"
 source "board/emulation/qemu-riscv/Kconfig"
 
-choice
-	prompt "CPU selection"
-	default CPU_RISCV_32
+# platform-specific options below
+source "arch/riscv/cpu/ax25/Kconfig"
 
-config CPU_RISCV_32
-	bool "RISC-V 32-bit"
+# architecture-specific options below
+
+choice
+	prompt "Base ISA"
+	default ARCH_RV32I
+
+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
 
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 8fb6a88..55d7c65 100644
--- a/arch/riscv/Makefile
+++ b/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/
diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk
index cc5d8d1..ff4fe64 100644
--- a/arch/riscv/config.mk
+++ b/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 @@
 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
diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig
new file mode 100644
index 0000000..6c7022f
--- /dev/null
+++ b/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.
diff --git a/arch/riscv/cpu/ax25/Makefile b/arch/riscv/cpu/ax25/Makefile
index 2ab0342..318bacc 100644
--- a/arch/riscv/cpu/ax25/Makefile
+++ b/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
diff --git a/arch/riscv/cpu/ax25/cache.c b/arch/riscv/cpu/ax25/cache.c
new file mode 100644
index 0000000..6600ac2
--- /dev/null
+++ b/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;
+}
diff --git a/arch/riscv/cpu/ax25/cpu.c b/arch/riscv/cpu/ax25/cpu.c
index fddcc15..76689b2 100644
--- a/arch/riscv/cpu/ax25/cpu.c
+++ b/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 @@
 	disable_interrupts();
 
 	/* turn off I/D-cache */
+	cache_flush();
+	icache_disable();
+	dcache_disable();
 
 	return 0;
 }
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index ae57fb8..d9f820c 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/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,
diff --git a/arch/riscv/cpu/qemu/cpu.c b/arch/riscv/cpu/qemu/cpu.c
index 6c7a327..25d97d0 100644
--- a/arch/riscv/cpu/qemu/cpu.c
+++ b/arch/riscv/cpu/qemu/cpu.c
@@ -15,7 +15,7 @@
 {
 	disable_interrupts();
 
-	/* turn off I/D-cache */
+	cache_flush();
 
 	return 0;
 }
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index 7cd7755..15e1b81 100644
--- a/arch/riscv/cpu/start.S
+++ b/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 @@
 	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 @@
  */
 .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
diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
index a1b06ff..b400def 100644
--- a/arch/riscv/dts/Makefile
+++ b/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
diff --git a/arch/riscv/dts/ae350.dts b/arch/riscv/dts/ae350.dts
index 4717ae8..e48c298 100644
--- a/arch/riscv/dts/ae350.dts
+++ b/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>;
diff --git a/arch/riscv/dts/ae350_32.dts b/arch/riscv/dts/ae350_32.dts
new file mode 100644
index 0000000..0679827
--- /dev/null
+++ b/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;
+		};
+	};
+};
diff --git a/arch/riscv/dts/ae350_64.dts b/arch/riscv/dts/ae350_64.dts
new file mode 100644
index 0000000..e48c298
--- /dev/null
+++ b/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;
+		};
+	};
+};
diff --git a/arch/riscv/include/asm/barrier.h b/arch/riscv/include/asm/barrier.h
new file mode 100644
index 0000000..a3f60a8
--- /dev/null
+++ b/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 */
diff --git a/arch/riscv/include/asm/cache.h b/arch/riscv/include/asm/cache.h
index ca83dd6..ec8fe20 100644
--- a/arch/riscv/include/asm/cache.h
+++ b/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
diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
index f4a76d87..acf5a96 100644
--- a/arch/riscv/include/asm/io.h
+++ b/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 @@
 }
 #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 @@
 #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 @@
 #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 u64 readq(const volatile void __iomem *addr)
 {
-	u32	val;
+	u64	val;
 
 	val = __arch_getq(addr);
 	__iormb();
@@ -487,4 +456,7 @@
 
 #endif	/* __mem_isa */
 #endif	/* __KERNEL__ */
+
+#include <asm-generic/io.h>
+
 #endif	/* __ASM_RISCV_IO_H */
diff --git a/arch/riscv/include/asm/posix_types.h b/arch/riscv/include/asm/posix_types.h
index 7438dbe..0fc0520 100644
--- a/arch/riscv/include/asm/posix_types.h
+++ b/arch/riscv/include/asm/posix_types.h
@@ -37,10 +37,10 @@
 #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;
diff --git a/arch/riscv/include/asm/types.h b/arch/riscv/include/asm/types.h
index bd86271..403cf9a 100644
--- a/arch/riscv/include/asm/types.h
+++ b/arch/riscv/include/asm/types.h
@@ -21,7 +21,11 @@
  */
 #ifdef __KERNEL__
 
+#ifdef CONFIG_ARCH_RV64I
+#define BITS_PER_LONG 64
+#else
 #define BITS_PER_LONG 32
+#endif
 
 #include <stddef.h>
 
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index 2b5ccce..124aeef 100644
--- a/arch/riscv/lib/bootm.c
+++ b/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,38 +28,28 @@
 	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;
-
-	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
-		return 1;
-
-	kernel = (void (*)(ulong, void *))images->ep;
-
-	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) {
-#ifdef CONFIG_OF_LIBFDT
-		debug("using: FDT\n");
-		if (image_setup_linux(images)) {
-			printf("FDT creation failed! hanging...");
-			hang();
-		}
+	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
 
-	/* we assume that the kernel is in place */
-	printf("\nStarting kernel ...\n\n");
+#ifdef CONFIG_USB_DEVICE
+	udc_disconnect();
+#endif
+
+	board_quiesce_devices();
 
 	/*
 	 * Call remove function of all devices with a removal flag set.
@@ -67,11 +59,62 @@
 	dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
 
 	cleanup_before_linux();
+}
 
-	if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
-		kernel(csr_read(mhartid), images->ft_addr);
+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");
+		if (image_setup_linux(images)) {
+			printf("FDT creation failed! hanging...");
+			hang();
+		}
+#endif
+	} else {
+		printf("Device tree not found or missing FDT support\n");
+		hang();
+	}
+}
 
-	/* does not return */
+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);
 
-	return 1;
+	kernel = (void (*)(ulong, void *))images->ep;
+
+	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+	debug("## Transferring control to Linux (at address %08lx) ...\n",
+	      (ulong)kernel);
+
+	announce_and_cleanup(fake);
+
+	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;
+
+	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;
 }
diff --git a/arch/riscv/lib/cache.c b/arch/riscv/lib/cache.c
index 1d67c49..ae5c607 100644
--- a/arch/riscv/lib/cache.c
+++ b/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;
 }
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index 0a0995a..903a1c4 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/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 @@
 	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 @@
 {
 }
 
-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();
 }
diff --git a/arch/riscv/lib/setjmp.S b/arch/riscv/lib/setjmp.S
index 8f5a6a2..72bc924 100644
--- a/arch/riscv/lib/setjmp.S
+++ b/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
diff --git a/board/AndesTech/ax25-ae350/MAINTAINERS b/board/AndesTech/ax25-ae350/MAINTAINERS
index 508c6ac..d87446e 100644
--- a/board/AndesTech/ax25-ae350/MAINTAINERS
+++ b/board/AndesTech/ax25-ae350/MAINTAINERS
@@ -3,4 +3,6 @@
 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
diff --git a/board/armltd/integrator/README b/board/armltd/integrator/README
index 5a0e934..af9dcc1 100644
--- a/board/armltd/integrator/README
+++ b/board/armltd/integrator/README
@@ -36,9 +36,7 @@
 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
diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig
index 37a80db..33ca253 100644
--- a/board/emulation/qemu-riscv/Kconfig
+++ b/board/emulation/qemu-riscv/Kconfig
@@ -29,5 +29,7 @@
 	imply CMD_EXT2
 	imply CMD_EXT4
 	imply CMD_FAT
+	imply BOARD_LATE_INIT
+	imply OF_BOARD_SETUP
 
 endif
diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c
index 2730a28..d6167aa 100644
--- a/board/emulation/qemu-riscv/qemu-riscv.c
+++ b/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 @@
 	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;
 }
diff --git a/board/grinn/chiliboard/board.c b/board/grinn/chiliboard/board.c
index 73a7d82..dc0de62 100644
--- a/board/grinn/chiliboard/board.c
+++ b/board/grinn/chiliboard/board.c
@@ -19,7 +19,6 @@
 #include <environment.h>
 #include <errno.h>
 #include <miiphy.h>
-#include <serial.h>
 #include <spl.h>
 #include <watchdog.h>
 
@@ -69,13 +68,6 @@
 }
 #endif /* CONFIG_SKIP_LOWLEVEL_INIT */
 
-#ifndef CONFIG_DM_SERIAL
-struct serial_device *default_serial_console(void)
-{
-	return &eserial1_device;
-}
-#endif
-
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
 void set_uart_mux_conf(void)
 {
@@ -150,56 +142,3 @@
 	return 0;
 }
 #endif
-
-#if !defined(CONFIG_DM_ETH) && defined(CONFIG_DRIVER_TI_CPSW) && \
-	!defined(CONFIG_SPL_BUILD)
-static void cpsw_control(int enabled)
-{
-	/* VTP can be added here */
-
-	return;
-}
-
-static struct cpsw_slave_data cpsw_slaves[] = {
-	{
-		.slave_reg_ofs	= 0x208,
-		.sliver_reg_ofs	= 0xd80,
-		.phy_addr	= 0,
-	}
-};
-
-static struct cpsw_platform_data cpsw_data = {
-	.mdio_base		= CPSW_MDIO_BASE,
-	.cpsw_base		= CPSW_BASE,
-	.mdio_div		= 0xff,
-	.channels		= 8,
-	.cpdma_reg_ofs		= 0x800,
-	.slaves			= 1,
-	.slave_data		= cpsw_slaves,
-	.ale_reg_ofs		= 0xd00,
-	.ale_entries		= 1024,
-	.host_port_reg_ofs	= 0x108,
-	.hw_stats_reg_ofs	= 0x900,
-	.bd_ram_ofs		= 0x2000,
-	.mac_control		= (1 << 5),
-	.control		= cpsw_control,
-	.host_port_num		= 0,
-	.version		= CPSW_CTRL_VERSION_2,
-};
-
-int board_eth_init(bd_t *bis)
-{
-	int rv, n = 0;
-
-	writel(RMII_MODE_ENABLE | RMII_CHIPCKL_ENABLE, &cdev->miisel);
-	cpsw_slaves[0].phy_if = PHY_INTERFACE_MODE_RMII;
-
-	rv = cpsw_register(&cpsw_data);
-	if (rv < 0)
-		printf("Error %d registering CPSW switch\n", rv);
-	else
-		n += rv;
-
-	return n;
-}
-#endif
diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
index 21f353f..979ac4a 100644
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -253,6 +253,7 @@
 
 	int len;
 	char *sep;
+	char *default_str;
 	struct bootmenu_entry *entry;
 
 	menu = malloc(sizeof(struct bootmenu_data));
@@ -263,6 +264,10 @@
 	menu->active = 0;
 	menu->first = NULL;
 
+	default_str = env_get("bootmenu_default");
+	if (default_str)
+		menu->active = (int)simple_strtol(default_str, NULL, 10);
+
 	while ((option = bootmenu_getoption(i))) {
 		sep = strchr(option, '=');
 		if (!sep) {
diff --git a/configs/ax25-ae350_defconfig b/configs/a25-ae350_32_defconfig
similarity index 93%
rename from configs/ax25-ae350_defconfig
rename to configs/a25-ae350_32_defconfig
index d7c4f40..5837b48 100644
--- a/configs/ax25-ae350_defconfig
+++ b/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_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
diff --git a/configs/ax25-ae350_defconfig b/configs/ax25-ae350_64_defconfig
similarity index 92%
copy from configs/ax25-ae350_defconfig
copy to configs/ax25-ae350_64_defconfig
index d7c4f40..b250d3f 100644
--- a/configs/ax25-ae350_defconfig
+++ b/configs/ax25-ae350_64_defconfig
@@ -1,7 +1,7 @@
 CONFIG_RISCV=y
 CONFIG_SYS_TEXT_BASE=0x00000000
 CONFIG_TARGET_AX25_AE350=y
-CONFIG_CPU_RISCV_64=y
+CONFIG_ARCH_RV64I=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_NR_DRAM_BANKS=2
 CONFIG_FIT=y
@@ -16,7 +16,7 @@
 CONFIG_BOOTP_PREFER_SERVERIP=y
 CONFIG_CMD_CACHE=y
 CONFIG_OF_BOARD=y
-CONFIG_DEFAULT_DEVICE_TREE="ae350"
+CONFIG_DEFAULT_DEVICE_TREE="ae350_64"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_MMC=y
diff --git a/configs/chiliboard_defconfig b/configs/chiliboard_defconfig
index b6cde09..3de0223 100644
--- a/configs/chiliboard_defconfig
+++ b/configs/chiliboard_defconfig
@@ -29,19 +29,27 @@
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nand0=8000000.nand"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=8000000.nand:128k(NAND.SPL),128k(NAND.SPL.backup1),128k(NAND.SPL.backup2),128k(NAND.SPL.backup3),256k(NAND.u-boot-spl-os),1m(NAND.u-boot),128k(NAND.u-boot-env),128k(NAND.u-boot-env.backup1),8m(NAND.kernel),-(NAND.file-system)"
+CONFIG_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="am335x-chiliboard"
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DM_GPIO=y
+CONFIG_MISC=y
+CONFIG_DM_MMC=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_NAND=y
-CONFIG_DRIVER_TI_CPSW=y
+CONFIG_DM_ETH=y
 CONFIG_MII=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SPI=y
 CONFIG_OMAP3_SPI=y
+CONFIG_TIMER=y
+CONFIG_OMAP_TIMER=y
 CONFIG_USB=y
+CONFIG_DM_USB=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_USB_MUSB_DSPS=y
+CONFIG_USB_MUSB_TI=y
 CONFIG_USB_STORAGE=y
 CONFIG_FAT_WRITE=y
 CONFIG_LZO=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-riscv32_defconfig
index ff1fb1f..6334d8c 100644
--- a/configs/qemu-riscv32_defconfig
+++ b/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
diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-riscv64_defconfig
index d6c1a5d..2d9ead9 100644
--- a/configs/qemu-riscv64_defconfig
+++ b/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
diff --git a/configs/vexpress_aemv8a_dram_defconfig b/configs/vexpress_aemv8a_dram_defconfig
index 9848f96..0f0f138 100644
--- a/configs/vexpress_aemv8a_dram_defconfig
+++ b/configs/vexpress_aemv8a_dram_defconfig
@@ -23,12 +23,14 @@
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_CACHE=y
 # CONFIG_CMD_MISC is not set
+CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_DM=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_MTD_DEVICE=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
 CONFIG_SYS_FLASH_PROTECTION=y
diff --git a/configs/vexpress_aemv8a_juno_defconfig b/configs/vexpress_aemv8a_juno_defconfig
index ef38915..ed611fe 100644
--- a/configs/vexpress_aemv8a_juno_defconfig
+++ b/configs/vexpress_aemv8a_juno_defconfig
@@ -23,12 +23,14 @@
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_CACHE=y
 # CONFIG_CMD_MISC is not set
+CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_DM=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_MTD_DEVICE=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
 CONFIG_SYS_FLASH_PROTECTION=y
diff --git a/configs/vexpress_aemv8a_semi_defconfig b/configs/vexpress_aemv8a_semi_defconfig
index a4d1233..0b3bb65 100644
--- a/configs/vexpress_aemv8a_semi_defconfig
+++ b/configs/vexpress_aemv8a_semi_defconfig
@@ -23,12 +23,14 @@
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_CACHE=y
 # CONFIG_CMD_MISC is not set
+CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_DM=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_MTD_DEVICE=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
 CONFIG_SYS_FLASH_PROTECTION=y
diff --git a/configs/vexpress_ca15_tc2_defconfig b/configs/vexpress_ca15_tc2_defconfig
index f4d555b..cabc0c4 100644
--- a/configs/vexpress_ca15_tc2_defconfig
+++ b/configs/vexpress_ca15_tc2_defconfig
@@ -18,8 +18,10 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
 # CONFIG_CMD_MISC is not set
+CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_MTD_DEVICE=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
 CONFIG_SYS_FLASH_PROTECTION=y
diff --git a/configs/vexpress_ca5x2_defconfig b/configs/vexpress_ca5x2_defconfig
index bdacc60..dc4411d 100644
--- a/configs/vexpress_ca5x2_defconfig
+++ b/configs/vexpress_ca5x2_defconfig
@@ -17,8 +17,10 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
 # CONFIG_CMD_MISC is not set
+CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_MTD_DEVICE=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
 CONFIG_SYS_FLASH_PROTECTION=y
diff --git a/configs/vexpress_ca9x4_defconfig b/configs/vexpress_ca9x4_defconfig
index 7a90831..9390cf6 100644
--- a/configs/vexpress_ca9x4_defconfig
+++ b/configs/vexpress_ca9x4_defconfig
@@ -17,8 +17,10 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
 # CONFIG_CMD_MISC is not set
+CONFIG_CMD_UBI=y
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_MTD_NOR_FLASH=y
+CONFIG_MTD_DEVICE=y
 CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
 CONFIG_SYS_FLASH_PROTECTION=y
diff --git a/doc/README.distro b/doc/README.distro
index f8e9752..ab6e6f4 100644
--- a/doc/README.distro
+++ b/doc/README.distro
@@ -292,7 +292,7 @@
 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 @@
   * 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
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 27246ee..3f7458d 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -569,6 +569,10 @@
 	bool
 	depends on MMC_SUNXI
 
+config MMC_SUNXI_HAS_MODE_SWITCH
+	bool
+	depends on MMC_SUNXI
+
 config GENERIC_ATMEL_MCI
 	bool "Atmel Multimedia Card Interface support"
 	depends on DM_MMC && BLK && ARCH_AT91
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 147eb9b..9bf040c 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -98,24 +98,21 @@
 static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
 {
 	unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly;
-	bool new_mode = false;
+	bool new_mode = true;
 	bool calibrate = false;
 	u32 val = 0;
 
-	if (IS_ENABLED(CONFIG_MMC_SUNXI_HAS_NEW_MODE) && (priv->mmc_no == 2))
-		new_mode = true;
+	if (!IS_ENABLED(CONFIG_MMC_SUNXI_HAS_NEW_MODE))
+		new_mode = false;
+
+	/* A83T support new mode only on eMMC */
+	if (IS_ENABLED(CONFIG_MACH_SUN8I_A83T) && priv->mmc_no != 2)
+		new_mode = false;
 
 #if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H6)
 	calibrate = true;
 #endif
 
-	/*
-	 * The MMC clock has an extra /2 post-divider when operating in the new
-	 * mode.
-	 */
-	if (new_mode)
-		hz = hz * 2;
-
 	if (hz <= 24000000) {
 		pll = CCM_MMC_CTRL_OSCM24;
 		pll_hz = 24000000;
@@ -176,7 +173,9 @@
 
 	if (new_mode) {
 #ifdef CONFIG_MMC_SUNXI_HAS_NEW_MODE
+#ifdef CONFIG_MMC_SUNXI_HAS_MODE_SWITCH
 		val = CCM_MMC_CTRL_MODE_SEL_NEW;
+#endif
 		setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);
 #endif
 	} else if (!calibrate) {
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
index 3ba3a1f..c979844 100644
--- a/drivers/net/sun8i_emac.c
+++ b/drivers/net/sun8i_emac.c
@@ -60,6 +60,10 @@
 #define SC_ETCS_MASK		GENMASK(1, 0)
 #define SC_ETCS_EXT_GMII	0x1
 #define SC_ETCS_INT_GMII	0x2
+#define SC_ETXDC_MASK		GENMASK(12, 10)
+#define SC_ETXDC_OFFSET		10
+#define SC_ERXDC_MASK		GENMASK(9, 5)
+#define SC_ERXDC_OFFSET		5
 
 #define CONFIG_MDIO_TIMEOUT	(3 * CONFIG_SYS_HZ)
 
@@ -140,6 +144,8 @@
 struct sun8i_eth_pdata {
 	struct eth_pdata eth_pdata;
 	u32 reset_delays[3];
+	int tx_delay_ps;
+	int rx_delay_ps;
 };
 
 
@@ -273,7 +279,8 @@
 	return 0;
 }
 
-static int sun8i_emac_set_syscon(struct emac_eth_dev *priv)
+static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
+				 struct emac_eth_dev *priv)
 {
 	int ret;
 	u32 reg;
@@ -312,6 +319,14 @@
 		return -EINVAL;
 	}
 
+	if (pdata->tx_delay_ps)
+		reg |= ((pdata->tx_delay_ps / 100) << SC_ETXDC_OFFSET)
+			 & SC_ETXDC_MASK;
+
+	if (pdata->rx_delay_ps)
+		reg |= ((pdata->rx_delay_ps / 100) << SC_ERXDC_OFFSET)
+			 & SC_ERXDC_MASK;
+
 	writel(reg, priv->sysctl_reg + 0x30);
 
 	return 0;
@@ -784,13 +799,14 @@
 
 static int sun8i_emac_eth_probe(struct udevice *dev)
 {
-	struct eth_pdata *pdata = dev_get_platdata(dev);
+	struct sun8i_eth_pdata *sun8i_pdata = dev_get_platdata(dev);
+	struct eth_pdata *pdata = &sun8i_pdata->eth_pdata;
 	struct emac_eth_dev *priv = dev_get_priv(dev);
 
 	priv->mac_reg = (void *)pdata->iobase;
 
 	sun8i_emac_board_setup(priv);
-	sun8i_emac_set_syscon(priv);
+	sun8i_emac_set_syscon(sun8i_pdata, priv);
 
 	sun8i_mdio_init(dev->name, dev);
 	priv->bus = miiphy_get_dev_by_name(dev->name);
@@ -891,6 +907,18 @@
 	if (!priv->use_internal_phy)
 		parse_phy_pins(dev);
 
+	sun8i_pdata->tx_delay_ps = fdtdec_get_int(gd->fdt_blob, node,
+						  "allwinner,tx-delay-ps", 0);
+	if (sun8i_pdata->tx_delay_ps < 0 || sun8i_pdata->tx_delay_ps > 700)
+		printf("%s: Invalid TX delay value %d\n", __func__,
+		       sun8i_pdata->tx_delay_ps);
+
+	sun8i_pdata->rx_delay_ps = fdtdec_get_int(gd->fdt_blob, node,
+						  "allwinner,rx-delay-ps", 0);
+	if (sun8i_pdata->rx_delay_ps < 0 || sun8i_pdata->rx_delay_ps > 3100)
+		printf("%s: Invalid RX delay value %d\n", __func__,
+		       sun8i_pdata->rx_delay_ps);
+
 #ifdef CONFIG_DM_GPIO
 	if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
 			    "snps,reset-active-low"))
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index d7568bc..2ca19d4 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -272,6 +272,14 @@
 		s++;    /* ; */
 		s = parsenum(s, &col);
 
+		/*
+		 * Video origin is [0, 0], terminal origin is [1, 1].
+		 */
+		if (row)
+			--row;
+		if (col)
+			--col;
+
 		set_cursor_position(priv, row, col);
 
 		break;
diff --git a/dts/Makefile b/dts/Makefile
index 9a9a3d5..cd6e9a9 100644
--- a/dts/Makefile
+++ b/dts/Makefile
@@ -61,4 +61,4 @@
 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
diff --git a/include/common.h b/include/common.h
index 3f69943..8b56137 100644
--- a/include/common.h
+++ b/include/common.h
@@ -549,11 +549,6 @@
 #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))
 
 /*
diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
index 5838eb3..555efb7 100644
--- a/include/config_distro_bootcmd.h
+++ b/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" \
diff --git a/include/configs/am65x_evm.h b/include/configs/am65x_evm.h
index 484c5ef..31749c6 100644
--- a/include/configs/am65x_evm.h
+++ b/include/configs/am65x_evm.h
@@ -29,7 +29,9 @@
 #define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME	"tispl.bin"
 #endif
 
+#ifndef CONFIG_CPU_V7R
 #define CONFIG_SKIP_LOWLEVEL_INIT
+#endif
 
 #define CONFIG_SPL_MAX_SIZE		CONFIG_SYS_K3_MAX_DOWNLODABLE_IMAGE_SIZE
 #define CONFIG_SYS_INIT_SP_ADDR         (CONFIG_SPL_TEXT_BASE +	\
diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h
index ba878eb..14a3046 100644
--- a/include/configs/da850evm.h
+++ b/include/configs/da850evm.h
@@ -124,8 +124,9 @@
 #ifdef CONFIG_SPL_BUILD
 #define CONFIG_SYS_SPI_BASE		DAVINCI_SPI1_BASE
 #define CONFIG_SF_DEFAULT_SPEED		30000000
-#define CONFIG_ENV_SPI_MAX_HZ	CONFIG_SF_DEFAULT_SPEED
 #endif
+#define CONFIG_ENV_SPI_MAX_HZ	0
+#define CONFIG_ENV_SPI_MODE	0
 
 #ifdef CONFIG_USE_SPIFLASH
 #define CONFIG_SYS_SPI_U_BOOT_OFFS	0x8000
diff --git a/include/configs/edminiv2.h b/include/configs/edminiv2.h
index 89aa11c..645fc3f 100644
--- a/include/configs/edminiv2.h
+++ b/include/configs/edminiv2.h
@@ -29,7 +29,6 @@
  * High Level Configuration Options (easy to change)
  */
 
-#define CONFIG_MARVELL		1
 #define CONFIG_FEROCEON		1	/* CPU Core subversion */
 #define CONFIG_88F5182		1	/* SOC Name */
 
diff --git a/include/configs/km/km_arm.h b/include/configs/km/km_arm.h
index e258517..0de83f6 100644
--- a/include/configs/km/km_arm.h
+++ b/include/configs/km/km_arm.h
@@ -22,7 +22,6 @@
 /*
  * High Level Configuration Options (easy to change)
  */
-#define CONFIG_MARVELL
 #define CONFIG_FEROCEON_88FR131		/* CPU Core subversion */
 #define CONFIG_KW88F6281		/* SOC Name */
 
diff --git a/include/configs/mv-common.h b/include/configs/mv-common.h
index 5eeb5a1..a803093 100644
--- a/include/configs/mv-common.h
+++ b/include/configs/mv-common.h
@@ -19,7 +19,6 @@
 /*
  * High Level Configuration Options (easy to change)
  */
-#define CONFIG_MARVELL		1
 
 /*
  * Custom CONFIG_SYS_TEXT_BASE can be done in <board>.h
diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h
index d279c23..b29d155 100644
--- a/include/configs/qemu-riscv.h
+++ b/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 */
diff --git a/include/configs/vexpress_common.h b/include/configs/vexpress_common.h
index 267b230..47ea89d 100644
--- a/include/configs/vexpress_common.h
+++ b/include/configs/vexpress_common.h
@@ -120,7 +120,7 @@
 #define CONFIG_INITRD_TAG		1
 
 /* Size of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 128 * 1024)
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 512 * 1024) /* >= 512 KiB */
 
 #define SCTL_BASE			V2M_SYSCTL
 #define VEXPRESS_FLASHPROG_FLVPPEN	(1 << 0)
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 2fc9fa3..92539b8 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -237,6 +237,16 @@
 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
  *
  * @ref:	valid node reference to read property from
diff --git a/include/environment/ti/boot.h b/include/environment/ti/boot.h
index 3c9c87f..5891009 100644
--- a/include/environment/ti/boot.h
+++ b/include/environment/ti/boot.h
@@ -34,9 +34,9 @@
 	"partitions_android=" \
 	"uuid_disk=${uuid_gpt_disk};" \
 	"name=xloader,start=128K,size=256K,uuid=${uuid_gpt_xloader};" \
-	"name=bootloader,size=1792K,uuid=${uuid_gpt_bootloader};" \
+	"name=bootloader,size=2048K,uuid=${uuid_gpt_bootloader};" \
+	"name=reserved,start=2432K,size=256K,uuid=${uuid_gpt_reserved};" \
 	"name=misc,size=128K,uuid=${uuid_gpt_misc};" \
-	"name=reserved,size=256K,uuid=${uuid_gpt_reserved};" \
 	"name=efs,size=16M,uuid=${uuid_gpt_efs};" \
 	"name=crypto,size=16K,uuid=${uuid_gpt_crypto};" \
 	"name=recovery,size=40M,uuid=${uuid_gpt_recovery};" \
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index abfb0ff..69bef5e 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -961,7 +961,6 @@
 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
@@ -1200,7 +1199,6 @@
 CONFIG_MALTA
 CONFIG_MARCO_MEMSET
 CONFIG_MARUBUN_PCCARD
-CONFIG_MARVELL
 CONFIG_MARVELL_GPIO
 CONFIG_MARVELL_MFP
 CONFIG_MASK_AER_AO
diff --git a/test/dm/video.c b/test/dm/video.c
index 7def338..5d1faac 100644
--- a/test/dm/video.c
+++ b/test/dm/video.c
@@ -178,12 +178,12 @@
 
 	/* test set-cursor: [%d;%df */
 	vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd");
-	ut_asserteq(142, compress_frame_buffer(dev));
+	ut_asserteq(143, compress_frame_buffer(dev));
 
 	/* test colors (30-37 fg color, 40-47 bg color) */
 	vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */
 	vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */
-	ut_asserteq(265, compress_frame_buffer(dev));
+	ut_asserteq(272, compress_frame_buffer(dev));
 
 	return 0;
 }
diff --git a/tools/.gitignore b/tools/.gitignore
index c8cdaef..e5ede22 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -24,6 +24,7 @@
 /mksunxiboot
 /mxsboot
 /ncb
+/prelink-riscv
 /proftool
 /relocate-rela
 /sunxi-spl-image-builder
diff --git a/tools/file2include.c b/tools/file2include.c
index b98af30..775440c 100644
--- a/tools/file2include.c
+++ b/tools/file2include.c
@@ -18,7 +18,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
-#include <malloc.h>
 
 /* Size of the blocks written to the compressed file */
 #define BLOCK_SIZE 8