Merge branch 'master' of https://gitlab.denx.de/u-boot/custodians/u-boot-sunxi

- SPL SPI support R40, H6 (Andre)
- eMMC boot part on a64-olinuxino (Petr)
diff --git a/MAINTAINERS b/MAINTAINERS
index 92dda40..b50652b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -527,6 +527,13 @@
 S:	Maintained
 F:	tools/binman/
 
+BTRFS
+M:	Marek Behun <marek.behun@nic.cz>
+S:	Maintained
+F:	cmd/btrfs.c
+F:	fs/btrfs/
+F:	include/btrfs.h
+
 BUILDMAN
 M:	Simon Glass <sjg@chromium.org>
 S:	Maintained
@@ -937,6 +944,7 @@
 F:	drivers/usb/
 F:	common/usb.c
 F:	common/usb_kbd.c
+F:	include/usb.h
 
 USB xHCI
 M:	Bin Meng <bmeng.cn@gmail.com>
diff --git a/arch/arm/dts/rv1108-elgin-r1.dts b/arch/arm/dts/rv1108-elgin-r1.dts
index 32b9594..83e8b31 100644
--- a/arch/arm/dts/rv1108-elgin-r1.dts
+++ b/arch/arm/dts/rv1108-elgin-r1.dts
@@ -40,9 +40,20 @@
 };
 
 &uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2m0_xfer_pullup>;
 	status = "okay";
 };
 
 &usb20_otg {
 	status = "okay";
 };
+
+&pinctrl {
+	uart2m0 {
+		uart2m0_xfer_pullup: uart2m0-xfer-pullup {
+			rockchip,pins = <2 RK_PD2 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
+					<2 RK_PD1 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
+		};
+	};
+};
diff --git a/arch/arm/dts/rv1108-u-boot.dtsi b/arch/arm/dts/rv1108-u-boot.dtsi
new file mode 100644
index 0000000..41ac054
--- /dev/null
+++ b/arch/arm/dts/rv1108-u-boot.dtsi
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include "rockchip-u-boot.dtsi"
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 3338b78..cc87da7 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -210,8 +210,21 @@
 	  Stack memory is pre-allocated. U-Boot must therefore know the
 	  maximum number of CPUs that may be present.
 
+config SBI
+	bool
+	default y if RISCV_SMODE || SPL_RISCV_SMODE
+
+config SBI_V01
+	bool "SBI v0.1 support"
+	default y
+	depends on SBI
+	help
+	  This config allows kernel to use SBI v0.1 APIs. This will be
+	  deprecated in future once legacy M-mode software are no longer in use.
+
 config SBI_IPI
 	bool
+	depends on SBI
 	default y if RISCV_SMODE || SPL_RISCV_SMODE
 	depends on SMP
 
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index ced57de..3595ee8 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) 2015 Regents of the University of California
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
  *
  * Taken from Linux arch/riscv/include/asm/sbi.h
  */
@@ -10,85 +11,113 @@
 
 #include <linux/types.h>
 
-#define SBI_SET_TIMER 0
-#define SBI_CONSOLE_PUTCHAR 1
-#define SBI_CONSOLE_GETCHAR 2
-#define SBI_CLEAR_IPI 3
-#define SBI_SEND_IPI 4
-#define SBI_REMOTE_FENCE_I 5
-#define SBI_REMOTE_SFENCE_VMA 6
-#define SBI_REMOTE_SFENCE_VMA_ASID 7
-#define SBI_SHUTDOWN 8
+enum sbi_ext_id {
+#ifdef CONFIG_SBI_V01
+	SBI_EXT_0_1_SET_TIMER = 0x0,
+	SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1,
+	SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2,
+	SBI_EXT_0_1_CLEAR_IPI = 0x3,
+	SBI_EXT_0_1_SEND_IPI = 0x4,
+	SBI_EXT_0_1_REMOTE_FENCE_I = 0x5,
+	SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6,
+	SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7,
+	SBI_EXT_0_1_SHUTDOWN = 0x8,
+#endif
+	SBI_EXT_BASE = 0x10,
+	SBI_EXT_TIME = 0x54494D45,
+	SBI_EXT_IPI = 0x735049,
+	SBI_EXT_RFENCE = 0x52464E43,
+};
 
-#define SBI_CALL(which, arg0, arg1, arg2) ({			\
-	register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0);	\
-	register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1);	\
-	register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2);	\
-	register uintptr_t a7 asm ("a7") = (uintptr_t)(which);	\
-	asm volatile ("ecall"					\
-		      : "+r" (a0)				\
-		      : "r" (a1), "r" (a2), "r" (a7)		\
-		      : "memory");				\
-	a0;							\
-})
+enum sbi_ext_base_fid {
+	SBI_EXT_BASE_GET_SPEC_VERSION = 0,
+	SBI_EXT_BASE_GET_IMP_ID,
+	SBI_EXT_BASE_GET_IMP_VERSION,
+	SBI_EXT_BASE_PROBE_EXT,
+	SBI_EXT_BASE_GET_MVENDORID,
+	SBI_EXT_BASE_GET_MARCHID,
+	SBI_EXT_BASE_GET_MIMPID,
+};
 
-/* Lazy implementations until SBI is finalized */
-#define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0)
-#define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0)
-#define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0)
+enum sbi_ext_time_fid {
+	SBI_EXT_TIME_SET_TIMER = 0,
+};
 
-static inline void sbi_console_putchar(int ch)
-{
-	SBI_CALL_1(SBI_CONSOLE_PUTCHAR, ch);
-}
+enum sbi_ext_ipi_fid {
+	SBI_EXT_IPI_SEND_IPI = 0,
+};
 
-static inline int sbi_console_getchar(void)
-{
-	return SBI_CALL_0(SBI_CONSOLE_GETCHAR);
-}
+enum sbi_ext_rfence_fid {
+	SBI_EXT_RFENCE_REMOTE_FENCE_I = 0,
+	SBI_EXT_RFENCE_REMOTE_SFENCE_VMA,
+	SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID,
+};
 
