summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorYe Li <ye.li@nxp.com>2018-11-26 02:55:56 -0800
committerYe Li <ye.li@nxp.com>2019-05-29 20:02:04 -0700
commit4783e96fa88a7f279a3efee2cc7646bb53c7c1a7 (patch)
treefda46bad75e2bd0c4985b709481ca964b1236960 /common
parent9aa68144ab0e4e7330f6735bc5099e82da73260a (diff)
MLK-21889-4 imx8mn: Add ROMAPI calls for SPL FIT loading
i.MX8MNano ROM exports APIs to load images from boot device. We use this way for SPL loading FIT image. Users need enable CONFIG_SPL_IMX_ROMAPI_SUPPORT and set a buffer address via CONFIG_SPL_IMX_ROMAPI_LOADADDR Signed-off-by: Ye Li <ye.li@nxp.com> Signed-off-by: Frank Li <Frank.Li@nxp.com>
Diffstat (limited to 'common')
-rw-r--r--common/spl/Kconfig10
-rw-r--r--common/spl/Makefile1
-rw-r--r--common/spl/spl_imx_romapi.c305
3 files changed, 316 insertions, 0 deletions
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index ab6fdfc15c..fba901007e 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -526,6 +526,16 @@ config SPL_ONENAND_SUPPORT
load U-Boot from supported devices. This enables the drivers in
drivers/mtd/onenand as part of an SPL build.
+config SPL_IMX_ROMAPI_SUPPORT
+ bool "Support call ROMAPI"
+ depends on SPL
+ help
+ Enable support call ROMAPI to load uboot from boot devices.
+
+config SPL_IMX_ROMAPI_LOADADDR
+ hex "Default load address to load image through ROM API"
+ depends on SPL_IMX_ROMAPI_SUPPORT
+
config SPL_OS_BOOT
bool "Activate Falcon Mode"
depends on !TI_SECURE_DEVICE
diff --git a/common/spl/Makefile b/common/spl/Makefile
index 9bf8a2d81a..d1982343c1 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -31,4 +31,5 @@ obj-$(CONFIG_$(SPL_TPL_)DFU_SUPPORT) += spl_dfu.o
obj-$(CONFIG_$(SPL_TPL_)SPI_LOAD) += spl_spi.o
obj-$(CONFIG_$(SPL_TPL_)RAM_SUPPORT) += spl_ram.o
obj-$(CONFIG_$(SPL_TPL_)USB_SDP_SUPPORT) += spl_sdp.o
+obj-$(CONFIG_$(SPL_TPL_)IMX_ROMAPI_SUPPORT) += spl_imx_romapi.o
endif
diff --git a/common/spl/spl_imx_romapi.c b/common/spl/spl_imx_romapi.c
new file mode 100644
index 0000000000..97cc9562a1
--- /dev/null
+++ b/common/spl/spl_imx_romapi.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <image.h>
+#include <linux/libfdt.h>
+#include <spl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define QUERY_ROM_VER 1
+#define QUERY_BT_DEV 2
+#define QUERY_PAGE_SZ 3
+#define QUERY_IVT_OFF 4
+#define QUERY_BT_STAGE 5
+#define QUERY_IMG_OFF 6
+
+#define BOOT_FROM_SD 1
+#define BOOT_FROM_MMC 2
+#define BOOT_FROM_NAND 3
+#define BOOT_FROM_SPINOR 4
+#define BOOT_FROM_USB 0xE
+
+#define ROM_API_OKAY 0xF0
+
+struct rom_api
+{
+ uint16_t ver;
+ uint16_t tag;
+ uint32_t reserved1;
+ uint32_t (*download_image)(uint8_t * dest, uint32_t offset, uint32_t size, uint32_t xor);
+ uint32_t (*query_boot_infor)(uint32_t info_type, uint32_t *info, uint32_t xor);
+} * g_rom_api = (struct rom_api*)0x980;
+
+
+
+static int is_boot_from_stream_device(uint32_t boot)
+{
+ uint32_t interface;
+ interface = boot >> 16;
+
+ if(interface >= BOOT_FROM_USB)
+ return 1;
+
+ if(interface == BOOT_FROM_MMC && (boot&1))
+ return 1;
+
+ return 0;
+}
+
+static ulong spl_romapi_read_seekable(struct spl_load_info *load, ulong sector, ulong count, void *buf)
+{
+ uint32_t pagesize = *(uint32_t*) load->priv;
+ volatile gd_t *pgd = gd;
+ int ret;
+ uint32_t offset;
+ ulong byte = count * pagesize;
+
+ offset = sector * pagesize;
+
+ debug("ROM API load from 0x%x, size 0x%x\n", offset, (uint32_t)byte);
+
+ ret = g_rom_api->download_image(buf, offset, byte,
+ ((uintptr_t) buf) ^ offset ^ byte);
+ gd = pgd;
+
+ if(ret == ROM_API_OKAY)
+ return count;
+
+ printf("ROM API Failure when load 0x%x\n", offset);
+ return 0;
+}
+
+static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev, u32 rom_bt_dev)
+{
+ int ret;
+ volatile gd_t *pgd = gd;
+ uint32_t offset;
+ uint32_t pagesize, size;
+ struct image_header *header;
+ uint32_t image_offset;
+
+ ret = g_rom_api->query_boot_infor(QUERY_IVT_OFF, &offset, ((uintptr_t) &offset)^ QUERY_IVT_OFF);
+ ret |= g_rom_api->query_boot_infor(QUERY_PAGE_SZ, &pagesize, ((uintptr_t) &pagesize)^ QUERY_PAGE_SZ);
+ ret |= g_rom_api->query_boot_infor(QUERY_IMG_OFF, &image_offset, ((uintptr_t) &image_offset)^ QUERY_IMG_OFF);
+
+ gd = pgd;
+
+ if (ret != ROM_API_OKAY) {
+ puts("ROMAPI: Failure query boot infor pagesize/offset\n");
+ return -1;
+ }
+
+ header = (struct image_header *)(CONFIG_SPL_IMX_ROMAPI_LOADADDR);
+
+ printf("image offset 0x%x, pagesize 0x%x, ivt offset 0x%x\n", image_offset, pagesize, offset);
+
+ if (((rom_bt_dev >> 16) & 0xff) == BOOT_FROM_MMC && image_offset == 0)
+ offset = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512 - 0x8000;
+ else
+ offset = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512;
+ size = ALIGN(sizeof(struct image_header), pagesize);
+ ret = g_rom_api->download_image((uint8_t*)header, offset, size, ((uintptr_t) header) ^ offset ^ size);
+ gd = pgd;
+
+ if (ret != ROM_API_OKAY) {
+ printf("ROMAPI: download failure offset 0x%x size 0x%x\n", offset, size);
+ return -1;
+ }
+
+ 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;
+ spl_load_simple_fit(spl_image, &load, offset / pagesize, header);
+
+ } else {
+ /* TODO */
+ puts("Can't support legacy image\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector,
+ ulong count, void *buf)
+{
+ memcpy(buf, (void *)(sector), count);
+
+ if (load->priv) {
+ ulong *p = (ulong*) load->priv;
+ ulong total = sector + count;
+ if( total > *p)
+ *p = total;
+ }
+ return count;
+}
+
+
+static ulong get_fit_image_size(void *fit)
+{
+ struct spl_image_info spl_image;
+ struct spl_load_info spl_load_info;
+
+ ulong last = (ulong)fit;
+ memset(&spl_load_info, 0, sizeof(spl_load_info));
+ spl_load_info.bl_len = 1;
+ spl_load_info.read = spl_ram_load_read;
+ spl_load_info.priv = &last;
+
+ spl_load_simple_fit(&spl_image, &spl_load_info, (uintptr_t)fit, fit);
+ return last - (ulong)fit;
+}
+
+uint8_t * search_fit_header(uint8_t *p, int size)
+{
+ int i = 0;
+ for (i = 0; i < size; i += 4)
+ if (genimg_get_format(p+i) == IMAGE_FORMAT_FIT)
+ return p + i;
+
+ return NULL;
+}
+
+static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ volatile gd_t *pgd = gd;
+ uint32_t pagesize, pg;
+ int ret;
+ int i = 0;
+ uint8_t *p = (uint8_t *)CONFIG_SPL_IMX_ROMAPI_LOADADDR;
+ uint8_t *pfit = NULL;
+ int imagesize;
+ int total;
+
+ ret = g_rom_api->query_boot_infor(QUERY_PAGE_SZ, &pagesize,
+ ((uintptr_t) &pagesize)^ QUERY_PAGE_SZ);
+ gd = pgd;
+
+ if (ret != ROM_API_OKAY) {
+ puts("failure at query_boot_info\n");
+ }
+
+ pg = pagesize;
+ if(pg < 1024)
+ pg = 1024;
+
+ for (i = 0; i < 640; i++) {
+
+ ret = g_rom_api->download_image(p, 0, pg, ((uintptr_t)p)^pg);
+ gd = pgd;
+
+ if (ret != ROM_API_OKAY) {
+ puts("Steam(USB) download failure\n");
+ return -1;
+ }
+
+ pfit = search_fit_header(p, pg);
+ p += pg;
+
+ if (pfit)
+ break;
+ }
+
+ if (pfit == NULL) {
+ puts("Can't found uboot FIT image in 640K range \n");
+ return -1;
+ }
+
+ if (p - pfit < sizeof(struct fdt_header)) {
+ ret = g_rom_api->download_image(p, 0, pg, ((uintptr_t)p)^pg);
+ gd = pgd;
+
+ if (ret != ROM_API_OKAY) {
+ puts("Steam(USB) download failure\n");
+ return -1;
+ }
+
+ p += pg;
+ }
+
+ imagesize = fit_get_size(pfit);
+ printf("Find FIT header 0x&%p, size %d\n", pfit, imagesize);
+
+ if (p - pfit < imagesize) {
+ imagesize -= p - pfit;
+
+ imagesize += pg -1; /*need pagesize hear after ROM fix USB problme*/
+ imagesize /= pg;
+ imagesize *= pg;
+
+ printf("Need continue download %d\n", imagesize);
+
+ ret = g_rom_api->download_image(p, 0, imagesize, ((uintptr_t)p)^imagesize);
+ gd = pgd;
+
+ p += imagesize;
+
+ if (ret != ROM_API_OKAY) {
+ printf("Failure download %d\n", imagesize);
+ return -1;
+ }
+ }
+
+ total = get_fit_image_size(pfit);
+ total += 3;
+ total &= ~0x3;
+
+ imagesize = total - (p - pfit);
+
+ imagesize += pagesize -1;
+ imagesize /= pagesize;
+ imagesize *= pagesize;
+
+ printf("Download %d, total fit %d\n", imagesize, total);
+
+ ret = g_rom_api->download_image(p, 0, imagesize, ((uintptr_t)p)^imagesize);
+ if (ret != ROM_API_OKAY) {
+ printf("ROM download failure %d\n", imagesize);
+ }
+
+ struct spl_load_info load;
+ memset(&load, 0, sizeof(load));
+ load.bl_len = 1;
+ load.read = spl_ram_load_read;
+ spl_load_simple_fit(spl_image, &load, (ulong)pfit, pfit);
+
+ return 0;
+}
+
+
+static int spl_romapi_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ volatile gd_t *pgd = gd;
+ int ret;
+ uint32_t boot;
+
+ ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot, ((uintptr_t) &boot)^ QUERY_BT_DEV);
+ gd = pgd;
+
+ if (ret != ROM_API_OKAY) {
+ puts("ROMAPI: failure at query_boot_info\n");
+ return -1;
+ }
+
+ if (is_boot_from_stream_device(boot))
+ return spl_romapi_load_image_stream(spl_image, bootdev);
+
+ return spl_romapi_load_image_seekable(spl_image, bootdev, boot);
+}
+
+SPL_LOAD_IMAGE_METHOD("ROMAPI", 0, BOOT_DEVICE_IMX_ROMAPI, spl_romapi_load_image);