#include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/gpio.h>
+#include <asm/arch/spl.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/timer.h>
 #include <asm/arch/tzpc.h>
         * binary over USB. If it is found, it determines where SPL was
         * read from.
         */
-       if (readl(4) != 0x4E4F4765 || readl(8) != 0x3054422E) /* eGON.BT0 */
+       if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
                return BOOT_DEVICE_BOARD;
 
        /* The BROM will try to boot from mmc0 first, so try that first. */
 
 #define SPL_SIGNATURE          "SPL" /* marks "sunxi" SPL header */
 #define SPL_HEADER_VERSION     1
 
+/* Note: A80 will require special handling here: SPL_ADDR 0x10000 */
+#define SPL_ADDR               0x0
+
 /* boot head definition from sun4i boot code */
 struct boot_file_head {
        uint32_t b_instruction; /* one intruction jumping to real code */
        uint32_t reserved;              /* padding, align to 32 bytes */
 };
 
+#define is_boot0_magic(addr)   (memcmp((void *)addr, BOOT0_MAGIC, 8) == 0)
+
 #endif
 
 }
 #endif
 
+#if !defined(CONFIG_SPL_BUILD)
+#include <asm/arch/spl.h>
+
+/*
+ * Check the SPL header for the "sunxi" variant. If found: parse values
+ * that might have been passed by the loader ("fel" utility), and update
+ * the environment accordingly.
+ */
+static void parse_spl_header(const uint32_t spl_addr)
+{
+       struct boot_file_head *spl = (void *)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;
+               }
+               printf("sunxi SPL version mismatch: expected %u, got %u\n",
+                      SPL_HEADER_VERSION, spl_header_version);
+       }
+}
+#endif
+
 #ifdef CONFIG_MISC_INIT_R
 int misc_init_r(void)
 {
        uint8_t mac_addr[6];
        int ret;
 
+#if !defined(CONFIG_SPL_BUILD)
+       setenv("fel_booted", NULL);
+       setenv("fel_scriptaddr", NULL);
+       /* determine if we are running in FEL mode */
+       if (!is_boot0_magic(SPL_ADDR + 4)) { /* eGON.BT0 */
+               setenv("fel_booted", "1");
+               parse_spl_header(SPL_ADDR);
+       }
+#endif
+
        ret = sunxi_get_sid(sid);
        if (ret == 0 && sid[0] != 0 && sid[3] != 0) {
                if (!getenv("ethaddr")) {