-static inline void sbi_set_timer(uint64_t stime_value)
-{
-#if __riscv_xlen == 32
-	SBI_CALL_2(SBI_SET_TIMER, stime_value, stime_value >> 32);
+#ifdef CONFIG_SBI_V01
+#define SBI_EXT_SET_TIMER		SBI_EXT_0_1_SET_TIMER
+#define SBI_FID_SET_TIMER		0
+#define SBI_EXT_SEND_IPI		SBI_EXT_0_1_SEND_IPI
+#define SBI_FID_SEND_IPI		0
+#define SBI_EXT_REMOTE_FENCE_I		SBI_EXT_0_1_REMOTE_FENCE_I
+#define SBI_FID_REMOTE_FENCE_I		0
+#define SBI_EXT_REMOTE_SFENCE_VMA	SBI_EXT_0_1_REMOTE_SFENCE_VMA
+#define SBI_FID_REMOTE_SFENCE_VMA	0
+#define SBI_EXT_REMOTE_SFENCE_VMA_ASID	SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID
+#define SBI_FID_REMOTE_SFENCE_VMA_ASID	0
 #else
-	SBI_CALL_1(SBI_SET_TIMER, stime_value);
+#define SBI_EXT_SET_TIMER		SBI_EXT_TIME
+#define SBI_FID_SET_TIMER		SBI_EXT_TIME_SET_TIMER
+#define SBI_EXT_SEND_IPI		SBI_EXT_IPI
+#define SBI_FID_SEND_IPI		SBI_EXT_IPI_SEND_IPI
+#define SBI_EXT_REMOTE_FENCE_I		SBI_EXT_RFENCE
+#define SBI_FID_REMOTE_FENCE_I		SBI_EXT_RFENCE_REMOTE_FENCE_I
+#define SBI_EXT_REMOTE_SFENCE_VMA	SBI_EXT_RFENCE
+#define SBI_FID_REMOTE_SFENCE_VMA	SBI_EXT_RFENCE_REMOTE_SFENCE_VMA
+#define SBI_EXT_REMOTE_SFENCE_VMA_ASID	SBI_EXT_RFENCE
+#define SBI_FID_REMOTE_SFENCE_VMA_ASID	SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID
 #endif
-}
 
-static inline void sbi_shutdown(void)
-{
-	SBI_CALL_0(SBI_SHUTDOWN);
-}
+#define SBI_SPEC_VERSION_DEFAULT	0x1
+#define SBI_SPEC_VERSION_MAJOR_SHIFT	24
+#define SBI_SPEC_VERSION_MAJOR_MASK	0x7f
+#define SBI_SPEC_VERSION_MINOR_MASK	0xffffff
 
-static inline void sbi_clear_ipi(void)
-{
-	SBI_CALL_0(SBI_CLEAR_IPI);
-}
+/* SBI return error codes */
+#define SBI_SUCCESS			0
+#define SBI_ERR_FAILURE			-1
+#define SBI_ERR_NOT_SUPPORTED		-2
+#define SBI_ERR_INVALID_PARAM		-3
+#define SBI_ERR_DENIED			-4
+#define SBI_ERR_INVALID_ADDRESS		-5
 
-static inline void sbi_send_ipi(const unsigned long *hart_mask)
-{
-	SBI_CALL_1(SBI_SEND_IPI, hart_mask);
-}
+extern unsigned long sbi_spec_version;
+struct sbiret {
+	long error;
+	long value;
+};
 
-static inline void sbi_remote_fence_i(const unsigned long *hart_mask)
-{
-	SBI_CALL_1(SBI_REMOTE_FENCE_I, hart_mask);
-}
+struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
+			unsigned long arg1, unsigned long arg2,
+			unsigned long arg3, unsigned long arg4,
+			unsigned long arg5);
 
-static inline void sbi_remote_sfence_vma(const unsigned long *hart_mask,
-					 unsigned long start,
-					 unsigned long size)
-{
-	SBI_CALL_1(SBI_REMOTE_SFENCE_VMA, hart_mask);
-}
+#ifdef CONFIG_SBI_V01
+void sbi_console_putchar(int ch);
+int sbi_console_getchar(void);
+void sbi_clear_ipi(void);
+void sbi_shutdown(void);
+#endif
+void sbi_set_timer(uint64_t stime_value);
+void sbi_send_ipi(const unsigned long *hart_mask);
+void sbi_remote_fence_i(const unsigned long *hart_mask);
+void sbi_remote_sfence_vma(const unsigned long *hart_mask,
+			   unsigned long start,
+			   unsigned long size);
+void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
+				unsigned long start,
+				unsigned long size,
+				unsigned long asid);
 
-static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
-					      unsigned long start,
-					      unsigned long size,
-					      unsigned long asid)
-{
-	SBI_CALL_1(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask);
-}
+int sbi_probe_extension(int ext);
 
 #endif
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index c9179a5..adadbf4 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -16,6 +16,7 @@
 obj-$(CONFIG_ANDES_PLMT) += andes_plmt.o
 else
 obj-$(CONFIG_RISCV_RDTIME) += rdtime.o
+obj-$(CONFIG_SBI) += sbi.o
 obj-$(CONFIG_SBI_IPI) += sbi_ipi.o
 endif
 obj-y	+= interrupts.o
