Merge tag 'fixes-for-2019.10' of https://gitlab.denx.de/u-boot/custodians/u-boot-video.git

- fix sunxi LCD clock divider
- fix splash logo with DM_VIDEO and CONFIG_VIDEO_LOGO
- fix splash banner output with DM_VIDEO
diff --git a/arch/arm/dts/rk3288-tinker-u-boot.dtsi b/arch/arm/dts/rk3288-tinker-u-boot.dtsi
index 2efb309..f7f9d6d 100644
--- a/arch/arm/dts/rk3288-tinker-u-boot.dtsi
+++ b/arch/arm/dts/rk3288-tinker-u-boot.dtsi
@@ -13,20 +13,20 @@
 	u-boot,dm-pre-reloc;
 };
 
+&uart2_xfer {
+	u-boot,dm-pre-reloc;
+};
+
 &sdmmc {
-	u-boot,dm-pre-reloc;
+	u-boot,dm-spl;
 };
 
-&emmc {
-	u-boot,dm-pre-reloc;
+&gpio7 {
+	u-boot,dm-spl;
 };
 
-&gpio3 {
-	u-boot,dm-pre-reloc;
-};
-
-&gpio8 {
-	u-boot,dm-pre-reloc;
+&vcc_sd {
+	u-boot,dm-spl;
 };
 
 &pcfg_pull_none_drv_8ma {
@@ -37,10 +37,22 @@
 	u-boot,dm-spl;
 };
 
+&pcfg_pull_none {
+	u-boot,dm-spl;
+};
+
+&pcfg_pull_up {
+	u-boot,dm-spl;
+};
+
 &sdmmc_bus4 {
 	u-boot,dm-spl;
 };
 
+&sdmmc_cd {
+	u-boot,dm-spl;
+};
+
 &sdmmc_clk {
 	u-boot,dm-spl;
 };
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index 87e3d34..4ebc079 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -104,7 +104,6 @@
 config TARGET_VYASA_RK3288
 	bool "Vyasa-RK3288"
 	select BOARD_LATE_INIT
-	select ROCKCHIP_BROM_HELPER
 	select TPL
 	help
 	  Vyasa is a RK3288-based development board with 2 USB ports,
diff --git a/arch/arm/mach-rockchip/spl-boot-order.c b/arch/arm/mach-rockchip/spl-boot-order.c
index c19c285..fa8e096 100644
--- a/arch/arm/mach-rockchip/spl-boot-order.c
+++ b/arch/arm/mach-rockchip/spl-boot-order.c
@@ -134,7 +134,7 @@
 		/* Try to resolve the config item (or alias) as a path */
 		node = fdt_path_offset(blob, conf);
 		if (node < 0) {
-			debug("%s: could not find %s in FDT", __func__, conf);
+			debug("%s: could not find %s in FDT\n", __func__, conf);
 			continue;
 		}
 
diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig
index 405fde0..7b0e908 100644
--- a/configs/evb-rk3288_defconfig
+++ b/configs/evb-rk3288_defconfig
@@ -5,6 +5,7 @@
 CONFIG_TARGET_EVB_RK3288=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_SPL_SIZE_LIMIT=307200
+CONFIG_SPL_STACK_R_ADDR=0x80000
 CONFIG_DEBUG_UART_BASE=0xff690000
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_DEBUG_UART=y
@@ -14,7 +15,8 @@
 CONFIG_DEFAULT_FDT_FILE="rk3288-evb-rk808.dtb"
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
-CONFIG_SPL_TEXT_BASE=0
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
diff --git a/configs/rockpro64-rk3399_defconfig b/configs/rockpro64-rk3399_defconfig
index 40ebad5..22b8bc5 100644
--- a/configs/rockpro64-rk3399_defconfig
+++ b/configs/rockpro64-rk3399_defconfig
@@ -9,6 +9,7 @@
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_DEBUG_UART=y
 CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-rockpro64.dtb"
+CONFIG_MISC_INIT_R=y
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
@@ -28,6 +29,8 @@
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_ROCKCHIP_EFUSE=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig
index 443f4d8..afee098 100644
--- a/configs/tinker-rk3288_defconfig
+++ b/configs/tinker-rk3288_defconfig
@@ -4,6 +4,7 @@
 CONFIG_ROCKCHIP_RK3288=y
 CONFIG_TARGET_TINKER_RK3288=y
 CONFIG_NR_DRAM_BANKS=1
+CONFIG_SPL_STACK_R_ADDR=0x80000
 CONFIG_SPL_SIZE_LIMIT=307200
 CONFIG_DEBUG_UART_BASE=0xff690000
 CONFIG_DEBUG_UART_CLOCK=24000000
@@ -15,7 +16,8 @@
 CONFIG_DEFAULT_FDT_FILE="rk3288-tinker.dtb"
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
-CONFIG_SPL_TEXT_BASE=0
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -47,7 +49,10 @@
 CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_SPL_I2C_SUPPORT=y
+CONFIG_SPL_POWER_SUPPORT=y
 CONFIG_MISC=y
 CONFIG_I2C_EEPROM=y
 CONFIG_MMC_DW=y
@@ -62,7 +67,9 @@
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_RK8XX=y
 CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_SPL_DM_REGULATOR=y
 CONFIG_REGULATOR_RK8XX=y
+CONFIG_SPL_DM_REGULATOR_FIXED=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_RAM=y
 CONFIG_SPL_RAM=y
diff --git a/configs/vyasa-rk3288_defconfig b/configs/vyasa-rk3288_defconfig
index c74c145..89921e6 100644
--- a/configs/vyasa-rk3288_defconfig
+++ b/configs/vyasa-rk3288_defconfig
@@ -15,7 +15,6 @@
 CONFIG_DEFAULT_FDT_FILE="rk3288-vyasa.dtb"
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
-CONFIG_SPL_TEXT_BASE=0xff704000
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
 CONFIG_CMD_GPIO=y
diff --git a/drivers/ram/rockchip/sdram_rk3288.c b/drivers/ram/rockchip/sdram_rk3288.c
index 6bb025a..5775254 100644
--- a/drivers/ram/rockchip/sdram_rk3288.c
+++ b/drivers/ram/rockchip/sdram_rk3288.c
@@ -79,7 +79,8 @@
 #define DQS_GATE_TRAINING_ERROR_RANK0	(1 << 4)
 #define DQS_GATE_TRAINING_ERROR_RANK1	(2 << 4)
 
-#ifdef CONFIG_SPL_BUILD
+#if defined(CONFIG_TPL_BUILD) || \
+	(!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
 static void copy_to_reg(u32 *dest, const u32 *src, u32 n)
 {
 	int i;
@@ -1035,7 +1036,8 @@
 
 static int rk3288_dmc_probe(struct udevice *dev)
 {
-#ifdef CONFIG_SPL_BUILD
+#if defined(CONFIG_TPL_BUILD) || \
+	(!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
 	struct rk3288_sdram_params *plat = dev_get_platdata(dev);
 	struct udevice *dev_clk;
 	struct regmap *map;
@@ -1044,7 +1046,8 @@
 	struct dram_info *priv = dev_get_priv(dev);
 
 	priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
-#ifdef CONFIG_SPL_BUILD
+#if defined(CONFIG_TPL_BUILD) || \
+	(!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
 	ret = conv_of_platdata(dev);
 	if (ret)
@@ -1111,12 +1114,14 @@
 	.id = UCLASS_RAM,
 	.of_match = rk3288_dmc_ids,
 	.ops = &rk3288_dmc_ops,
-#ifdef CONFIG_SPL_BUILD
+#if defined(CONFIG_TPL_BUILD) || \
+	(!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
 	.ofdata_to_platdata = rk3288_dmc_ofdata_to_platdata,
 #endif
 	.probe = rk3288_dmc_probe,
 	.priv_auto_alloc_size = sizeof(struct dram_info),
-#ifdef CONFIG_SPL_BUILD
+#if defined(CONFIG_TPL_BUILD) || \
+	(!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
 	.platdata_auto_alloc_size = sizeof(struct rk3288_sdram_params),
 #endif
 };
diff --git a/include/charset.h b/include/charset.h
index 020f8a9..fde6bdd 100644
--- a/include/charset.h
+++ b/include/charset.h
@@ -168,6 +168,21 @@
  */
 s32 utf_to_upper(const s32 code);
 
+/*
+ * u16_strncmp() - compare two u16 string
+ *
+ * @s1:		first string to compare
+ * @s2:		second string to compare
+ * @n:		maximum number of u16 to compare
+ * Return:	0  if the first n u16 are the same in s1 and s2
+ *		< 0 if the first different u16 in s1 is less than the
+ *		corresponding u16 in s2
+ *		> 0 if the first different u16 in s1 is greater than the
+ *		corresponding u16 in s2
+ */
+int u16_strncmp(const u16 *s1, const u16 *s2, size_t n);
+#define u16_strcmp(s1, s2)	u16_strncmp((s1), (s2), SIZE_MAX)
+
 /**
  * u16_strlen - count non-zero words
  *
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h
index bcda769..910fe58 100644
--- a/include/configs/rk3288_common.h
+++ b/include/configs/rk3288_common.h
@@ -9,7 +9,7 @@
 #include <asm/arch-rockchip/hardware.h>
 #include "rockchip-common.h"
 
-#define CONFIG_SYS_BOOTM_LEN (16 << 20) /* 16MB */
+#define CONFIG_SYS_BOOTM_LEN		(64 << 20) /* 64MB */
 
 #define CONFIG_SKIP_LOWLEVEL_INIT_ONLY
 #define CONFIG_SYS_CBSIZE		1024
diff --git a/include/efi_loader.h b/include/efi_loader.h
index dd24a27..53b3699 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -24,6 +24,10 @@
 #define U_BOOT_GUID \
 	EFI_GUID(0xe61d73b9, 0xa384, 0x4acc, \
 		 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, 0x62, 0x8b)
+/* GUID used as host device on sandbox */
+#define U_BOOT_HOST_DEV_GUID \
+	EFI_GUID(0xbbe4e671, 0x5773, 0x4ea1, \
+		 0x9a, 0xab, 0x3a, 0x7d, 0xbf, 0x40, 0xc4, 0x82)
 
 /* Root node */
 extern efi_handle_t efi_root;
@@ -121,6 +125,10 @@
 
 /* GUID of the U-Boot root node */
 extern const efi_guid_t efi_u_boot_guid;
+#ifdef CONFIG_SANDBOX
+/* GUID of U-Boot host device on sandbox */
+extern const efi_guid_t efi_guid_host_dev;
+#endif
 /* GUID of the EFI_BLOCK_IO_PROTOCOL */
 extern const efi_guid_t efi_block_io_guid;
 extern const efi_guid_t efi_global_variable_guid;
diff --git a/lib/charset.c b/lib/charset.c
index 72d745d..1c6a7f6 100644
--- a/lib/charset.c
+++ b/lib/charset.c
@@ -335,6 +335,31 @@
 	return ret;
 }
 
+/*
+ * u16_strncmp() - compare two u16 string
+ *
+ * @s1:		first string to compare
+ * @s2:		second string to compare
+ * @n:		maximum number of u16 to compare
+ * Return:	0  if the first n u16 are the same in s1 and s2
+ *		< 0 if the first different u16 in s1 is less than the
+ *		corresponding u16 in s2
+ *		> 0 if the first different u16 in s1 is greater than the
+ *		corresponding u16 in s2
+ */
+int u16_strncmp(const u16 *s1, const u16 *s2, size_t n)
+{
+	int ret = 0;
+
+	for (; n; --n, ++s1, ++s2) {
+		ret = *s1 - *s2;
+		if (ret || !*s1)
+			break;
+	}
+
+	return ret;
+}
+
 size_t u16_strlen(const void *in)
 {
 	const char *pos = in;
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index b9bff89..493d906 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -3499,7 +3499,6 @@
 	efi_handle_t *child_handle_buffer = NULL;
 	size_t number_of_children = 0;
 	efi_status_t r;
-	size_t stop_count = 0;
 	struct efi_object *efiobj;
 
 	EFI_ENTRY("%p, %p, %p", controller_handle, driver_image_handle,
@@ -3539,32 +3538,35 @@
 				       (void **)&binding_protocol,
 				       driver_image_handle, NULL,
 				       EFI_OPEN_PROTOCOL_GET_PROTOCOL));
-	if (r != EFI_SUCCESS)
+	if (r != EFI_SUCCESS) {
+		r = EFI_INVALID_PARAMETER;
 		goto out;
+	}
 	/* Remove the children */
 	if (number_of_children) {
 		r = EFI_CALL(binding_protocol->stop(binding_protocol,
 						    controller_handle,
 						    number_of_children,
 						    child_handle_buffer));
-		if (r == EFI_SUCCESS)
-			++stop_count;
+		if (r != EFI_SUCCESS) {
+			r = EFI_DEVICE_ERROR;
+			goto out;
+		}
 	}
 	/* Remove the driver */
-	if (!child_handle)
+	if (!child_handle) {
 		r = EFI_CALL(binding_protocol->stop(binding_protocol,
 						    controller_handle,
 						    0, NULL));
-	if (r == EFI_SUCCESS)
-		++stop_count;
+		if (r != EFI_SUCCESS) {
+			r = EFI_DEVICE_ERROR;
+			goto out;
+		}
+	}
 	EFI_CALL(efi_close_protocol(driver_image_handle,
 				    &efi_guid_driver_binding_protocol,
 				    driver_image_handle, NULL));
-
-	if (stop_count)
-		r = EFI_SUCCESS;
-	else
-		r = EFI_NOT_FOUND;
+	r = EFI_SUCCESS;
 out:
 	if (!child_handle)
 		free(child_handle_buffer);
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index ea39f13..86297bb 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -12,8 +12,13 @@
 #include <mmc.h>
 #include <efi_loader.h>
 #include <part.h>
+#include <sandboxblockdev.h>
 #include <asm-generic/unaligned.h>
 
+#ifdef CONFIG_SANDBOX
+const efi_guid_t efi_guid_host_dev = U_BOOT_HOST_DEV_GUID;
+#endif
+
 /* template END node: */
 static const struct efi_device_path END = {
 	.type     = DEVICE_PATH_TYPE_END,
@@ -446,6 +451,16 @@
 			return dp_size(dev->parent) +
 				sizeof(struct efi_device_path_sd_mmc_path);
 #endif
+#ifdef CONFIG_SANDBOX
+		case UCLASS_ROOT:
+			 /*
+			  * Sandbox's host device will be represented
+			  * as vendor device with extra one byte for
+			  * device number
+			  */
+			return dp_size(dev->parent)
+				+ sizeof(struct efi_device_path_vendor) + 1;
+#endif
 		default:
 			return dp_size(dev->parent);
 		}
@@ -505,6 +520,24 @@
 #ifdef CONFIG_BLK
 	case UCLASS_BLK:
 		switch (dev->parent->uclass->uc_drv->id) {
+#ifdef CONFIG_SANDBOX
+		case UCLASS_ROOT: {
+			/* stop traversing parents at this point: */
+			struct efi_device_path_vendor *dp = buf;
+			struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+			dp_fill(buf, dev->parent);
+			dp = buf;
+			++dp;
+			dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
+			dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
+			dp->dp.length = sizeof(*dp) + 1;
+			memcpy(&dp->guid, &efi_guid_host_dev,
+			       sizeof(efi_guid_t));
+			dp->vendor_data[0] = desc->devnum;
+			return &dp->vendor_data[1];
+			}
+#endif
 #ifdef CONFIG_IDE
 		case UCLASS_IDE: {
 			struct efi_device_path_atapi *dp =
diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index 6687b69..48ee255 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -424,17 +424,17 @@
 				     efi_uintn_t data_size, const void *data)
 {
 	char *native_name = NULL, *val = NULL, *s;
+	const char *old_val;
+	size_t old_size;
 	efi_status_t ret = EFI_SUCCESS;
 	u32 attr;
 
 	EFI_ENTRY("\"%ls\" %pUl %x %zu %p", variable_name, vendor, attributes,
 		  data_size, data);
 
-	/* TODO: implement APPEND_WRITE */
 	if (!variable_name || !*variable_name || !vendor ||
 	    ((attributes & EFI_VARIABLE_RUNTIME_ACCESS) &&
-	     !(attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS)) ||
-	    (attributes & EFI_VARIABLE_APPEND_WRITE)) {
+	     !(attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS))) {
 		ret = EFI_INVALID_PARAMETER;
 		goto out;
 	}
@@ -445,35 +445,51 @@
 
 #define ACCESS_ATTR (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)
 
-	if ((data_size == 0) || !(attributes & ACCESS_ATTR)) {
-		/* delete the variable: */
-		env_set(native_name, NULL);
-		ret = EFI_SUCCESS;
-		goto out;
-	}
+	old_val = env_get(native_name);
+	if (old_val) {
+		old_val = parse_attr(old_val, &attr);
 
-	val = env_get(native_name);
-	if (val) {
-		parse_attr(val, &attr);
-
-		/* We should not free val */
-		val = NULL;
+		/* check read-only first */
 		if (attr & READ_ONLY) {
 			ret = EFI_WRITE_PROTECTED;
 			goto out;
 		}
 
-		/*
-		 * attributes won't be changed
-		 * TODO: take care of APPEND_WRITE once supported
-		 */
-		if (attr != attributes) {
+		if ((data_size == 0) || !(attributes & ACCESS_ATTR)) {
+			/* delete the variable: */
+			env_set(native_name, NULL);
+			ret = EFI_SUCCESS;
+			goto out;
+		}
+
+		/* attributes won't be changed */
+		if (attr != (attributes & ~EFI_VARIABLE_APPEND_WRITE)) {
 			ret = EFI_INVALID_PARAMETER;
 			goto out;
 		}
+
+		if (attributes & EFI_VARIABLE_APPEND_WRITE) {
+			if (!prefix(old_val, "(blob)")) {
+				return EFI_DEVICE_ERROR;
+				goto out;
+			}
+			old_size = strlen(old_val);
+		} else {
+			old_size = 0;
+		}
+	} else {
+		if ((data_size == 0) || !(attributes & ACCESS_ATTR) ||
+		    (attributes & EFI_VARIABLE_APPEND_WRITE)) {
+			/* delete, but nothing to do */
+			ret = EFI_NOT_FOUND;
+			goto out;
+		}
+
+		old_size = 0;
 	}
 
-	val = malloc(2 * data_size + strlen("{ro,run,boot,nv}(blob)") + 1);
+	val = malloc(old_size + 2 * data_size
+		     + strlen("{ro,run,boot,nv}(blob)") + 1);
 	if (!val) {
 		ret = EFI_OUT_OF_RESOURCES;
 		goto out;
@@ -481,10 +497,7 @@
 
 	s = val;
 
-	/*
-	 * store attributes
-	 * TODO: several attributes are not supported
-	 */
+	/* store attributes */
 	attributes &= (EFI_VARIABLE_NON_VOLATILE |
 		       EFI_VARIABLE_BOOTSERVICE_ACCESS |
 		       EFI_VARIABLE_RUNTIME_ACCESS);
@@ -505,8 +518,13 @@
 	}
 	s += sprintf(s, "}");
 
+	if (old_size)
+		/* APPEND_WRITE */
+		s += sprintf(s, old_val);
+	else
+		s += sprintf(s, "(blob)");
+
 	/* store payload: */
-	s += sprintf(s, "(blob)");
 	s = bin2hex(s, data, data_size);
 	*s = '\0';
 
diff --git a/lib/efi_selftest/efi_selftest_variables.c b/lib/efi_selftest/efi_selftest_variables.c
index 06c1a03..a6b41d1 100644
--- a/lib/efi_selftest/efi_selftest_variables.c
+++ b/lib/efi_selftest/efi_selftest_variables.c
@@ -21,6 +21,9 @@
 static const efi_guid_t guid_vendor1 =
 	EFI_GUID(0xff629290, 0x1fc1, 0xd73f,
 		 0x8f, 0xb1, 0x32, 0xf9, 0x0c, 0xa0, 0x42, 0xea);
+static const efi_guid_t guid_global =
+	EFI_GUID(0x8be4df61, 0x93ca, 0x11d2,
+		 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c);
 
 /*
  * Setup unit test.
@@ -116,7 +119,7 @@
 				    EFI_VARIABLE_APPEND_WRITE,
 				    7, v + 8);
 	if (ret != EFI_SUCCESS) {
-		efi_st_todo("SetVariable(APPEND_WRITE) failed\n");
+		efi_st_error("SetVariable(APPEND_WRITE) failed\n");
 	} else {
 		len = EFI_ST_MAX_DATA_SIZE;
 		ret = runtime->get_variable(L"efi_st_var1", &guid_vendor1,
@@ -131,6 +134,21 @@
 		if (memcmp(data, v, len))
 			efi_st_todo("GetVariable returned wrong value\n");
 	}
+	/* Append variable 2 */
+	ret = runtime->set_variable(L"efi_none", &guid_vendor1,
+				    EFI_VARIABLE_BOOTSERVICE_ACCESS |
+				    EFI_VARIABLE_APPEND_WRITE,
+				    15, v);
+	if (ret != EFI_NOT_FOUND)
+		efi_st_error("SetVariable(APPEND_WRITE) with size 0 to non-existent variable returns wrong code\n");
+	/* Append variable 3 */
+	ret = runtime->set_variable(L"PlatformLangCodes", &guid_global,
+				    EFI_VARIABLE_BOOTSERVICE_ACCESS |
+				    EFI_VARIABLE_RUNTIME_ACCESS |
+				    EFI_VARIABLE_APPEND_WRITE,
+				    15, v);
+	if (ret != EFI_WRITE_PROTECTED)
+		efi_st_todo("SetVariable(APPEND_WRITE) to read-only variable returns wrong code\n");
 	/* Enumerate variables */
 	boottime->set_mem(&guid, 16, 0);
 	*varname = 0;
diff --git a/test/unicode_ut.c b/test/unicode_ut.c
index 1ccd36e..8875cdc 100644
--- a/test/unicode_ut.c
+++ b/test/unicode_ut.c
@@ -567,6 +567,19 @@
 }
 UNICODE_TEST(unicode_test_utf_to_upper);
 
+static int unicode_test_u16_strncmp(struct unit_test_state *uts)
+{
+	ut_assert(u16_strncmp(L"abc", L"abc", 3) == 0);
+	ut_assert(u16_strncmp(L"abcdef", L"abcghi", 3) == 0);
+	ut_assert(u16_strncmp(L"abcdef", L"abcghi", 6) < 0);
+	ut_assert(u16_strncmp(L"abcghi", L"abcdef", 6) > 0);
+	ut_assert(u16_strcmp(L"abc", L"abc") == 0);
+	ut_assert(u16_strcmp(L"abcdef", L"deghi") < 0);
+	ut_assert(u16_strcmp(L"deghi", L"abcdef") > 0);
+	return 0;
+}
+UNICODE_TEST(unicode_test_u16_strncmp);
+
 int do_ut_unicode(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	struct unit_test *tests = ll_entry_start(struct unit_test, unicode_test);