usb: gadget: f_sdp: Allow SPL to load and boot FIT via SDP
authorFrieder Schrempf <frieder.schrempf@kontron.de>
Tue, 4 Jun 2019 19:56:29 +0000 (21:56 +0200)
committerStefano Babic <sbabic@denx.de>
Thu, 27 Jun 2019 11:50:28 +0000 (13:50 +0200)
Add support for loading u-boot FIT images over the USB SDP protocol in
the SPL

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
[Various build fixes]
Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
Tested-by: Fabio Estevam <festevam@gmail.com>
Tested-by: Lukasz Majewski <lukma@denx.de>
common/spl/spl_sdp.c
drivers/usb/gadget/f_sdp.c
include/sdp.h

index 807256e908c2cc43eefcced065f7cb25b822f1b6..51b245b886262e253f516acb50cabed64437e112 100644 (file)
@@ -25,10 +25,14 @@ static int spl_sdp_load_image(struct spl_image_info *spl_image,
                return -ENODEV;
        }
 
-       /* This command typically does not return but jumps to an image */
-       sdp_handle(controller_index);
-       pr_err("SDP ended\n");
+       /*
+        * This command either loads a legacy image, jumps and never returns,
+        * or it loads a FIT image and returns it to be handled by the SPL
+        * code.
+        */
+       ret = spl_sdp_handle(controller_index, spl_image);
+       debug("SDP ended\n");
 
-       return -EINVAL;
+       return ret;
 }
 SPL_LOAD_IMAGE_METHOD("USB SDP", 0, BOOT_DEVICE_BOARD, spl_sdp_load_image);
index ae97ab2b497399ae8840fb12327b7f61c6581736..fab7ce6f97b202ed1881c34c57937bdbd11a515d 100644 (file)
@@ -638,7 +638,20 @@ static u32 sdp_jump_imxheader(void *address)
        return 0;
 }
 
-static void sdp_handle_in_ep(void)
+#ifdef CONFIG_SPL_BUILD
+#ifdef CONFIG_SPL_LOAD_FIT
+static ulong sdp_fit_read(struct spl_load_info *load, ulong sector,
+                         ulong count, void *buf)
+{
+       debug("%s: sector %lx, count %lx, buf %lx\n",
+             __func__, sector, count, (ulong)buf);
+       memcpy(buf, (void *)(load->dev + sector), count);
+       return count;
+}
+#endif
+#endif
+
+static void sdp_handle_in_ep(struct spl_image_info *spl_image)
 {
        u8 *data = sdp_func->in_req->buf;
        u32 status;
@@ -690,10 +703,25 @@ static void sdp_handle_in_ep(void)
                /* If imx header fails, try some U-Boot specific headers */
                if (status) {
 #ifdef CONFIG_SPL_BUILD
+                       image_header_t *header =
+                               sdp_ptr(sdp_func->jmp_address);
+#ifdef CONFIG_SPL_LOAD_FIT
+                       if (image_get_magic(header) == FDT_MAGIC) {
+                               struct spl_load_info load;
+
+                               debug("Found FIT\n");
+                               load.dev = header;
+                               load.bl_len = 1;
+                               load.read = sdp_fit_read;
+                               spl_load_simple_fit(spl_image, &load, 0,
+                                                   header);
+
+                               return;
+                       }
+#endif
                        /* In SPL, allow jumps to U-Boot images */
                        struct spl_image_info spl_image = {};
-                       spl_parse_image_header(&spl_image,
-                               (struct image_header *)sdp_func->jmp_address);
+                       spl_parse_image_header(&spl_image, header);
                        jump_to_image_no_args(&spl_image);
 #else
                        /* In U-Boot, allow jumps to scripts */
@@ -715,19 +743,32 @@ static void sdp_handle_in_ep(void)
        };
 }
 
-void sdp_handle(int controller_index)
+#ifndef CONFIG_SPL_BUILD
+int sdp_handle(int controller_index)
+#else
+int spl_sdp_handle(int controller_index, struct spl_image_info *spl_image)
+#endif
 {
        printf("SDP: handle requests...\n");
        while (1) {
                if (ctrlc()) {
                        puts("\rCTRL+C - Operation aborted.\n");
-                       return;
+                       return -EINVAL;
                }
 
+#ifdef CONFIG_SPL_BUILD
+               if (spl_image->flags & SPL_FIT_FOUND)
+                       return 0;
+#endif
+
                WATCHDOG_RESET();
                usb_gadget_handle_interrupts(controller_index);
 
-               sdp_handle_in_ep();
+#ifdef CONFIG_SPL_BUILD
+               sdp_handle_in_ep(spl_image);
+#else
+               sdp_handle_in_ep(NULL);
+#endif
        }
 }
 
index f6252d027f032fce8c11a44937e4221f795f9d37..6ac64fb1f31653172f95e6920a1ed0434c3cb085 100644 (file)
 #define __SDP_H_
 
 int sdp_init(int controller_index);
-void sdp_handle(int controller_index);
+
+#ifdef CONFIG_SPL_BUILD
+#include <spl.h>
+
+int spl_sdp_handle(int controller_index, struct spl_image_info *spl_image);
+#else
+int sdp_handle(int controller_index);
+#endif
 
 #endif /* __SDP_H_ */