diff --git a/arch/riscv/lib/sbi.c b/arch/riscv/lib/sbi.c
new file mode 100644
index 0000000..7bdf071
--- /dev/null
+++ b/arch/riscv/lib/sbi.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * SBI initialilization and all extension implementation.
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Taken from Linux arch/riscv/kernel/sbi.c
+ */
+
+#include <common.h>
+#include <asm/encoding.h>
+#include <asm/sbi.h>
+
+/* default SBI version is 0.1 */
+unsigned long sbi_spec_version = SBI_SPEC_VERSION_DEFAULT;
+
+struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
+			unsigned long arg1, unsigned long arg2,
+			unsigned long arg3, unsigned long arg4,
+			unsigned long arg5)
+{
+	struct sbiret ret;
+
+	register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0);
+	register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1);
+	register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2);
+	register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3);
+	register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4);
+	register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5);
+	register uintptr_t a6 asm ("a6") = (uintptr_t)(fid);
+	register uintptr_t a7 asm ("a7") = (uintptr_t)(ext);
+	asm volatile ("ecall"
+		      : "+r" (a0), "+r" (a1)
+		      : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
+		      : "memory");
+	ret.error = a0;
+	ret.value = a1;
+
+	return ret;
+}
+
+#ifdef CONFIG_SBI_V01
+
+/**
+ * sbi_console_putchar() - Writes given character to the console device.
+ * @ch: The data to be written to the console.
+ *
+ * Return: None
+ */
+void sbi_console_putchar(int ch)
+{
+	sbi_ecall(SBI_EXT_0_1_CONSOLE_PUTCHAR, 0, ch, 0, 0, 0, 0, 0);
+}
+
+/**
+ * sbi_console_getchar() - Reads a byte from console device.
+ *
+ * Returns the value read from console.
+ */
+int sbi_console_getchar(void)
+{
+	struct sbiret ret;
+
+	ret = sbi_ecall(SBI_EXT_0_1_CONSOLE_GETCHAR, 0, 0, 0, 0, 0, 0, 0);
+
+	return ret.error;
+}
+
+/**
+ * sbi_clear_ipi() - Clear any pending IPIs for the calling hart.
+ *
+ * Return: None
+ */
+void sbi_clear_ipi(void)
+{
+	sbi_ecall(SBI_EXT_0_1_CLEAR_IPI, 0, 0, 0, 0, 0, 0, 0);
+}
+
+/**
+ * sbi_shutdown() - Remove all the harts from executing supervisor code.
+ *
+ * Return: None
+ */
+void sbi_shutdown(void)
+{
+	sbi_ecall(SBI_EXT_0_1_SHUTDOWN, 0, 0, 0, 0, 0, 0, 0);
+}
+
+#endif /* CONFIG_SBI_V01 */
+
+/**
+ * sbi_set_timer() - Program the timer for next timer event.
+ * @stime_value: The value after which next timer event should fire.
+ *
+ * Return: None
+ */
+void sbi_set_timer(uint64_t stime_value)
+{
+#if __riscv_xlen == 32
+	sbi_ecall(SBI_EXT_SET_TIMER, SBI_FID_SET_TIMER, stime_value,
+		  stime_value >> 32, 0, 0, 0, 0);
+#else
+	sbi_ecall(SBI_EXT_SET_TIMER, SBI_FID_SET_TIMER, stime_value,
+		  0, 0, 0, 0, 0);
+#endif
+}
+
+/**
+ * sbi_send_ipi() - Send an IPI to any hart.
+ * @hart_mask: A cpu mask containing all the target harts.
+ *
+ * Return: None
+ */
+void sbi_send_ipi(const unsigned long *hart_mask)
+{
+	sbi_ecall(SBI_EXT_SEND_IPI, SBI_FID_SEND_IPI, (unsigned long)hart_mask,
+		  0, 0, 0, 0, 0);
+}
+
+/**
+ * sbi_remote_fence_i() - Execute FENCE.I instruction on given remote harts.
+ * @hart_mask: A cpu mask containing all the target harts.
+ *
+ * Return: None
+ */
+void sbi_remote_fence_i(const unsigned long *hart_mask)
+{
+	sbi_ecall(SBI_EXT_REMOTE_FENCE_I, SBI_FID_REMOTE_FENCE_I,
+		  (unsigned long)hart_mask, 0, 0, 0, 0, 0);
+}
+
+/**
+ * sbi_remote_sfence_vma() - Execute SFENCE.VMA instructions on given remote
+ *			     harts for the specified virtual address range.
+ * @hart_mask: A cpu mask containing all the target harts.
+ * @start: Start of the virtual address
+ * @size: Total size of the virtual address range.
+ *
+ * Return: None
+ */
+void sbi_remote_sfence_vma(const unsigned long *hart_mask,
+			   unsigned long start,
+			   unsigned long size)
+{
+	sbi_ecall(SBI_EXT_REMOTE_SFENCE_VMA, SBI_FID_REMOTE_SFENCE_VMA,
+		  (unsigned long)hart_mask, start, size, 0, 0, 0);
+}
+
+/**
+ * sbi_remote_sfence_vma_asid() - Execute SFENCE.VMA instructions on given
+ * remote harts for a virtual address range belonging to a specific ASID.
+ *
+ * @hart_mask: A cpu mask containing all the target harts.
+ * @start: Start of the virtual address
+ * @size: Total size of the virtual address range.
+ * @asid: The value of address space identifier (ASID).
+ *
+ * Return: None
+ */
+void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
+				unsigned long start,
+				unsigned long size,
+				unsigned long asid)
+{
+	sbi_ecall(SBI_EXT_REMOTE_SFENCE_VMA_ASID,
+		  SBI_FID_REMOTE_SFENCE_VMA_ASID,
+		  (unsigned long)hart_mask, start, size, asid, 0, 0);
+}
+
+/**
+ * sbi_probe_extension() - Check if an SBI extension ID is supported or not.
+ * @extid: The extension ID to be probed.
+ *
+ * Return: Extension specific nonzero value f yes, -ENOTSUPP otherwise.
+ */
+int sbi_probe_extension(int extid)
+{
+	struct sbiret ret;
+
+	ret = sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, extid,
+			0, 0, 0, 0, 0);
+	if (!ret.error)
+		if (ret.value)
+			return ret.value;
+
+	return -ENOTSUPP;
+}
diff --git a/arch/riscv/lib/sbi_ipi.c b/arch/riscv/lib/sbi_ipi.c
index 9a698ce..abafca9 100644
--- a/arch/riscv/lib/sbi_ipi.c
+++ b/arch/riscv/lib/sbi_ipi.c
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <asm/encoding.h>
 #include <asm/sbi.h>
 
 int riscv_send_ipi(int hart)
@@ -19,7 +20,7 @@
 
 int riscv_clear_ipi(int hart)
 {
-	sbi_clear_ipi();
+	csr_clear(CSR_SIP, SIP_SSIP);
 
 	return 0;
 }
diff --git a/board/elgin/elgin_rv1108/elgin_rv1108.c b/board/elgin/elgin_rv1108/elgin_rv1108.c
index 607667a..c5a1cc9 100644
--- a/board/elgin/elgin_rv1108/elgin_rv1108.c
+++ b/board/elgin/elgin_rv1108/elgin_rv1108.c
@@ -5,8 +5,9 @@
  */
 
 #include <common.h>
+#include <syscon.h>
 #include <asm/io.h>
-#include <fdtdec.h>
+#include <asm/arch-rockchip/clock.h>
 #include <asm/arch-rockchip/grf_rv1108.h>
 #include <asm/arch-rockchip/hardware.h>
 #include <asm/gpio.h>
