This patch makes use of a new sunxi SPL header format, where
fields for passing data to U-Boot are reserved. This allows the
"fel" utility to provide specific pieces of information by
setting these fields (which will be evaluated by U-Boot then).

For now, we provide the memory location of the boot script file
(boot.scr) this way. A suitably modified U-Boot can adjust the
boot process accordingly and will auto-execute the script.

Signed-off-by: Bernhard Nortmann <[email protected]>
---
 fel.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 61 insertions(+), 1 deletion(-)

diff --git a/fel.c b/fel.c
index 7bfd25b..f697735 100644
--- a/fel.c
+++ b/fel.c
@@ -932,6 +932,60 @@ void aw_fel_process_spl_and_uboot(libusb_device_handle 
*usb,
                aw_fel_write_uboot_image(usb, buf + SPL_LEN_LIMIT, size - 
SPL_LEN_LIMIT);
 }
 
+/*
+ * Test the SPL header for our "sunxi" variant. We want to make sure that
+ * we can safely use specific header fields to pass information to U-Boot.
+ * In case of a missing signature (e.g. Allwinner boot0) or header version
+ * mismatch, this function will return "false". If all seems fine,
+ * the result is "true".
+ */
+#define SPL_SIGNATURE                  "SPL" /* marks "sunxi" header */
+#define SPL_MIN_VERSION                        1 /* minimum required version */
+#define SPL_MAX_VERSION                        1 /* maximum supported version 
*/
+int have_sunxi_spl(libusb_device_handle *usb, soc_sram_info *sram_info)
+{
+       uint8_t spl_signature[4];
+
+       aw_fel_read(usb, sram_info->spl_addr + 0x14,
+               &spl_signature, sizeof(spl_signature));
+
+       if (memcmp(spl_signature, SPL_SIGNATURE, 3) != 0)
+               return 0; /* signature mismatch, no "sunxi" SPL */
+
+       if (spl_signature[3] < SPL_MIN_VERSION) {
+               fprintf(stderr, "sunxi SPL version mismatch: "
+                       "found 0x%02X < required minimum 0x%02X\n",
+                       spl_signature[3], SPL_MIN_VERSION);
+               fprintf(stderr, "You need to update your U-Boot (mksunxiboot) 
to a more recent version.\n");
+               return 0;
+       }
+       if (spl_signature[3] > SPL_MAX_VERSION) {
+               fprintf(stderr, "sunxi SPL version mismatch: "
+                       "found 0x%02X > maximum supported 0x%02X\n",
+                       spl_signature[3], SPL_MAX_VERSION);
+               fprintf(stderr, "You need a more recent version of this 
(sunxi-tools) fel utility.\n");
+               return 0;
+       }
+       return 1; /* sunxi SPL and suitable version */
+}
+
+/*
+ * Pass information to U-Boot via specialized fields in the SPL header
+ * (see "boot_file_head" in ${U-BOOT}/tools/mksunxiboot.c), providing
+ * information about the boot script address (DRAM location of boot.scr).
+ */
+void pass_fel_information(libusb_device_handle *usb, soc_sram_info *sram_info,
+                         uint32_t script_address)
+{
+       /* write something _only_ if we have a suitable SPL header */
+       if (have_sunxi_spl(usb, sram_info)) {
+               pr_info("Passing boot info via sunxi SPL: script address = 
0x%08X\n",
+                       script_address);
+               aw_fel_write(usb, &script_address,
+                       sram_info->spl_addr + 0x18, sizeof(script_address));
+       }
+}
+
 static int aw_fel_get_endpoint(libusb_device_handle *usb)
 {
        struct libusb_device *dev = libusb_get_device(usb);
@@ -1073,13 +1127,19 @@ int main(int argc, char **argv)
                        double t1, t2;
                        size_t size;
                        void *buf = load_file(argv[3], &size);
+                       uint32_t offset = strtoul(argv[2], NULL, 0);
                        t1 = gettime();
-                       aw_fel_write(handle, buf, strtoul(argv[2], NULL, 0), 
size);
+                       aw_fel_write(handle, buf, offset, size);
                        t2 = gettime();
                        if (t2 > t1)
                                pr_info("Written %.1f KB in %.1f sec (speed: 
%.1f KB/s)\n",
                                        (double)size / 1000., t2 - t1,
                                        (double)size / (t2 - t1) / 1000.);
+
+                       /* If we have transferred a script, try to inform 
U-Boot about it. */
+                       if (get_image_type(buf, size) == IH_TYPE_SCRIPT)
+                               pass_fel_information(handle, sram_info, offset);
+
                        free(buf);
                        skip=3;
                } else if (strcmp(argv[1], "read") == 0 && argc > 4) {
-- 
2.4.6

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to