MLK-20559-6 f_sdp: Support searching and loading FIT or container image
authorYe Li <ye.li@nxp.com>
Thu, 3 Jan 2019 08:50:24 +0000 (00:50 -0800)
committerYe Li <ye.li@nxp.com>
Fri, 24 May 2019 10:38:53 +0000 (03:38 -0700)
Add support to f_sdp to search and load iMX8 container image or iMX8M
FIT image by new UUU command SDPV.

When using the SDPV, the uuu will continue to send out data after first
level boot loader used by ROM. This means uuu won't skip to the offset
of the second boot loader, and the padding data before second boot loader
will be sent out. So we have to search the FIT header or container header
in the buffer that SDP received.

The new BCD value is used by uuu to distinguish if the SPL supports the
SDPV.

Signed-off-by: Ye Li <ye.li@nxp.com>
(cherry picked from commit cddb0fde374769dccff44275a5072c5e28e41446)

arch/arm/mach-imx/imx8/parser.c
arch/arm/mach-imx/spl.c
drivers/usb/gadget/f_sdp.c

index 68cf17e..88432f4 100644 (file)
@@ -2,7 +2,6 @@
 /*
  * Copyright 2018 NXP
  */
-
 #include <common.h>
 #include <spl.h>
 #include <errno.h>
@@ -17,6 +16,7 @@
 
 #define MMC_DEV                0
 #define QSPI_DEV       1
+#define RAM_DEV        3
 
 #define SEC_SECURE_RAM_BASE                    (0x31800000UL)
 #define SEC_SECURE_RAM_END_BASE                        (SEC_SECURE_RAM_BASE + 0xFFFFUL)
@@ -30,11 +30,11 @@ static int current_dev_type = MMC_DEV;
 static int start_offset;
 static void *device;
 
-static int read(int start, int len, void *load_addr)
+static int read(u32 start, u32 len, void *load_addr)
 {
        int ret = -ENODEV;
 
-       if (!device) {
+       if (!device && current_dev_type != RAM_DEV) {
                debug("No device selected\n");
                return ret;
        }
@@ -69,6 +69,11 @@ static int read(int start, int len, void *load_addr)
        }
 #endif
 
+       if (current_dev_type == RAM_DEV) {
+               memcpy(load_addr, (const void *)(ulong)start, len);
+               ret = 0;
+       }
+
        return ret;
 }
 
@@ -197,6 +202,8 @@ static int read_auth_container(struct spl_image_info *spl_image)
 
                if (!image) {
                        ret = -EINVAL;
+                       if (sc_seco_authenticate(-1, SC_MISC_REL_CONTAINER, 0) != SC_ERR_NONE)
+                               printf("Error: release container failed!\n");
                        goto out;
                }
 
@@ -245,3 +252,18 @@ int spi_load_image_parse_container(struct spl_image_info *spl_image,
 
        return ret;
 }
+
+int sdp_load_image_parse_container(struct spl_image_info *spl_image,
+                                  unsigned long offset)
+{
+       int ret = 0;
+
+       current_dev_type = RAM_DEV;
+       device = NULL;
+
+       start_offset = offset;
+
+       ret = read_auth_container(spl_image);
+
+       return ret;
+}
index 959aa86..6efa926 100644 (file)
@@ -179,6 +179,12 @@ int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
 
        return 0;
 }
+
+#define SDPV_BCD_DEVICE 0x500
+int g_dnl_get_board_bcd_device_number(int gcnum)
+{
+       return SDPV_BCD_DEVICE;
+}
 #endif
 
 #if defined(CONFIG_SPL_MMC_SUPPORT)
index ebf40dc..2a47d88 100644 (file)
@@ -247,6 +247,14 @@ static struct usb_gadget_strings *sdp_generic_strings[] = {
        NULL,
 };
 
+#ifdef CONFIG_PARSE_CONTAINER
+int __weak sdp_load_image_parse_container(struct spl_image_info *spl_image,
+                                  unsigned long offset)
+{
+       return -EINVAL;
+}
+#endif
+
 void __weak board_sdp_cleanup(void)
 {
 }
@@ -676,6 +684,34 @@ static ulong sdp_spl_fit_read(struct spl_load_info *load, ulong sector,
        return count;
 }
 
+#ifdef CONFIG_SPL_BUILD
+#ifdef CONFIG_PARSE_CONTAINER
+static ulong search_container_header(ulong p, int size)
+{
+       int i = 0;
+       uint8_t *hdr;
+       for (i = 0; i < size; i += 4) {
+               hdr = (uint8_t *)(p +i);
+               if (*(hdr + 3) == 0x87 && *hdr == 0 &&
+                       (*(hdr + 1) != 0 || *(hdr + 2) != 0))
+                        return p +i;
+       }
+        return 0;
+}
+#else
+static ulong search_fit_header(ulong p, int size)
+{
+       int i = 0;
+       for (i = 0; i < size; i += 4) {
+                if (genimg_get_format((const void *)(p+i)) == IMAGE_FORMAT_FIT)
+                        return p + i;
+       }
+
+        return 0;
+}
+#endif
+#endif
+
 static void sdp_handle_in_ep(void)
 {
        u8 *data = sdp_func->in_req->buf;
@@ -731,6 +767,20 @@ static void sdp_handle_in_ep(void)
                        struct image_header *header;
                        struct spl_image_info spl_image = {};
 
+#ifdef CONFIG_PARSE_CONTAINER
+                       sdp_func->jmp_address = (u32)search_container_header((ulong)sdp_func->jmp_address,
+                               sdp_func->dnl_bytes);
+#else
+                       if (IS_ENABLED(CONFIG_SPL_LOAD_FIT))
+                               sdp_func->jmp_address = (u32)search_fit_header((ulong)sdp_func->jmp_address,
+                                       sdp_func->dnl_bytes);
+#endif
+                       if (sdp_func->jmp_address == 0) {
+                               panic("Error in search header, failed to jump\n");
+                       }
+
+                       printf("Found header at 0x%08x\n", sdp_func->jmp_address);
+
                        header = (struct image_header *)(ulong)(sdp_func->jmp_address);
 
                        if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
@@ -747,9 +797,14 @@ static void sdp_handle_in_ep(void)
                                                          sdp_func->jmp_address,
                                                          (void *)header);
                        } else {
+#ifdef CONFIG_PARSE_CONTAINER
+                               sdp_load_image_parse_container(&spl_image,
+                                                            sdp_func->jmp_address);
+#else
                                /* In SPL, allow jumps to U-Boot images */
                                spl_parse_image_header(&spl_image,
                                        (struct image_header *)(ulong)(sdp_func->jmp_address));
+#endif
                        }
 
                        board_sdp_cleanup();