@@ -15,7 +16,6 @@
 
 int mach_cpu_init(void)
 {
-	int node;
 	struct rv1108_grf *grf;
 	enum {
 		GPIO3C3_SHIFT           = 6,
@@ -35,8 +35,7 @@
 		GPIO2D1_UART2_SIN_M0,
 	};
 
-	node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "rockchip,rv1108-grf");
-	grf = (struct rv1108_grf *)fdtdec_get_addr(gd->fdt_blob, node, "reg");
+	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
 
 	/* Elgin board use UART2 m0 for debug*/
 	rk_clrsetreg(&grf->gpio2d_iomux,
@@ -50,7 +49,7 @@
 
 #define MODEM_ENABLE_GPIO 111
 
-int board_early_init_f(void)
+int rk_board_late_init(void)
 {
 	gpio_request(MODEM_ENABLE_GPIO, "modem_enable");
 	gpio_direction_output(MODEM_ENABLE_GPIO, 0);
diff --git a/board/rockchip/evb_rv1108/evb_rv1108.c b/board/rockchip/evb_rv1108/evb_rv1108.c
index 733f293..5d622c3 100644
--- a/board/rockchip/evb_rv1108/evb_rv1108.c
+++ b/board/rockchip/evb_rv1108/evb_rv1108.c
@@ -5,8 +5,9 @@
  */
 
 #include <common.h>
+#include <syscon.h>
 #include <asm/io.h>
-#include <fdtdec.h>
+#include <asm/arch-rockchip/clock.h>
 #include <asm/arch-rockchip/grf_rv1108.h>
 #include <asm/arch-rockchip/hardware.h>
 
@@ -14,7 +15,6 @@
 
 int mach_cpu_init(void)
 {
-	int node;
 	struct rv1108_grf *grf;
 	enum {
 		GPIO3C3_SHIFT           = 6,
@@ -34,8 +34,7 @@
 		GPIO2D1_UART2_SIN_M0,
 	};
 
-	node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "rockchip,rv1108-grf");
-	grf = (struct rv1108_grf *)fdtdec_get_addr(gd->fdt_blob, node, "reg");
+	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
 
 	/*evb board use UART2 m0 for debug*/
 	rk_clrsetreg(&grf->gpio2d_iomux,
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 24fc42a..3bbe2d6 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -149,6 +149,20 @@
 	return ret;
 }
 
+static void efi_reserve_memory(u64 addr, u64 size)
+{
+	u64 pages;
+
+	/* Convert from sandbox address space. */
+	addr = (uintptr_t)map_sysmem(addr, 0);
+	pages = efi_size_in_pages(size + (addr & EFI_PAGE_MASK));
+	addr &= ~EFI_PAGE_MASK;
+	if (efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE,
+			       false) != EFI_SUCCESS)
+		printf("Reserved memory mapping failed addr %llx size %llx\n",
+		       addr, size);
+}
+
 /**
  * efi_carve_out_dt_rsv() - Carve out DT reserved memory ranges
  *
@@ -161,7 +175,8 @@
 static void efi_carve_out_dt_rsv(void *fdt)
 {
 	int nr_rsv, i;
-	uint64_t addr, size, pages;
+	u64 addr, size;
+	int nodeoffset, subnode;
 
 	nr_rsv = fdt_num_mem_rsv(fdt);
 
@@ -169,15 +184,25 @@
 	for (i = 0; i < nr_rsv; i++) {
 		if (fdt_get_mem_rsv(fdt, i, &addr, &size) != 0)
 			continue;
-
-		/* Convert from sandbox address space. */
-		addr = (uintptr_t)map_sysmem(addr, 0);
+		efi_reserve_memory(addr, size);
+	}
 
-		pages = efi_size_in_pages(size + (addr & EFI_PAGE_MASK));
-		addr &= ~EFI_PAGE_MASK;
-		if (efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE,
-				       false) != EFI_SUCCESS)
-			printf("FDT memrsv map %d: Failed to add to map\n", i);
+	/* process reserved-memory */
+	nodeoffset = fdt_subnode_offset(fdt, 0, "reserved-memory");
+	if (nodeoffset >= 0) {
+		subnode = fdt_first_subnode(fdt, nodeoffset);
+		while (subnode >= 0) {
+			/* check if this subnode has a reg property */
+			addr = fdtdec_get_addr_size(fdt, subnode, "reg",
+						    (fdt_size_t *)&size);
+			/*
+			 * The /reserved-memory node may have children with
+			 * a size instead of a reg property.
+			 */
+			if (addr != FDT_ADDR_T_NONE)
+				efi_reserve_memory(addr, size);
+			subnode = fdt_next_subnode(fdt, subnode);
+		}
 	}
 }
 
@@ -263,9 +288,6 @@
 		return EFI_LOAD_ERROR;
 	}
 
-	/* Create memory reservations as indicated by the device tree */
-	efi_carve_out_dt_rsv(fdt);
-
 	/* Prepare device tree for payload */
 	ret = copy_fdt(&fdt);
 	if (ret) {
@@ -278,6 +300,9 @@
 		return EFI_LOAD_ERROR;
 	}
 
+	/* Create memory reservations as indicated by the device tree */
+	efi_carve_out_dt_rsv(fdt);
+
 	/* Install device tree as UEFI table */
 	ret = efi_install_configuration_table(&efi_guid_fdt, fdt);
 	if (ret != EFI_SUCCESS) {
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index 8c3681c..bb7c13d 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -12,6 +12,7 @@
 #include <exports.h>
 #include <hexdump.h>
 #include <malloc.h>
+#include <mapmem.h>
 #include <search.h>
 #include <linux/ctype.h>
 
@@ -488,9 +489,10 @@
 
 		printf("%-16s %.*llx-%.*llx", type,
 		       EFI_PHYS_ADDR_WIDTH,
-		       map->physical_start,
+		       (u64)map_to_sysmem((void *)map->physical_start),
 		       EFI_PHYS_ADDR_WIDTH,
-		       map->physical_start + map->num_pages * EFI_PAGE_SIZE);
+		       (u64)map_to_sysmem((void *)map->physical_start +
+					  map->num_pages * EFI_PAGE_SIZE));
 
 		print_memory_attributes(map->attribute);
 		putc('\n');
