summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx/spl_imx_romapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx/spl_imx_romapi.c')
-rw-r--r--arch/arm/mach-imx/spl_imx_romapi.c172
1 files changed, 133 insertions, 39 deletions
diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c
index d2085dabd3..d827de375a 100644
--- a/arch/arm/mach-imx/spl_imx_romapi.c
+++ b/arch/arm/mach-imx/spl_imx_romapi.c
@@ -10,11 +10,44 @@
#include <asm/global_data.h>
#include <linux/libfdt.h>
#include <spl.h>
-
+#include <asm/mach-imx/image.h>
#include <asm/arch/sys_proto.h>
DECLARE_GLOBAL_DATA_PTR;
+/* Caller need ensure the offset and size to align with page size */
+ulong spl_romapi_raw_seekable_read(u32 offset, u32 size, void *buf)
+{
+ volatile gd_t *pgd = gd;
+ int ret;
+
+ debug("%s 0x%x, size 0x%x\n", __func__, offset, size);
+
+ ret = g_rom_api->download_image(buf, offset, size,
+ ((uintptr_t)buf) ^ offset ^ size);
+
+ set_gd(pgd);
+
+ if (ret == ROM_API_OKAY)
+ return size;
+
+ printf("%s Failure when load 0x%x, size 0x%x\n", __func__, offset, size);
+
+ return 0;
+}
+
+ulong __weak spl_romapi_get_uboot_base(u32 image_offset, u32 rom_bt_dev)
+{
+ u32 offset;
+
+ if (((rom_bt_dev >> 16) & 0xff) == BT_DEV_TYPE_FLEXSPINOR)
+ offset = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512;
+ else
+ offset = image_offset + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512 - 0x8000;
+
+ return offset;
+}
+
static int is_boot_from_stream_device(u32 boot)
{
u32 interface;
@@ -34,25 +67,12 @@ static ulong spl_romapi_read_seekable(struct spl_load_info *load,
void *buf)
{
u32 pagesize = *(u32 *)load->priv;
- volatile gd_t *pgd = gd;
ulong byte = count * pagesize;
- int ret;
u32 offset;
offset = sector * pagesize;
- debug("ROM API load from 0x%x, size 0x%x\n", offset, (u32)byte);
-
- ret = g_rom_api->download_image(buf, offset, byte,
- ((uintptr_t)buf) ^ offset ^ byte);
- set_gd(pgd);
-
- if (ret == ROM_API_OKAY)
- return count;
-
- printf("ROM API Failure when load 0x%x\n", offset);
-
- return 0;
+ return spl_romapi_raw_seekable_read(offset, byte, buf) / pagesize;
}
static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
@@ -85,11 +105,7 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
printf("image offset 0x%x, pagesize 0x%x, ivt offset 0x%x\n",
image_offset, pagesize, offset);
- if (((rom_bt_dev >> 16) & 0xff) == BT_DEV_TYPE_FLEXSPINOR)
- offset = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512;
- else
- offset = image_offset +
- CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512 - 0x8000;
+ offset = spl_romapi_get_uboot_base(image_offset, rom_bt_dev);
size = ALIGN(sizeof(struct image_header), pagesize);
ret = g_rom_api->download_image((u8 *)header, offset, size,
@@ -102,16 +118,23 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
return -1;
}
- if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
- image_get_magic(header) == FDT_MAGIC) {
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) {
struct spl_load_info load;
memset(&load, 0, sizeof(load));
load.bl_len = pagesize;
load.read = spl_romapi_read_seekable;
load.priv = &pagesize;
- return spl_load_simple_fit(spl_image, &load,
- offset / pagesize, header);
+ return spl_load_simple_fit(spl_image, &load, offset / pagesize, header);
+ } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
+ struct spl_load_info load;
+
+ memset(&load, 0, sizeof(load));
+ load.bl_len = pagesize;
+ load.read = spl_romapi_read_seekable;
+ load.priv = &pagesize;
+
+ ret = spl_load_imx_container(spl_image, &load, offset / pagesize);
} else {
/* TODO */
puts("Can't support legacy image\n");
@@ -154,7 +177,7 @@ static ulong get_fit_image_size(void *fit)
return last - (ulong)fit;
}
-u8 *search_fit_header(u8 *p, int size)
+static u8 *search_fit_header(u8 *p, int size)
{
int i;
@@ -165,6 +188,71 @@ u8 *search_fit_header(u8 *p, int size)
return NULL;
}
+static u8 *search_container_header(u8 *p, int size)
+{
+ int i = 0;
+ u8 *hdr;
+
+ for (i = 0; i < size; i += 4) {
+ hdr = p + i;
+ if (*(hdr + 3) == 0x87 && *hdr == 0 && (*(hdr + 1) != 0 || *(hdr + 2) != 0))
+ return p + i;
+ }
+
+ return NULL;
+}
+
+static u8 *search_img_header(u8 *p, int size)
+{
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT))
+ return search_fit_header(p, size);
+ else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER))
+ return search_container_header(p, size);
+
+ return NULL;
+}
+
+static u32 img_header_size(void)
+{
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT))
+ return sizeof(struct fdt_header);
+ else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER))
+ return sizeof(struct container_hdr);
+
+ return 0;
+}
+
+static int img_info_size(void *img_hdr)
+{
+#ifdef CONFIG_SPL_LOAD_FIT
+ return fit_get_size(img_hdr);
+#elif defined CONFIG_SPL_LOAD_IMX_CONTAINER
+ struct container_hdr *container = img_hdr;
+
+ return (container->length_lsb + (container->length_msb << 8));
+#else
+ return 0;
+#endif
+}
+
+static int img_total_size(void *img_hdr)
+{
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) {
+ return get_fit_image_size(img_hdr);
+ } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
+ int total = get_container_size((ulong)img_hdr, NULL);
+
+ if (total < 0) {
+ printf("invalid container image\n");
+ return 0;
+ }
+
+ return total;
+ }
+
+ return 0;
+}
+
static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
struct spl_boot_device *bootdev)
{
@@ -174,7 +262,7 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
int ret;
int i = 0;
u8 *p = (u8 *)CONFIG_SPL_IMX_ROMAPI_LOADADDR;
- u8 *pfit = NULL;
+ u8 *phdr = NULL;
int imagesize;
int total;
@@ -199,19 +287,19 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
return -1;
}
- pfit = search_fit_header(p, pg);
+ phdr = search_img_header(p, pg);
p += pg;
- if (pfit)
+ if (phdr)
break;
}
- if (!pfit) {
- puts("Can't found uboot FIT image in 640K range \n");
+ if (!phdr) {
+ puts("Can't found uboot image in 640K range\n");
return -1;
}
- if (p - pfit < sizeof(struct fdt_header)) {
+ if (p - phdr < img_header_size()) {
ret = g_rom_api->download_image(p, 0, pg, ((uintptr_t)p) ^ pg);
set_gd(pgd);
@@ -223,11 +311,11 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
p += pg;
}
- imagesize = fit_get_size(pfit);
- printf("Find FIT header 0x&%p, size %d\n", pfit, imagesize);
+ imagesize = img_info_size(phdr);
+ printf("Find img info 0x&%p, size %d\n", phdr, imagesize);
- if (p - pfit < imagesize) {
- imagesize -= p - pfit;
+ if (p - phdr < imagesize) {
+ imagesize -= p - phdr;
/*need pagesize hear after ROM fix USB problme*/
imagesize += pg - 1;
imagesize /= pg;
@@ -247,20 +335,21 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
}
}
- total = get_fit_image_size(pfit);
+ total = img_total_size(phdr);
total += 3;
total &= ~0x3;
- imagesize = total - (p - pfit);
+ imagesize = total - (p - phdr);
imagesize += pagesize - 1;
imagesize /= pagesize;
imagesize *= pagesize;
- printf("Download %d, total fit %d\n", imagesize, total);
+ printf("Download %d, Total size %d\n", imagesize, total);
ret = g_rom_api->download_image(p, 0, imagesize,
((uintptr_t)p) ^ imagesize);
+ set_gd(pgd);
if (ret != ROM_API_OKAY)
printf("ROM download failure %d\n", imagesize);
@@ -268,7 +357,12 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
load.bl_len = 1;
load.read = spl_ram_load_read;
- return spl_load_simple_fit(spl_image, &load, (ulong)pfit, pfit);
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT))
+ return spl_load_simple_fit(spl_image, &load, (ulong)phdr, phdr);
+ else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER))
+ return spl_load_imx_container(spl_image, &load, (ulong)phdr);
+
+ return -1;
}
int board_return_to_bootrom(struct spl_image_info *spl_image,