sunxi: FEL - Add the ability to recognize and auto-import uEnv-style data

The patch converts one of the "reserved" fields in the sunxi SPL
header to a fel_uEnv_length entry. When booting over USB ("FEL
mode"), this enables the sunxi-fel utility to pass the string
length of uEnv.txt compatible data; at the same time requesting
that this data be imported into the U-Boot environment.

If parse_spl_header() in the sunxi board.c encounters a non-zero
value in this header field, it will therefore call himport_r() to
merge the string (lines) passed via FEL into the default settings.
Environment vars can be changed this way even before U-Boot will
attempt to autoboot - specifically, this also allows overriding
"bootcmd".

With fel_script_addr set and a zero fel_uEnv_length, U-Boot is
safe to assume that data in .scr format (a mkimage-type script)
was passed at fel_script_addr, and will handle it using the
existing mechanism ("bootcmd_fel").

Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
Acked-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
index ec73379..5d7ab55 100644
--- a/arch/arm/include/asm/arch-sunxi/spl.h
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -51,7 +51,14 @@
 		uint8_t spl_signature[4];
 	};
 	uint32_t fel_script_address;
-	uint32_t reserved1[3];
+	/*
+	 * If the fel_uEnv_length member below is set to a non-zero value,
+	 * it specifies the size (byte count) of data at fel_script_address.
+	 * At the same time this indicates that the data is in uEnv.txt
+	 * compatible format, ready to be imported via "env import -t".
+	 */
+	uint32_t fel_uEnv_length;
+	uint32_t reserved1[2];
 	uint32_t boot_media;		/* written here by the boot ROM */
 	uint32_t reserved2[5];		/* padding, align to 64 bytes */
 };
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index c8bf316..78dfda5 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -573,6 +573,7 @@
 
 #if !defined(CONFIG_SPL_BUILD)
 #include <asm/arch/spl.h>
+#include <environment.h>
 
 /*
  * Check the SPL header for the "sunxi" variant. If found: parse values
@@ -582,17 +583,29 @@
 static void parse_spl_header(const uint32_t spl_addr)
 {
 	struct boot_file_head *spl = (void *)(ulong)spl_addr;
-	if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) == 0) {
-		uint8_t spl_header_version = spl->spl_signature[3];
-		if (spl_header_version == SPL_HEADER_VERSION) {
-			if (spl->fel_script_address)
-				setenv_hex("fel_scriptaddr",
-					   spl->fel_script_address);
-			return;
-		}
+	if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) != 0)
+		return; /* signature mismatch, no usable header */
+
+	uint8_t spl_header_version = spl->spl_signature[3];
+	if (spl_header_version != SPL_HEADER_VERSION) {
 		printf("sunxi SPL version mismatch: expected %u, got %u\n",
 		       SPL_HEADER_VERSION, spl_header_version);
+		return;
+	}
+	if (!spl->fel_script_address)
+		return;
+
+	if (spl->fel_uEnv_length != 0) {
+		/*
+		 * data is expected in uEnv.txt compatible format, so "env
+		 * import -t" the string(s) at fel_script_address right away.
+		 */
+		himport_r(&env_htab, (char *)spl->fel_script_address,
+			  spl->fel_uEnv_length, '\n', H_NOCLEAR, 0, 0, NULL);
+		return;
 	}
+	/* otherwise assume .scr format (mkimage-type script) */
+	setenv_hex("fel_scriptaddr", spl->fel_script_address);
 }
 #endif