diff --git a/configs/elgin-rv1108_defconfig b/configs/elgin-rv1108_defconfig
index 62af763..b668299 100644
--- a/configs/elgin-rv1108_defconfig
+++ b/configs/elgin-rv1108_defconfig
@@ -4,12 +4,14 @@
 CONFIG_ENV_OFFSET=0x3F8000
 CONFIG_ROCKCHIP_RV1108=y
 CONFIG_TARGET_ELGIN_RV1108=y
+CONFIG_ROCKCHIP_BOOT_MODE_REG=0
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_DEBUG_UART_BASE=0x10210000
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_DEBUG_UART=y
 # CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_DEFAULT_FDT_FILE="rv1108-elgin-r1.dtb"
+CONFIG_BOARD_LATE_INIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_CMD_GPIO=y
diff --git a/configs/miqi-rk3288_defconfig b/configs/miqi-rk3288_defconfig
index edba9da..e3e205f 100644
--- a/configs/miqi-rk3288_defconfig
+++ b/configs/miqi-rk3288_defconfig
@@ -75,6 +75,7 @@
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
 CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_USB_KEYBOARD=y
 CONFIG_DM_VIDEO=y
 # CONFIG_VIDEO_BPP8 is not set
 CONFIG_DISPLAY=y
diff --git a/configs/roc-pc-rk3399_defconfig b/configs/roc-pc-rk3399_defconfig
index 659c67a..d540a17 100644
--- a/configs/roc-pc-rk3399_defconfig
+++ b/configs/roc-pc-rk3399_defconfig
@@ -56,5 +56,6 @@
 CONFIG_USB_ETHER_MCS7830=y
 CONFIG_USB_ETHER_RTL8152=y
 CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_USB_KEYBOARD=y
 CONFIG_SPL_TINY_MEMSET=y
 CONFIG_ERRNO_STR=y
diff --git a/configs/rock2_defconfig b/configs/rock2_defconfig
index bb12b32..cf71c85 100644
--- a/configs/rock2_defconfig
+++ b/configs/rock2_defconfig
@@ -74,6 +74,7 @@
 CONFIG_ROCKCHIP_USB2_PHY=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_USB_KEYBOARD=y
 CONFIG_DM_VIDEO=y
 # CONFIG_VIDEO_BPP8 is not set
 CONFIG_DISPLAY=y
diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig
index 50820ba..034d28e 100644
--- a/configs/tinker-rk3288_defconfig
+++ b/configs/tinker-rk3288_defconfig
@@ -80,6 +80,7 @@
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
 CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_USB_KEYBOARD=y
 CONFIG_DM_VIDEO=y
 CONFIG_DISPLAY=y
 CONFIG_VIDEO_ROCKCHIP=y
diff --git a/configs/tinker-s-rk3288_defconfig b/configs/tinker-s-rk3288_defconfig
index ab192cf..06c5d9b 100644
--- a/configs/tinker-s-rk3288_defconfig
+++ b/configs/tinker-s-rk3288_defconfig
@@ -80,6 +80,7 @@
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
 CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_USB_KEYBOARD=y
 CONFIG_DM_VIDEO=y
 # CONFIG_VIDEO_BPP8 is not set
 CONFIG_DISPLAY=y
diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c
index 1c616a2..966b427 100644
--- a/fs/ext4/ext4fs.c
+++ b/fs/ext4/ext4fs.c
@@ -288,7 +288,7 @@
 	if (cache->buf && cache->block == block && cache->size == size)
 		return 1;
 	ext_cache_fini(cache);
-	cache->buf = malloc(size);
+	cache->buf = memalign(ARCH_DMA_MINALIGN, size);
 	if (!cache->buf)
 		return 0;
 	if (!ext4fs_devread(block, 0, size, cache->buf)) {
diff --git a/include/configs/miqi_rk3288.h b/include/configs/miqi_rk3288.h
index c9691a0..e19fa90 100644
--- a/include/configs/miqi_rk3288.h
+++ b/include/configs/miqi_rk3288.h
@@ -7,7 +7,7 @@
 #define __CONFIG_H
 
 #define ROCKCHIP_DEVICE_SETTINGS \
-		"stdin=serial,cros-ec-keyb\0" \
+		"stdin=serial,usbkbd\0" \
 		"stdout=serial,vidconsole\0" \
 		"stderr=serial,vidconsole\0"
 
diff --git a/include/configs/roc-pc-rk3399.h b/include/configs/roc-pc-rk3399.h
index 3fd1062..d4cbc35 100644
--- a/include/configs/roc-pc-rk3399.h
+++ b/include/configs/roc-pc-rk3399.h
@@ -7,7 +7,7 @@
 #define __ROC_PC_RK3399_H
 
 #define ROCKCHIP_DEVICE_SETTINGS \
-		"stdin=serial,cros-ec-keyb\0" \
+		"stdin=serial,usbkbd\0" \
 		"stdout=serial,vidconsole\0" \
 		"stderr=serial,vidconsole\0"
 
diff --git a/include/configs/rock2.h b/include/configs/rock2.h
index 917caf4..9e4a669 100644
--- a/include/configs/rock2.h
+++ b/include/configs/rock2.h
@@ -7,7 +7,7 @@
 #define __CONFIG_H
 
 #define ROCKCHIP_DEVICE_SETTINGS \
-		"stdin=serial,cros-ec-keyb\0" \
+		"stdin=serial,usbkbd\0" \
 		"stdout=serial,vidconsole\0" \
 		"stderr=serial,vidconsole\0"
 
diff --git a/include/configs/tinker_rk3288.h b/include/configs/tinker_rk3288.h
index f1095cc..d239e3b 100644
--- a/include/configs/tinker_rk3288.h
+++ b/include/configs/tinker_rk3288.h
@@ -7,7 +7,7 @@
 #define __CONFIG_H
 
 #define ROCKCHIP_DEVICE_SETTINGS \
-		"stdin=serial,cros-ec-keyb\0" \
+		"stdin=serial,usbkbd\0" \
 		"stdout=serial,vidconsole\0" \
 		"stderr=serial,vidconsole\0"
 
diff --git a/include/configs/vyasa-rk3288.h b/include/configs/vyasa-rk3288.h
index e31dc77..c3521ca 100644
--- a/include/configs/vyasa-rk3288.h
+++ b/include/configs/vyasa-rk3288.h
@@ -9,7 +9,7 @@
 #define __CONFIG_H
 
 #define ROCKCHIP_DEVICE_SETTINGS \
-		"stdin=serial,cros-ec-keyb\0" \
+		"stdin=serial,usbkbd\0" \
 		"stdout=serial,vidconsole\0" \
 		"stderr=serial,vidconsole\0"
 
diff --git a/include/efi_api.h b/include/efi_api.h
index 3d1a6be..1c40ffc 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -57,6 +57,16 @@
 
 struct efi_event;
 
+/* OsIndicationsSupported flags */
+#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI		    0x0000000000000001
+#define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION		    0x0000000000000002
+#define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED  0x0000000000000004
+#define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED	    0x0000000000000008
+#define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED	    0x0000000000000010
+#define EFI_OS_INDICATIONS_START_OS_RECOVERY		    0x0000000000000020
+#define EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY	    0x0000000000000040
+#define EFI_OS_INDICATIONS_JSON_CONFIG_DATA_REFRESH	    0x0000000000000080
+
 /* EFI Boot Services table */
 #define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42
 struct efi_boot_services {
@@ -207,11 +217,11 @@
 #define CAPSULE_FLAGS_INITIATE_RESET		0x00040000
 
 struct efi_capsule_header {
-	efi_guid_t *capsule_guid;
+	efi_guid_t capsule_guid;
 	u32 header_size;
 	u32 flags;
 	u32 capsule_image_size;
-};
+} __packed;
 
 #define EFI_RT_SUPPORTED_GET_TIME			0x0001
 #define EFI_RT_SUPPORTED_SET_TIME			0x0002
@@ -262,7 +272,7 @@
 					    efi_uintn_t *data_size, void *data);
 	efi_status_t (EFIAPI *get_next_variable_name)(
 			efi_uintn_t *variable_name_size,
-			u16 *variable_name, const efi_guid_t *vendor);
+			u16 *variable_name, efi_guid_t *vendor);
 	efi_status_t (EFIAPI *set_variable)(u16 *variable_name,
 					    const efi_guid_t *vendor,
 					    u32 attributes,
@@ -1645,4 +1655,31 @@
 #define LOAD_OPTION_CATEGORY_BOOT	0x00000000
 #define LOAD_OPTION_CATEGORY_APP	0x00000100
 
+/*
+ * System Resource Table
+ */
+/* Firmware Type Definitions */
+#define ESRT_FW_TYPE_UNKNOWN		0x00000000
+#define ESRT_FW_TYPE_SYSTEMFIRMWARE	0x00000001
+#define ESRT_FW_TYPE_DEVICEFIRMWARE	0x00000002
+#define ESRT_FW_TYPE_UEFIDRIVER		0x00000003
+
+/* Last Attempt Status Values */
+#define LAST_ATTEMPT_STATUS_SUCCESS			0x00000000
+#define LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL		0x00000001
+#define LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES 0x00000002
+#define LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION	0x00000003
+#define LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT	0x00000004
+#define LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR		0x00000005
+#define LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_AC		0x00000006
+#define LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_BATT		0x00000007
+#define LAST_ATTEMPT_STATUS_ERROR_UNSATISFIED_DEPENDENCIES 0x00000008
+
+/*
+ * The LastAttemptStatus values of 0x1000 - 0x4000 are reserved for vendor
+ * usage.
+ */
+#define LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL_VENDOR_RANGE_MIN 0x00001000
+#define LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL_VENDOR_RANGE_MAX 0x00004000
+
 #endif
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 8e34379..3f27928 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -457,6 +457,20 @@
 /* Install multiple protocol interfaces */
 efi_status_t EFIAPI efi_install_multiple_protocol_interfaces
 				(efi_handle_t *handle, ...);
+/* Get handles that support a given protocol */
+efi_status_t EFIAPI efi_locate_handle_buffer(
+			enum efi_locate_search_type search_type,
+			const efi_guid_t *protocol, void *search_key,
+			efi_uintn_t *no_handles, efi_handle_t **buffer);
+/* Close an previously opened protocol interface */
+efi_status_t EFIAPI efi_close_protocol(efi_handle_t handle,
+				       const efi_guid_t *protocol,
+				       efi_handle_t agent_handle,
+				       efi_handle_t controller_handle);
+/* Open a protocol interface */
+efi_status_t EFIAPI efi_handle_protocol(efi_handle_t handle,
+					const efi_guid_t *protocol,
+					void **protocol_interface);
 /* Call this to create an event */
 efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
 			      void (EFIAPI *notify_function) (
@@ -631,7 +645,7 @@
 				     efi_uintn_t *data_size, void *data);
 efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size,
 					       u16 *variable_name,
-					       const efi_guid_t *vendor);
+					       efi_guid_t *vendor);
 efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
 				     const efi_guid_t *vendor, u32 attributes,
 				     efi_uintn_t data_size, const void *data);
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index e533a18..3b79a88 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -2106,10 +2106,10 @@
  *
  * Return: status code
  */
-static efi_status_t EFIAPI efi_close_protocol(efi_handle_t handle,
-					      const efi_guid_t *protocol,
-					      efi_handle_t agent_handle,
-					      efi_handle_t controller_handle)
+efi_status_t EFIAPI efi_close_protocol(efi_handle_t handle,
+				       const efi_guid_t *protocol,
+				       efi_handle_t agent_handle,
+				       efi_handle_t controller_handle)
 {
 	struct efi_handler *handler;
 	struct efi_open_protocol_info_item *item;
@@ -2282,7 +2282,7 @@
  *
  * Return: status code
  */
-static efi_status_t EFIAPI efi_locate_handle_buffer(
+efi_status_t EFIAPI efi_locate_handle_buffer(
 			enum efi_locate_search_type search_type,
 			const efi_guid_t *protocol, void *search_key,
 			efi_uintn_t *no_handles, efi_handle_t **buffer)
@@ -3182,9 +3182,9 @@
  *
  * Return: status code
  */
-static efi_status_t EFIAPI efi_handle_protocol(efi_handle_t handle,
-					       const efi_guid_t *protocol,
-					       void **protocol_interface)
+efi_status_t EFIAPI efi_handle_protocol(efi_handle_t handle,
+					const efi_guid_t *protocol,
+					void **protocol_interface)
 {
 	return efi_open_protocol(handle, protocol, protocol_interface, efi_root,
 				 NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index ed7fb3f..fc0682b 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -222,15 +222,17 @@
 	.flush_blocks = &efi_disk_flush_blocks,
 };
 
-/*
- * Get the simple file system protocol for a file device path.
+/**
+ * efi_fs_from_path() - retrieve simple file system protocol
+ *
+ * Gets the simple file system protocol for a file device path.
  *
  * The full path provided is split into device part and into a file
  * part. The device part is used to find the handle on which the
  * simple file system protocol is installed.
  *
- * @full_path	device path including device and file
- * @return	simple file system protocol
+ * @full_path:	device path including device and file
+ * Return:	simple file system protocol
  */
 struct efi_simple_file_system_protocol *
 efi_fs_from_path(struct efi_device_path *full_path)
@@ -285,15 +287,15 @@
 }
 
 /*
- * Create a handle for a partition or disk
+ * efi_disk_add_dev() - create a handle for a partition or disk
  *
- * @parent	parent handle
- * @dp_parent	parent device path
- * @if_typename interface name for block device
- * @desc	internal block device
- * @dev_index   device index for block device
- * @offset	offset into disk for simple partitions
- * @return	disk object
+ * @parent:		parent handle
+ * @dp_parent:		parent device path
+ * @if_typename:	interface name for block device
+ * @desc:		internal block device
+ * @dev_index:		device index for block device
+ * @offset:		offset into disk for simple partitions
+ * Return:		disk object
  */
 static efi_status_t efi_disk_add_dev(
 				efi_handle_t parent,
@@ -365,7 +367,7 @@
 	diskobj->media.block_size = desc->blksz;
 	diskobj->media.io_align = desc->blksz;
 	diskobj->media.last_block = desc->lba - offset;
-	if (part != 0)
+	if (part)
 		diskobj->media.logical_partition = 1;
 	diskobj->ops.media = &diskobj->media;
 	if (disk)
@@ -373,15 +375,17 @@
 	return EFI_SUCCESS;
 }
 
-/*
- * Create handles and protocols for the partitions of a block device
+/**
+ * efi_disk_create_partitions() - create handles and protocols for partitions
  *
- * @parent		handle of the parent disk
- * @blk_desc		block device
- * @if_typename		interface type
- * @diskid		device number
- * @pdevname		device name
- * @return		number of partitions created
+ * Create handles and protocols for the partitions of a block device.
+ *
+ * @parent:		handle of the parent disk
+ * @blk_desc:		block device
+ * @if_typename:	interface type
+ * @diskid:		device number
+ * @pdevname:		device name
+ * Return:		number of partitions created
  */
 int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
 			       const char *if_typename, int diskid,
@@ -418,16 +422,20 @@
 	return disks;
 }
 
-/*
+/**
+ * efi_disk_register() - register block devices
+ *
  * U-Boot doesn't have a list of all online disk devices. So when running our
  * EFI payload, we scan through all of the potentially available ones and
  * store them in our object pool.
  *
+ * This function is called in efi_init_obj_list().
+ *
  * TODO(sjg@chromium.org): Actually with CONFIG_BLK, U-Boot does have this.
  * Consider converting the code to look up devices as needed. The EFI device
  * could be a child of the UCLASS_BLK block device, perhaps.
  *
- * This gets called from do_bootefi_exec().
+ * Return:	status code
  */
 efi_status_t efi_disk_register(void)
 {
diff --git a/lib/efi_loader/efi_freestanding.c b/lib/efi_loader/efi_freestanding.c
index dcf5d1c..bd0dff1 100644
--- a/lib/efi_loader/efi_freestanding.c
+++ b/lib/efi_loader/efi_freestanding.c
@@ -47,7 +47,7 @@
 	u8 *d = dest;
 	const u8 *s = src;
 
-	if (d >= s) {
+	if (d <= s) {
 		for (; n; --n)
 			*d++ = *s++;
 	} else {
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index 4be5133..6a25acb 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -483,7 +483,7 @@
 }
 
 /**
- * efi_convert_pointer_runtime() - convert from physical to virtual pointer
+ * efi_convert_pointer() - convert from physical to virtual pointer
  *
  * This function implements the ConvertPointer() runtime service until
  * the first call to SetVirtualAddressMap().
@@ -493,7 +493,7 @@
  *
  * @debug_disposition:	indicates if pointer may be converted to NULL
  * @address:		pointer to be converted
- * Return:		status code EFI_UNSUPPORTED
+ * Return:		status code
  */
 static __efi_runtime efi_status_t EFIAPI efi_convert_pointer(
 			efi_uintn_t debug_disposition, void **address)
diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index c316bdf..fe2f264 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- *  EFI utils
+ * UEFI runtime variable services
  *
- *  Copyright (c) 2017 Rob Clark
+ * Copyright (c) 2017 Rob Clark
  */
 
 #include <common.h>
@@ -273,7 +273,8 @@
 					 u32 *attributes)
 {
 	char *guid, *name, *end, c;
-	unsigned long name_len;
+	size_t name_len;
+	efi_uintn_t old_variable_name_size;
 	u16 *p;
 
 	guid = strchr(variable, '_');
@@ -289,17 +290,17 @@
 		return EFI_INVALID_PARAMETER;
 
 	name_len = end - name;
-	if (*variable_name_size < (name_len + 1)) {
-		*variable_name_size = name_len + 1;
+	old_variable_name_size = *variable_name_size;
+	*variable_name_size = sizeof(u16) * (name_len + 1);
+	if (old_variable_name_size < *variable_name_size)
 		return EFI_BUFFER_TOO_SMALL;
-	}
+
 	end++; /* point to value */
 
 	/* variable name */
 	p = variable_name;
 	utf8_utf16_strncpy(&p, name, name_len);
 	variable_name[name_len] = 0;
-	*variable_name_size = name_len + 1;
 
 	/* guid */
 	c = *(name - 1);
@@ -329,7 +330,7 @@
  */
 efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size,
 					       u16 *variable_name,
-					       const efi_guid_t *vendor)
+					       efi_guid_t *vendor)
 {
 	char *native_name, *variable;
 	ssize_t name_len, list_len;
@@ -597,7 +598,7 @@
  */
 static efi_status_t __efi_runtime EFIAPI
 efi_get_next_variable_name_runtime(efi_uintn_t *variable_name_size,
-				   u16 *variable_name, const efi_guid_t *vendor)
+				   u16 *variable_name, efi_guid_t *vendor)
 {
 	return EFI_UNSUPPORTED;
 }
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index cf132c3..e9baa64 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -27,6 +27,7 @@
 efi_selftest_gop.o \
 efi_selftest_loaded_image.o \
 efi_selftest_manageprotocols.o \
+efi_selftest_mem.o \
 efi_selftest_memory.o \
 efi_selftest_open_protocol.o \
 efi_selftest_register_notify.o \
diff --git a/lib/efi_selftest/efi_selftest_mem.c b/lib/efi_selftest/efi_selftest_mem.c
new file mode 100644
index 0000000..51f0fec
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_mem.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * efi_selftest_memory
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * This unit test checks the following boottime services:
+ * CopyMem, SetMem, CalculateCrc32
+ *
+ * The memory type used for the device tree is checked.
+ */
+
+#include <efi_selftest.h>
+
+static struct efi_boot_services *boottime;
+
+/**
+ * setup() - setup unit test
+ *
+ * @handle:	handle of the loaded image
+ * @systable:	system table
+ * Return:	EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+		 const struct efi_system_table *systable)
+{
+	boottime = systable->boottime;
+
+	return EFI_ST_SUCCESS;
+}
+
+/*
+ * execute() - execute unit test
+ *
+ * Return:	EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+	u8 c1[] = "abcdefghijklmnop";
+	u8 c2[] = "abcdefghijklmnop";
+	u32 crc32;
+	efi_status_t ret;
+
+	ret = boottime->calculate_crc32(c1, 16, &crc32);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("CalculateCrc32 failed\n");
+		return EFI_ST_FAILURE;
+	}
+	if (crc32 != 0x943ac093) {
+		efi_st_error("CalculateCrc32 returned wrong value\n");
+		return EFI_ST_FAILURE;
+	}
+	boottime->copy_mem(&c1[5], &c1[3], 8);
+	if (memcmp(c1, "abcdedefghijknop", 16)) {
+		efi_st_error("CopyMem forward copy failed: %s\n", c1);
+		return EFI_ST_FAILURE;
+	}
+	boottime->copy_mem(&c2[3], &c2[5], 8);
+	if (memcmp(c2, "abcfghijklmlmnop", 16)) {
+		efi_st_error("CopyMem backward copy failed: %s\n", c2);
+		return EFI_ST_FAILURE;
+	}
+	boottime->set_mem(&c1[3], 8, 'x');
+	if (memcmp(c1, "abcxxxxxxxxjknop", 16)) {
+		efi_st_error("SetMem failed: %s\n", c1);
+		return EFI_ST_FAILURE;
+	}
+
+	return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(mem) = {
+	.name = "mem",
+	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+	.setup = setup,
+	.execute = execute,
+};
diff --git a/lib/efi_selftest/efi_selftest_variables.c b/lib/efi_selftest/efi_selftest_variables.c
index 5d98c02..2c16f3d 100644
--- a/lib/efi_selftest/efi_selftest_variables.c
+++ b/lib/efi_selftest/efi_selftest_variables.c
@@ -11,7 +11,7 @@
 #include <efi_selftest.h>
 
 #define EFI_ST_MAX_DATA_SIZE 16
-#define EFI_ST_MAX_VARNAME_SIZE 40
+#define EFI_ST_MAX_VARNAME_SIZE 80
 
 static struct efi_boot_services *boottime;
 static struct efi_runtime_services *runtime;
@@ -155,8 +155,14 @@
 			return EFI_ST_FAILURE;
 		}
 		if (!memcmp(&guid, &guid_vendor0, sizeof(efi_guid_t)) &&
-		    !efi_st_strcmp_16_8(varname, "efi_st_var0"))
+		    !efi_st_strcmp_16_8(varname, "efi_st_var0")) {
 			flag |= 1;
+			if (len != 24) {
+				efi_st_error("GetNextVariableName report wrong length %u, expected 24\n",
+					     (unsigned int)len);
+				return EFI_ST_FAILURE;
+			}
+		}
 		if (!memcmp(&guid, &guid_vendor1, sizeof(efi_guid_t)) &&
 		    !efi_st_strcmp_16_8(varname, "efi_st_var1"))
 			flag |= 2;
diff --git a/test/compression.c b/test/compression.c
index cf040d7..63f929f 100644
--- a/test/compression.c
+++ b/test/compression.c
@@ -451,7 +451,7 @@
 }
 
 /**
- * run_bootm_test() - Run tests on the bootm decopmression function
+ * run_bootm_test() - Run tests on the bootm decompression function
  *
  * @comp_type:	Compression type to test
  * @compress:	Our function to compress data
diff --git a/test/py/tests/test_mmc_rd.py b/test/py/tests/test_mmc_rd.py
index a25aa5f..ea652f9 100644
--- a/test/py/tests/test_mmc_rd.py
+++ b/test/py/tests/test_mmc_rd.py
@@ -56,7 +56,7 @@
         'info_mode': ???,
         'info_buswidth': ???.
     },
-}
+)
 
 # Configuration data for test_mmc_rd; defines regions of the MMC (entire
 # devices, or ranges of sectors) which can be read:
@@ -210,7 +210,7 @@
     assert good_response in response
     good_response = "Bus Speed: %s" % info_speed
     assert good_response in response
-    good_response = "Mode : %s" % info_mode
+    good_response = "Mode: %s" % info_mode
     assert good_response in response
     good_response = "Bus Width: %s" % info_buswidth
     assert good_response in response
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index c2382df..8f281f5 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -307,11 +307,13 @@
 					   rkcommon_offset_to_spi(hdr1_offset));
 
 	for (i = 0; i < ARRAY_SIZE(spl_infos); i++) {
-		if (!memcmp(&hdr1_sdmmc->magic, spl_infos[i].spl_hdr, 4)) {
+		if (!memcmp(&hdr1_sdmmc->magic, spl_infos[i].spl_hdr,
+			    RK_SPL_HDR_SIZE)) {
 			if (spl_info)
 				*spl_info = &spl_infos[i];
 			return IH_TYPE_RKSD;
-		} else if (!memcmp(&hdr1_spi->magic, spl_infos[i].spl_hdr, 4)) {
+		} else if (!memcmp(&hdr1_spi->magic, spl_infos[i].spl_hdr,
+				   RK_SPL_HDR_SIZE)) {
 			if (spl_info)
 				*spl_info = &spl_infos[i];
 			return IH_TYPE_RKSPI;