summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/board_f.c4
-rw-r--r--common/console.c17
-rw-r--r--common/env_common.c2
-rw-r--r--common/spl/Kconfig22
-rw-r--r--common/spl/Makefile1
-rw-r--r--common/spl/spl.c191
-rw-r--r--common/spl/spl_ext.c21
-rw-r--r--common/spl/spl_fat.c23
-rw-r--r--common/spl/spl_fit.c9
-rw-r--r--common/spl/spl_mmc.c72
-rw-r--r--common/spl/spl_nand.c37
-rw-r--r--common/spl/spl_net.c36
-rw-r--r--common/spl/spl_nor.c18
-rw-r--r--common/spl/spl_onenand.c9
-rw-r--r--common/spl/spl_sata.c15
-rw-r--r--common/spl/spl_spi.c127
-rw-r--r--common/spl/spl_ubi.c14
-rw-r--r--common/spl/spl_usb.c17
-rw-r--r--common/spl/spl_ymodem.c13
19 files changed, 424 insertions, 224 deletions
diff --git a/common/board_f.c b/common/board_f.c
index 2c88595078..1b888228ca 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -1058,7 +1058,7 @@ void board_init_f(ulong boot_flags)
{
#ifdef CONFIG_SYS_GENERIC_GLOBAL_DATA
/*
- * For some archtectures, global data is initialized and used before
+ * For some architectures, global data is initialized and used before
* calling this function. The data should be preserved. For others,
* CONFIG_SYS_GENERIC_GLOBAL_DATA should be defined and use the stack
* here to host global data until relocation.
@@ -1070,7 +1070,7 @@ void board_init_f(ulong boot_flags)
/*
* Clear global data before it is accessed at debug print
* in initcall_run_list. Otherwise the debug print probably
- * get the wrong vaule of gd->have_console.
+ * get the wrong value of gd->have_console.
*/
zero_global_data();
#endif
diff --git a/common/console.c b/common/console.c
index 12293f3836..c7f3243431 100644
--- a/common/console.c
+++ b/common/console.c
@@ -687,15 +687,22 @@ int console_assign(int file, const char *devname)
return -1;
}
-/* Called before relocation - use serial functions */
-int console_init_f(void)
+static void console_update_silent(void)
{
- gd->have_console = 1;
-
#ifdef CONFIG_SILENT_CONSOLE
if (getenv("silent") != NULL)
gd->flags |= GD_FLG_SILENT;
+ else
+ gd->flags &= ~GD_FLG_SILENT;
#endif
+}
+
+/* Called before relocation - use serial functions */
+int console_init_f(void)
+{
+ gd->have_console = 1;
+
+ console_update_silent();
print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT1_SERIAL);
@@ -831,6 +838,8 @@ int console_init_r(void)
struct list_head *pos;
struct stdio_dev *dev;
+ console_update_silent();
+
#ifdef CONFIG_SPLASH_SCREEN
/*
* suppress all output if splash screen is enabled and we have
diff --git a/common/env_common.c b/common/env_common.c
index 560cad0247..7fb62e8b45 100644
--- a/common/env_common.c
+++ b/common/env_common.c
@@ -226,7 +226,7 @@ int env_import(const char *buf, int check)
return 0;
}
-/* Emport the environment and generate CRC for it. */
+/* Export the environment and generate CRC for it. */
int env_export(env_t *env_out)
{
char *res;
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 2a8ddbc76b..72aacab52c 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -61,6 +61,15 @@ config SPL_SEPARATE_BSS
location is used. Normally we put the device tree at the end of BSS
but with this option enabled, it goes at _image_binary_end.
+config SPL_DISPLAY_PRINT
+ depends on SPL
+ bool "Display a board-specific message in SPL"
+ help
+ If this option is enabled, U-Boot will call the function
+ spl_display_print() immediately after displaying the SPL console
+ banner ("U-Boot SPL ..."). This function should be provided by
+ the board.
+
config TPL
bool
depends on SPL && SUPPORT_TPL
@@ -163,6 +172,19 @@ config SPL_ENV_SUPPORT
starting U-Boot first. Enabling this option will make getenv()
and setenv() available in SPL.
+config SPL_SAVEENV
+ bool "Support save environment"
+ depends on SPL && SPL_ENV_SUPPORT
+ help
+ Enable save environment support in SPL after setenv. By default
+ the saveenv option is not provided in SPL, but some boards need
+ this support in 'Falcon' boot, where SPL need to boot from
+ different images based on environment variable set by OS. For
+ example OS may set "reboot_image" environment variable to
+ "recovery" inorder to boot recovery image by SPL. The SPL read
+ "reboot_image" and act accordingly and change the reboot_image
+ to default mode using setenv and save the environemnt.
+
config SPL_ETH_SUPPORT
bool "Support Ethernet"
depends on SPL_ENV_SUPPORT
diff --git a/common/spl/Makefile b/common/spl/Makefile
index 5bd0b1841e..ed02635e72 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -25,4 +25,5 @@ obj-$(CONFIG_SPL_FAT_SUPPORT) += spl_fat.o
obj-$(CONFIG_SPL_EXT_SUPPORT) += spl_ext.o
obj-$(CONFIG_SPL_SATA_SUPPORT) += spl_sata.o
obj-$(CONFIG_SPL_DFU_SUPPORT) += spl_dfu.o
+obj-$(CONFIG_SPL_SPI_LOAD) += spl_spi.o
endif
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 57b73af4a7..bdb165ac28 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -29,7 +29,6 @@ DECLARE_GLOBAL_DATA_PTR;
#endif
u32 *boot_params_ptr = NULL;
-struct spl_image_info spl_image;
/* Define board data structure */
static bd_t bdata __attribute__ ((section(".data")));
@@ -82,42 +81,43 @@ __weak void spl_board_prepare_for_boot(void)
/* Nothing to do! */
}
-void spl_set_header_raw_uboot(void)
+void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
{
- spl_image.size = CONFIG_SYS_MONITOR_LEN;
- spl_image.entry_point = CONFIG_SYS_UBOOT_START;
- spl_image.load_addr = CONFIG_SYS_TEXT_BASE;
- spl_image.os = IH_OS_U_BOOT;
- spl_image.name = "U-Boot";
+ spl_image->size = CONFIG_SYS_MONITOR_LEN;
+ spl_image->entry_point = CONFIG_SYS_UBOOT_START;
+ spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
+ spl_image->os = IH_OS_U_BOOT;
+ spl_image->name = "U-Boot";
}
-int spl_parse_image_header(const struct image_header *header)
+int spl_parse_image_header(struct spl_image_info *spl_image,
+ const struct image_header *header)
{
u32 header_size = sizeof(struct image_header);
if (image_get_magic(header) == IH_MAGIC) {
- if (spl_image.flags & SPL_COPY_PAYLOAD_ONLY) {
+ if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY) {
/*
* On some system (e.g. powerpc), the load-address and
* entry-point is located at address 0. We can't load
* to 0-0x40. So skip header in this case.
*/
- spl_image.load_addr = image_get_load(header);
- spl_image.entry_point = image_get_ep(header);
- spl_image.size = image_get_data_size(header);
+ spl_image->load_addr = image_get_load(header);
+ spl_image->entry_point = image_get_ep(header);
+ spl_image->size = image_get_data_size(header);
} else {
- spl_image.entry_point = image_get_load(header);
+ spl_image->entry_point = image_get_load(header);
/* Load including the header */
- spl_image.load_addr = spl_image.entry_point -
+ spl_image->load_addr = spl_image->entry_point -
header_size;
- spl_image.size = image_get_data_size(header) +
+ spl_image->size = image_get_data_size(header) +
header_size;
}
- spl_image.os = image_get_os(header);
- spl_image.name = image_get_name(header);
+ spl_image->os = image_get_os(header);
+ spl_image->name = image_get_name(header);
debug("spl: payload image: %.*s load addr: 0x%x size: %d\n",
- (int)sizeof(spl_image.name), spl_image.name,
- spl_image.load_addr, spl_image.size);
+ (int)sizeof(spl_image->name), spl_image->name,
+ spl_image->load_addr, spl_image->size);
} else {
#ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE
/*
@@ -135,13 +135,13 @@ int spl_parse_image_header(const struct image_header *header)
ulong start, end;
if (!bootz_setup((ulong)header, &start, &end)) {
- spl_image.name = "Linux";
- spl_image.os = IH_OS_LINUX;
- spl_image.load_addr = CONFIG_SYS_LOAD_ADDR;
- spl_image.entry_point = CONFIG_SYS_LOAD_ADDR;
- spl_image.size = end - start;
+ spl_image->name = "Linux";
+ spl_image->os = IH_OS_LINUX;
+ spl_image->load_addr = CONFIG_SYS_LOAD_ADDR;
+ spl_image->entry_point = CONFIG_SYS_LOAD_ADDR;
+ spl_image->size = end - start;
debug("spl: payload zImage, load addr: 0x%x size: %d\n",
- spl_image.load_addr, spl_image.size);
+ spl_image->load_addr, spl_image->size);
return 0;
}
#endif
@@ -153,7 +153,7 @@ int spl_parse_image_header(const struct image_header *header)
/* Signature not found - assume u-boot.bin */
debug("mkimage signature not found - ih_magic = %x\n",
header->ih_magic);
- spl_set_header_raw_uboot();
+ spl_set_header_raw_uboot(spl_image);
#endif
}
return 0;
@@ -184,12 +184,18 @@ static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector,
return count;
}
-static int spl_ram_load_image(void)
+static int spl_ram_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
{
struct image_header *header;
header = (struct image_header *)CONFIG_SPL_LOAD_FIT_ADDRESS;
+#if defined(CONFIG_SPL_DFU_SUPPORT)
+ if (bootdev->boot_device == BOOT_DEVICE_DFU)
+ spl_dfu_cmd(0, "dfu_alt_info_ram", "ram", "0");
+#endif
+
if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
image_get_magic(header) == FDT_MAGIC) {
struct spl_load_info load;
@@ -197,7 +203,7 @@ static int spl_ram_load_image(void)
debug("Found FIT\n");
load.bl_len = 1;
load.read = spl_ram_load_read;
- spl_load_simple_fit(&load, 0, header);
+ spl_load_simple_fit(spl_image, &load, 0, header);
} else {
debug("Legacy image\n");
/*
@@ -209,11 +215,15 @@ static int spl_ram_load_image(void)
header = (struct image_header *)
(CONFIG_SYS_TEXT_BASE - sizeof(struct image_header));
- spl_parse_image_header(header);
+ spl_parse_image_header(spl_image, header);
}
return 0;
}
+SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_RAM, spl_ram_load_image);
+#if defined(CONFIG_SPL_DFU_SUPPORT)
+SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_DFU, spl_ram_load_image);
+#endif
#endif
int spl_init(void)
@@ -252,14 +262,6 @@ int spl_init(void)
#define BOOT_DEVICE_NONE 0xdeadbeef
#endif
-static u32 spl_boot_list[] = {
- BOOT_DEVICE_NONE,
- BOOT_DEVICE_NONE,
- BOOT_DEVICE_NONE,
- BOOT_DEVICE_NONE,
- BOOT_DEVICE_NONE,
-};
-
__weak void board_boot_order(u32 *spl_boot_list)
{
spl_boot_list[0] = spl_boot_device();
@@ -346,86 +348,49 @@ static void announce_boot_device(u32 boot_device)
static inline void announce_boot_device(u32 boot_device) { }
#endif
-static int spl_load_image(u32 boot_device)
+static struct spl_image_loader *spl_ll_find_loader(uint boot_device)
{
- switch (boot_device) {
-#ifdef CONFIG_SPL_RAM_DEVICE
- case BOOT_DEVICE_RAM:
- return spl_ram_load_image();
-#endif
-#ifdef CONFIG_SPL_MMC_SUPPORT
- case BOOT_DEVICE_MMC1:
- case BOOT_DEVICE_MMC2:
- case BOOT_DEVICE_MMC2_2:
- return spl_mmc_load_image(boot_device);
-#endif
-#ifdef CONFIG_SPL_UBI
- case BOOT_DEVICE_NAND:
- case BOOT_DEVICE_ONENAND:
- return spl_ubi_load_image(boot_device);
-#else
-#ifdef CONFIG_SPL_NAND_SUPPORT
- case BOOT_DEVICE_NAND:
- return spl_nand_load_image();
-#endif
-#ifdef CONFIG_SPL_ONENAND_SUPPORT
- case BOOT_DEVICE_ONENAND:
- return spl_onenand_load_image();
-#endif
-#endif
-#ifdef CONFIG_SPL_NOR_SUPPORT
- case BOOT_DEVICE_NOR:
- return spl_nor_load_image();
-#endif
-#ifdef CONFIG_SPL_YMODEM_SUPPORT
- case BOOT_DEVICE_UART:
- return spl_ymodem_load_image();
-#endif
-#if defined(CONFIG_SPL_SPI_SUPPORT) || defined(CONFIG_SPL_SPI_FLASH_SUPPORT)
- case BOOT_DEVICE_SPI:
- return spl_spi_load_image();
-#endif
-#ifdef CONFIG_SPL_ETH_SUPPORT
- case BOOT_DEVICE_CPGMAC:
-#ifdef CONFIG_SPL_ETH_DEVICE
- return spl_net_load_image(CONFIG_SPL_ETH_DEVICE);
-#else
- return spl_net_load_image(NULL);
-#endif
-#endif
-#ifdef CONFIG_SPL_USBETH_SUPPORT
- case BOOT_DEVICE_USBETH:
- return spl_net_load_image("usb_ether");
-#endif
-#ifdef CONFIG_SPL_USB_SUPPORT
- case BOOT_DEVICE_USB:
- return spl_usb_load_image();
-#endif
-#ifdef CONFIG_SPL_DFU_SUPPORT
- case BOOT_DEVICE_DFU:
- spl_dfu_cmd(0, "dfu_alt_info_ram", "ram", "0");
- return spl_ram_load_image();
-#endif
-#ifdef CONFIG_SPL_SATA_SUPPORT
- case BOOT_DEVICE_SATA:
- return spl_sata_load_image();
-#endif
-#ifdef CONFIG_SPL_BOARD_LOAD_IMAGE
- case BOOT_DEVICE_BOARD:
- return spl_board_load_image();
-#endif
- default:
-#if defined(CONFIG_SPL_SERIAL_SUPPORT) && defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
- puts("SPL: Unsupported Boot Device!\n");
-#endif
- return -ENODEV;
+ struct spl_image_loader *drv =
+ ll_entry_start(struct spl_image_loader, spl_image_loader);
+ const int n_ents =
+ ll_entry_count(struct spl_image_loader, spl_image_loader);
+ struct spl_image_loader *entry;
+
+ for (entry = drv; entry != drv + n_ents; entry++) {
+ if (boot_device == entry->boot_device)
+ return entry;
}
- return -EINVAL;
+ /* Not found */
+ return NULL;
+}
+
+static int spl_load_image(struct spl_image_info *spl_image, u32 boot_device)
+{
+ struct spl_boot_device bootdev;
+ struct spl_image_loader *loader = spl_ll_find_loader(boot_device);
+
+ bootdev.boot_device = boot_device;
+ bootdev.boot_device_name = NULL;
+ if (loader)
+ return loader->load_image(spl_image, &bootdev);
+
+#if defined(CONFIG_SPL_SERIAL_SUPPORT) && defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+ puts("SPL: Unsupported Boot Device!\n");
+#endif
+ return -ENODEV;
}
void board_init_r(gd_t *dummy1, ulong dummy2)
{
+ u32 spl_boot_list[] = {
+ BOOT_DEVICE_NONE,
+ BOOT_DEVICE_NONE,
+ BOOT_DEVICE_NONE,
+ BOOT_DEVICE_NONE,
+ BOOT_DEVICE_NONE,
+ };
+ struct spl_image_info spl_image;
int i;
debug(">>spl:board_init_r()\n");
@@ -451,11 +416,12 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
spl_board_init();
#endif
+ memset(&spl_image, '\0', sizeof(spl_image));
board_boot_order(spl_boot_list);
for (i = 0; i < ARRAY_SIZE(spl_boot_list) &&
spl_boot_list[i] != BOOT_DEVICE_NONE; i++) {
announce_boot_device(spl_boot_list[i]);
- if (!spl_load_image(spl_boot_list[i]))
+ if (!spl_load_image(&spl_image, spl_boot_list[i]))
break;
}
@@ -473,7 +439,8 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
case IH_OS_LINUX:
debug("Jumping to Linux\n");
spl_board_prepare_for_linux();
- jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR);
+ jump_to_image_linux(&spl_image,
+ (void *)CONFIG_SYS_SPL_ARGS_ADDR);
#endif
default:
debug("Unsupported OS image.. Jumping nevertheless..\n");
diff --git a/common/spl/spl_ext.c b/common/spl/spl_ext.c
index a85dc85ffe..b93e1eacd3 100644
--- a/common/spl/spl_ext.c
+++ b/common/spl/spl_ext.c
@@ -10,9 +10,9 @@
#include <image.h>
#ifdef CONFIG_SPL_EXT_SUPPORT
-int spl_load_image_ext(struct blk_desc *block_dev,
- int partition,
- const char *filename)
+int spl_load_image_ext(struct spl_image_info *spl_image,
+ struct blk_desc *block_dev, int partition,
+ const char *filename)
{
s32 err;
struct image_header *header;
@@ -48,13 +48,13 @@ int spl_load_image_ext(struct blk_desc *block_dev,
goto end;
}
- err = spl_parse_image_header(header);
+ err = spl_parse_image_header(spl_image, header);
if (err < 0) {
puts("spl: ext: failed to parse image header\n");
goto end;
}
- err = ext4fs_read((char *)spl_image.load_addr, filelen, &actlen);
+ err = ext4fs_read((char *)spl_image->load_addr, filelen, &actlen);
end:
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
@@ -67,7 +67,8 @@ end:
}
#ifdef CONFIG_SPL_OS_BOOT
-int spl_load_image_ext_os(struct blk_desc *block_dev, int partition)
+int spl_load_image_ext_os(struct spl_image_info *spl_image,
+ struct blk_desc *block_dev, int partition)
{
int err;
__maybe_unused loff_t filelen, actlen;
@@ -104,7 +105,8 @@ int spl_load_image_ext_os(struct blk_desc *block_dev, int partition)
}
file = getenv("falcon_image_file");
if (file) {
- err = spl_load_image_ext(block_dev, partition, file);
+ err = spl_load_image_ext(spl_image, block_dev,
+ partition, file);
if (err != 0) {
puts("spl: falling back to default\n");
goto defaults;
@@ -134,11 +136,12 @@ defaults:
return -1;
}
- return spl_load_image_ext(block_dev, partition,
+ return spl_load_image_ext(spl_image, block_dev, partition,
CONFIG_SPL_FS_LOAD_KERNEL_NAME);
}
#else
-int spl_load_image_ext_os(struct blk_desc *block_dev, int partition)
+int spl_load_image_ext_os(struct spl_image_info *spl_image,
+ struct blk_desc *block_dev, int partition)
{
return -ENOSYS;
}
diff --git a/common/spl/spl_fat.c b/common/spl/spl_fat.c
index 73d33f54fc..a14acceebb 100644
--- a/common/spl/spl_fat.c
+++ b/common/spl/spl_fat.c
@@ -54,9 +54,9 @@ static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset,
return actread;
}
-int spl_load_image_fat(struct blk_desc *block_dev,
- int partition,
- const char *filename)
+int spl_load_image_fat(struct spl_image_info *spl_image,
+ struct blk_desc *block_dev, int partition,
+ const char *filename)
{
int err;
struct image_header *header;
@@ -82,14 +82,14 @@ int spl_load_image_fat(struct blk_desc *block_dev,
load.filename = (void *)filename;
load.priv = NULL;
- return spl_load_simple_fit(&load, 0, header);
+ return spl_load_simple_fit(spl_image, &load, 0, header);
} else {
- err = spl_parse_image_header(header);
+ err = spl_parse_image_header(spl_image, header);
if (err)
goto end;
err = file_fat_read(filename,
- (u8 *)(uintptr_t)spl_image.load_addr, 0);
+ (u8 *)(uintptr_t)spl_image->load_addr, 0);
}
end:
@@ -103,7 +103,8 @@ end:
}
#ifdef CONFIG_SPL_OS_BOOT
-int spl_load_image_fat_os(struct blk_desc *block_dev, int partition)
+int spl_load_image_fat_os(struct spl_image_info *spl_image,
+ struct blk_desc *block_dev, int partition)
{
int err;
__maybe_unused char *file;
@@ -123,7 +124,8 @@ int spl_load_image_fat_os(struct blk_desc *block_dev, int partition)
}
file = getenv("falcon_image_file");
if (file) {
- err = spl_load_image_fat(block_dev, partition, file);
+ err = spl_load_image_fat(spl_image, block_dev,
+ partition, file);
if (err != 0) {
puts("spl: falling back to default\n");
goto defaults;
@@ -148,11 +150,12 @@ defaults:
return -1;
}
- return spl_load_image_fat(block_dev, partition,
+ return spl_load_image_fat(spl_image, block_dev, partition,
CONFIG_SPL_FS_LOAD_KERNEL_NAME);
}
#else
-int spl_load_image_fat_os(struct blk_desc *block_dev, int partition)
+int spl_load_image_fat_os(struct spl_image_info *spl_image,
+ struct blk_desc *block_dev, int partition)
{
return -ENOSYS;
}
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index be86072c24..aae556f97d 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -123,7 +123,8 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size,
return (data_size + info->bl_len - 1) / info->bl_len;
}
-int spl_load_simple_fit(struct spl_load_info *info, ulong sector, void *fit)
+int spl_load_simple_fit(struct spl_image_info *spl_image,
+ struct spl_load_info *info, ulong sector, void *fit)
{
int sectors;
ulong size, load;
@@ -184,9 +185,9 @@ int spl_load_simple_fit(struct spl_load_info *info, ulong sector, void *fit)
data_size = fdt_getprop_u32(fit, node, "data-size");
load = fdt_getprop_u32(fit, node, "load");
debug("data_offset=%x, data_size=%x\n", data_offset, data_size);
- spl_image.load_addr = load;
- spl_image.entry_point = load;
- spl_image.os = IH_OS_U_BOOT;
+ spl_image->load_addr = load;
+ spl_image->entry_point = load;
+ spl_image->os = IH_OS_U_BOOT;
/*
* Work out where to place the image. We read it so that the first
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index 7c7f32959b..c674e61cbd 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -18,26 +18,26 @@
DECLARE_GLOBAL_DATA_PTR;
-static int mmc_load_legacy(struct mmc *mmc, ulong sector,
- struct image_header *header)
+static int mmc_load_legacy(struct spl_image_info *spl_image, struct mmc *mmc,
+ ulong sector, struct image_header *header)
{
u32 image_size_sectors;
unsigned long count;
int ret;
- ret = spl_parse_image_header(header);
+ ret = spl_parse_image_header(spl_image, header);
if (ret)
return ret;
/* convert size to sectors - round up */
- image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) /
+ image_size_sectors = (spl_image->size + mmc->read_bl_len - 1) /
mmc->read_bl_len;
/* Read the header too to avoid extra memcpy */
count = blk_dread(mmc_get_blk_desc(mmc), sector, image_size_sectors,
- (void *)(ulong)spl_image.load_addr);
+ (void *)(ulong)spl_image->load_addr);
debug("read %x sectors to %x\n", image_size_sectors,
- spl_image.load_addr);
+ spl_image->load_addr);
if (count != image_size_sectors)
return -EIO;
@@ -52,7 +52,8 @@ static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
return blk_dread(mmc_get_blk_desc(mmc), sector, count, buf);
}
-static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector)
+static int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
+ struct mmc *mmc, unsigned long sector)
{
unsigned long count;
struct image_header *header;
@@ -79,9 +80,9 @@ static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector)
load.filename = NULL;
load.bl_len = mmc->read_bl_len;
load.read = h_spl_load_read;
- ret = spl_load_simple_fit(&load, sector, header);
+ ret = spl_load_simple_fit(spl_image, &load, sector, header);
} else {
- ret = mmc_load_legacy(mmc, sector, header);
+ ret = mmc_load_legacy(spl_image, mmc, sector, header);
}
end:
@@ -150,7 +151,8 @@ static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
}
#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
-static int mmc_load_image_raw_partition(struct mmc *mmc, int partition)
+static int mmc_load_image_raw_partition(struct spl_image_info *spl_image,
+ struct mmc *mmc, int partition)
{
disk_partition_t info;
int err;
@@ -164,22 +166,24 @@ static int mmc_load_image_raw_partition(struct mmc *mmc, int partition)
}
#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
- return mmc_load_image_raw_sector(mmc, info.start +
- CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
+ return mmc_load_image_raw_sector(spl_image, mmc,
+ info.start + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
#else
- return mmc_load_image_raw_sector(mmc, info.start);
+ return mmc_load_image_raw_sector(spl_image, mmc, info.start);
#endif
}
#else
#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION -1
-static int mmc_load_image_raw_partition(struct mmc *mmc, int partition)
+static int mmc_load_image_raw_partition(struct spl_image_info *spl_image,
+ struct mmc *mmc, int partition)
{
return -ENOSYS;
}
#endif
#ifdef CONFIG_SPL_OS_BOOT
-static int mmc_load_image_raw_os(struct mmc *mmc)
+static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
+ struct mmc *mmc)
{
unsigned long count;
int ret;
@@ -195,12 +199,12 @@ static int mmc_load_image_raw_os(struct mmc *mmc)
return -1;
}
- ret = mmc_load_image_raw_sector(mmc,
+ ret = mmc_load_image_raw_sector(spl_image, mmc,
CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
if (ret)
return ret;
- if (spl_image.os != IH_OS_LINUX) {
+ if (spl_image->os != IH_OS_LINUX) {
puts("Expected Linux image is not found. Trying to start U-boot\n");
return -ENOENT;
}
@@ -212,26 +216,27 @@ int spl_start_uboot(void)
{
return 1;
}
-static int mmc_load_image_raw_os(struct mmc *mmc)
+static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
+ struct mmc *mmc)
{
return -ENOSYS;
}
#endif
#ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION
-int spl_mmc_do_fs_boot(struct mmc *mmc)
+static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc)
{
int err = -ENOSYS;
#ifdef CONFIG_SPL_FAT_SUPPORT
if (!spl_start_uboot()) {
- err = spl_load_image_fat_os(mmc_get_blk_desc(mmc),
+ err = spl_load_image_fat_os(spl_image, mmc_get_blk_desc(mmc),
CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
if (!err)
return err;
}
#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
- err = spl_load_image_fat(mmc_get_blk_desc(mmc),
+ err = spl_load_image_fat(spl_image, mmc_get_blk_desc(mmc),
CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
if (!err)
@@ -240,13 +245,13 @@ int spl_mmc_do_fs_boot(struct mmc *mmc)
#endif
#ifdef CONFIG_SPL_EXT_SUPPORT
if (!spl_start_uboot()) {
- err = spl_load_image_ext_os(&mmc->block_dev,
+ err = spl_load_image_ext_os(spl_image, &mmc->block_dev,
CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
if (!err)
return err;
}
#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
- err = spl_load_image_ext(&mmc->block_dev,
+ err = spl_load_image_ext(spl_image, &mmc->block_dev,
CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
if (!err)
@@ -261,20 +266,21 @@ int spl_mmc_do_fs_boot(struct mmc *mmc)
return err;
}
#else
-int spl_mmc_do_fs_boot(struct mmc *mmc)
+static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc)
{
return -ENOSYS;
}
#endif
-int spl_mmc_load_image(u32 boot_device)
+static int spl_mmc_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
{
struct mmc *mmc = NULL;
u32 boot_mode;
int err = 0;
__maybe_unused int part;
- err = spl_mmc_find_device(&mmc, boot_device);
+ err = spl_mmc_find_device(&mmc, bootdev->boot_device);
if (err)
return err;
@@ -286,7 +292,7 @@ int spl_mmc_load_image(u32 boot_device)
return err;
}
- boot_mode = spl_boot_mode(boot_device);
+ boot_mode = spl_boot_mode(bootdev->boot_device);
err = -EINVAL;
switch (boot_mode) {
case MMCSD_MODE_EMMCBOOT:
@@ -312,17 +318,17 @@ int spl_mmc_load_image(u32 boot_device)
debug("spl: mmc boot mode: raw\n");
if (!spl_start_uboot()) {
- err = mmc_load_image_raw_os(mmc);
+ err = mmc_load_image_raw_os(spl_image, mmc);
if (!err)
return err;
}
- err = mmc_load_image_raw_partition(mmc,
+ err = mmc_load_image_raw_partition(spl_image, mmc,
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION);
if (!err)
return err;
#if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR)
- err = mmc_load_image_raw_sector(mmc,
+ err = mmc_load_image_raw_sector(spl_image, mmc,
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
if (!err)
return err;
@@ -331,7 +337,7 @@ int spl_mmc_load_image(u32 boot_device)
case MMCSD_MODE_FS:
debug("spl: mmc boot mode: fs\n");
- err = spl_mmc_do_fs_boot(mmc);
+ err = spl_mmc_do_fs_boot(spl_image, mmc);
if (!err)
return err;
@@ -345,3 +351,7 @@ int spl_mmc_load_image(u32 boot_device)
return err;
}
+
+SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_MMC1, spl_mmc_load_image);
+SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_MMC2, spl_mmc_load_image);
+SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_MMC2_2, spl_mmc_load_image);
diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c
index 0e35e0fd6b..d1abda6e4c 100644
--- a/common/spl/spl_nand.c
+++ b/common/spl/spl_nand.c
@@ -13,14 +13,15 @@
#include <fdt.h>
#if defined(CONFIG_SPL_NAND_RAW_ONLY)
-int spl_nand_load_image(void)
+int spl_nand_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
{
nand_init();
nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
CONFIG_SYS_NAND_U_BOOT_SIZE,
(void *)CONFIG_SYS_NAND_U_BOOT_DST);
- spl_set_header_raw_uboot();
+ spl_set_header_raw_uboot(spl_image);
nand_deselect();
return 0;
@@ -39,7 +40,8 @@ static ulong spl_nand_fit_read(struct spl_load_info *load, ulong offs,
return 0;
}
-static int spl_nand_load_element(int offset, struct image_header *header)
+static int spl_nand_load_element(struct spl_image_info *spl_image,
+ int offset, struct image_header *header)
{
int err;
@@ -57,17 +59,18 @@ static int spl_nand_load_element(int offset, struct image_header *header)
load.filename = NULL;
load.bl_len = 1;
load.read = spl_nand_fit_read;
- return spl_load_simple_fit(&load, offset, header);
+ return spl_load_simple_fit(spl_image, &load, offset, header);
} else {
- err = spl_parse_image_header(header);
+ err = spl_parse_image_header(spl_image, header);
if (err)
return err;
- return nand_spl_load_image(offset, spl_image.size,
- (void *)(ulong)spl_image.load_addr);
+ return nand_spl_load_image(offset, spl_image->size,
+ (void *)(ulong)spl_image->load_addr);
}
}
-int spl_nand_load_image(void)
+static int spl_nand_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
{
int err;
struct image_header *header;
@@ -107,15 +110,15 @@ int spl_nand_load_image(void)
/* load linux */
nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
sizeof(*header), (void *)header);
- err = spl_parse_image_header(header);
+ err = spl_parse_image_header(spl_image, header);
if (err)
return err;
if (header->ih_os == IH_OS_LINUX) {
/* happy - was a linux */
err = nand_spl_load_image(
CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
- spl_image.size,
- (void *)spl_image.load_addr);
+ spl_image->size,
+ (void *)spl_image->load_addr);
nand_deselect();
return err;
} else {
@@ -127,17 +130,19 @@ int spl_nand_load_image(void)
}
#endif
#ifdef CONFIG_NAND_ENV_DST
- spl_nand_load_element(CONFIG_ENV_OFFSET, header);
+ spl_nand_load_element(spl_image, CONFIG_ENV_OFFSET, header);
#ifdef CONFIG_ENV_OFFSET_REDUND
- spl_nand_load_element(CONFIG_ENV_OFFSET_REDUND, header);
+ spl_nand_load_element(spl_image, CONFIG_ENV_OFFSET_REDUND, header);
#endif
#endif
/* Load u-boot */
- err = spl_nand_load_element(CONFIG_SYS_NAND_U_BOOT_OFFS, header);
+ err = spl_nand_load_element(spl_image, CONFIG_SYS_NAND_U_BOOT_OFFS,
+ header);
#ifdef CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND
#if CONFIG_SYS_NAND_U_BOOT_OFFS != CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND
if (err)
- err = spl_nand_load_element(CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND,
+ err = spl_nand_load_element(spl_image,
+ CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND,
header);
#endif
#endif
@@ -145,3 +150,5 @@ int spl_nand_load_image(void)
return err;
}
#endif
+/* Use priorty 1 so that Ubi can override this */
+SPL_LOAD_IMAGE_METHOD(1, BOOT_DEVICE_NAND, spl_nand_load_image);
diff --git a/common/spl/spl_net.c b/common/spl/spl_net.c
index ae71d26f0a..f4b4bc4833 100644
--- a/common/spl/spl_net.c
+++ b/common/spl/spl_net.c
@@ -14,7 +14,9 @@
DECLARE_GLOBAL_DATA_PTR;
-int spl_net_load_image(const char *device)
+#if defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USBETH_SUPPORT)
+static int spl_net_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
{
int rv;
@@ -27,12 +29,38 @@ int spl_net_load_image(const char *device)
printf("No Ethernet devices found\n");
return -ENODEV;
}
- if (device)
- setenv("ethact", device);
+ if (bootdev->boot_device_name)
+ setenv("ethact", bootdev->boot_device_name);
rv = net_loop(BOOTP);
if (rv < 0) {
printf("Problem booting with BOOTP\n");
return rv;
}
- return spl_parse_image_header((struct image_header *)load_addr);
+ return spl_parse_image_header(spl_image,
+ (struct image_header *)load_addr);
}
+#endif
+
+#ifdef CONFIG_SPL_ETH_SUPPORT
+int spl_net_load_image_cpgmac(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+#ifdef CONFIG_SPL_ETH_DEVICE
+ bootdev->boot_device_name = CONFIG_SPL_ETH_DEVICE;
+#endif
+
+ return spl_net_load_image(spl_image, bootdev);
+}
+SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_CPGMAC, spl_net_load_image_cpgmac);
+#endif
+
+#ifdef CONFIG_SPL_USBETH_SUPPORT
+int spl_net_load_image_usb(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ bootdev->boot_device_name = "usb_ether";
+
+ return spl_net_load_image(spl_image, bootdev);
+}
+SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_USBETH, spl_net_load_image_usb);
+#endif
diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c
index 8ea874c888..6bfa399bac 100644
--- a/common/spl/spl_nor.c
+++ b/common/spl/spl_nor.c
@@ -7,14 +7,15 @@
#include <common.h>
#include <spl.h>
-int spl_nor_load_image(void)
+static int spl_nor_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
{
int ret;
/*
* Loading of the payload to SDRAM is done with skipping of
* the mkimage header in this SPL NOR driver
*/
- spl_image.flags |= SPL_COPY_PAYLOAD_ONLY;
+ spl_image->flags |= SPL_COPY_PAYLOAD_ONLY;
#ifdef CONFIG_SPL_OS_BOOT
if (!spl_start_uboot()) {
@@ -29,14 +30,14 @@ int spl_nor_load_image(void)
if (image_get_os(header) == IH_OS_LINUX) {
/* happy - was a Linux */
- ret = spl_parse_image_header(header);
+ ret = spl_parse_image_header(spl_image, header);
if (ret)
return ret;
- memcpy((void *)spl_image.load_addr,
+ memcpy((void *)spl_image->load_addr,
(void *)(CONFIG_SYS_OS_BASE +
sizeof(struct image_header)),
- spl_image.size);
+ spl_image->size);
/*
* Copy DT blob (fdt) to SDRAM. Passing pointer to
@@ -59,14 +60,15 @@ int spl_nor_load_image(void)
* Load real U-Boot from its location in NOR flash to its
* defined location in SDRAM
*/
- ret = spl_parse_image_header(
+ ret = spl_parse_image_header(spl_image,
(const struct image_header *)CONFIG_SYS_UBOOT_BASE);
if (ret)
return ret;
- memcpy((void *)(unsigned long)spl_image.load_addr,
+ memcpy((void *)(unsigned long)spl_image->load_addr,
(void *)(CONFIG_SYS_UBOOT_BASE + sizeof(struct image_header)),
- spl_image.size);
+ spl_image->size);
return 0;
}
+SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_NOR, spl_nor_load_image);
diff --git a/common/spl/spl_onenand.c b/common/spl/spl_onenand.c
index 1a28a84e44..f076e2c7c8 100644
--- a/common/spl/spl_onenand.c
+++ b/common/spl/spl_onenand.c
@@ -14,7 +14,8 @@
#include <asm/io.h>
#include <onenand_uboot.h>
-int spl_onenand_load_image(void)
+static int spl_onenand_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
{
struct image_header *header;
int ret;
@@ -26,11 +27,13 @@ int spl_onenand_load_image(void)
/* Load u-boot */
onenand_spl_load_image(CONFIG_SYS_ONENAND_U_BOOT_OFFS,
CONFIG_SYS_ONENAND_PAGE_SIZE, (void *)header);
- ret = spl_parse_image_header(header);
+ ret = spl_parse_image_header(spl_image, header);
if (ret)
return ret;
onenand_spl_load_image(CONFIG_SYS_ONENAND_U_BOOT_OFFS,
- spl_image.size, (void *)spl_image.load_addr);
+ spl_image->size, (void *)spl_image->load_addr);
return 0;
}
+/* Use priorty 1 so that Ubi can override this */
+SPL_LOAD_IMAGE_METHOD(1, BOOT_DEVICE_ONENAND, spl_onenand_load_image);
diff --git a/common/spl/spl_sata.c b/common/spl/spl_sata.c
index 9d8cc7c2dd..a3c07cd9ce 100644
--- a/common/spl/spl_sata.c
+++ b/common/spl/spl_sata.c
@@ -20,7 +20,8 @@
DECLARE_GLOBAL_DATA_PTR;
-int spl_sata_load_image(void)
+static int spl_sata_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
{
int err;
struct blk_desc *stor_dev;
@@ -40,12 +41,15 @@ int spl_sata_load_image(void)
}
#ifdef CONFIG_SPL_OS_BOOT
- if (spl_start_uboot() || spl_load_image_fat_os(stor_dev,
- CONFIG_SYS_SATA_FAT_BOOT_PARTITION))
+ if (spl_start_uboot() ||
+ spl_load_image_fat_os(spl_image, stor_dev,
+ CONFIG_SYS_SATA_FAT_BOOT_PARTITION))
#endif
- err = spl_load_image_fat(stor_dev,
- CONFIG_SYS_SATA_FAT_BOOT_PARTITION,
+ {
+ err = spl_load_image_fat(spl_image, stor_dev,
+ CONFIG_SYS_SATA_FAT_BOOT_PARTITION,
CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
+ }
if (err) {
puts("Error loading sata device\n");
return err;
@@ -53,3 +57,4 @@ int spl_sata_load_image(void)
return 0;
}
+SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_SATA, spl_sata_load_image);
diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c
new file mode 100644
index 0000000000..a3caafbd46
--- /dev/null
+++ b/common/spl/spl_spi.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2011 OMICRON electronics GmbH
+ *
+ * based on drivers/mtd/nand/nand_spl_load.c
+ *
+ * Copyright (C) 2011
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <errno.h>
+#include <spl.h>
+
+#ifdef CONFIG_SPL_OS_BOOT
+/*
+ * Load the kernel, check for a valid header we can parse, and if found load
+ * the kernel and then device tree.
+ */
+static int spi_load_image_os(struct spl_image_info *spl_image,
+ struct spi_flash *flash,
+ struct image_header *header)
+{
+ int err;
+
+ /* Read for a header, parse or error out. */
+ spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, 0x40,
+ (void *)header);
+
+ if (image_get_magic(header) != IH_MAGIC)
+ return -1;
+
+ err = spl_parse_image_header(spl_image, header);
+ if (err)
+ return err;
+
+ spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS,
+ spl_image->size, (void *)spl_image->load_addr);
+
+ /* Read device tree. */
+ spi_flash_read(flash, CONFIG_SYS_SPI_ARGS_OFFS,
+ CONFIG_SYS_SPI_ARGS_SIZE,
+ (void *)CONFIG_SYS_SPL_ARGS_ADDR);
+
+ return 0;
+}
+#endif
+
+static ulong spl_spi_fit_read(struct spl_load_info *load, ulong sector,
+ ulong count, void *buf)
+{
+ struct spi_flash *flash = load->dev;
+ ulong ret;
+
+ ret = spi_flash_read(flash, sector, count, buf);
+ if (!ret)
+ return count;
+ else
+ return 0;
+}
+/*
+ * The main entry for SPI booting. It's necessary that SDRAM is already
+ * configured and available since this code loads the main U-Boot image
+ * from SPI into SDRAM and starts it from there.
+ */
+static int spl_spi_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ int err = 0;
+ struct spi_flash *flash;
+ struct image_header *header;
+
+ /*
+ * Load U-Boot image from SPI flash into RAM
+ */
+
+ flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+ CONFIG_SF_DEFAULT_CS,
+ CONFIG_SF_DEFAULT_SPEED,
+ CONFIG_SF_DEFAULT_MODE);
+ if (!flash) {
+ puts("SPI probe failed.\n");
+ return -ENODEV;
+ }
+
+ /* use CONFIG_SYS_TEXT_BASE as temporary storage area */
+ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
+
+#ifdef CONFIG_SPL_OS_BOOT
+ if (spl_start_uboot() || spi_load_image_os(spl_image, flash, header))
+#endif
+ {
+ /* Load u-boot, mkimage header is 64 bytes. */
+ err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40,
+ (void *)header);
+ if (err)
+ return err;
+
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) {
+ struct spl_load_info load;
+
+ debug("Found FIT\n");
+ load.dev = flash;
+ load.priv = NULL;
+ load.filename = NULL;
+ load.bl_len = 1;
+ load.read = spl_spi_fit_read;
+ err = spl_load_simple_fit(spl_image, &load,
+ CONFIG_SYS_SPI_U_BOOT_OFFS,
+ header);
+ } else {
+ err = spl_parse_image_header(spl_image, header);
+ if (err)
+ return err;
+ err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS,
+ spl_image->size,
+ (void *)spl_image->load_addr);
+ }
+ }
+
+ return err;
+}
+/* Use priorty 1 so that boards can override this */
+SPL_LOAD_IMAGE_METHOD(1, BOOT_DEVICE_SPI, spl_spi_load_image);
diff --git a/common/spl/spl_ubi.c b/common/spl/spl_ubi.c
index f97e1ef680..c03910bb40 100644
--- a/common/spl/spl_ubi.c
+++ b/common/spl/spl_ubi.c
@@ -12,14 +12,15 @@
#include <ubispl.h>
#include <spl.h>
-int spl_ubi_load_image(u32 boot_device)
+int spl_ubi_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
{
struct image_header *header;
struct ubispl_info info;
struct ubispl_load volumes[2];
int ret = 1;
- switch (boot_device) {
+ switch (bootdev->boot_device) {
#ifdef CONFIG_SPL_NAND_SUPPORT
case BOOT_DEVICE_NAND:
nand_init();
@@ -54,7 +55,7 @@ int spl_ubi_load_image(u32 boot_device)
ret = ubispl_load_volumes(&info, volumes, 2);
if (!ret) {
header = (struct image_header *)volumes[0].load_addr;
- spl_parse_image_header(header);
+ spl_parse_image_header(spl_image, header);
puts("Linux loaded.\n");
goto out;
}
@@ -68,11 +69,14 @@ int spl_ubi_load_image(u32 boot_device)
ret = ubispl_load_volumes(&info, volumes, 1);
if (!ret)
- spl_parse_image_header(header);
+ spl_parse_image_header(spl_image, header);
out:
#ifdef CONFIG_SPL_NAND_SUPPORT
- if (boot_device == BOOT_DEVICE_NAND)
+ if (bootdev->boot_device == BOOT_DEVICE_NAND)
nand_deselect();
#endif
return ret;
}
+/* Use priorty 0 so that Ubi will override NAND and ONENAND methods */
+SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_NAND, spl_ubi_load_image);
+SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_ONENAND, spl_ubi_load_image);
diff --git a/common/spl/spl_usb.c b/common/spl/spl_usb.c
index 04fa66758c..e37966ed6c 100644
--- a/common/spl/spl_usb.c
+++ b/common/spl/spl_usb.c
@@ -22,7 +22,8 @@ DECLARE_GLOBAL_DATA_PTR;
static int usb_stor_curr_dev = -1; /* current device */
#endif
-int spl_usb_load_image(void)
+static int spl_usb_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
{
int err;
struct blk_desc *stor_dev;
@@ -47,12 +48,15 @@ int spl_usb_load_image(void)
debug("boot mode - FAT\n");
#ifdef CONFIG_SPL_OS_BOOT
- if (spl_start_uboot() || spl_load_image_fat_os(stor_dev,
- CONFIG_SYS_USB_FAT_BOOT_PARTITION))
+ if (spl_start_uboot() ||
+ spl_load_image_fat_os(spl_image, stor_dev,
+ CONFIG_SYS_USB_FAT_BOOT_PARTITION))
#endif
- err = spl_load_image_fat(stor_dev,
- CONFIG_SYS_USB_FAT_BOOT_PARTITION,
- CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
+ {
+ err = spl_load_image_fat(spl_image, stor_dev,
+ CONFIG_SYS_USB_FAT_BOOT_PARTITION,
+ CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
+ }
if (err) {
puts("Error loading from USB device\n");
@@ -61,3 +65,4 @@ int spl_usb_load_image(void)
return 0;
}
+SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_USB, spl_usb_load_image);
diff --git a/common/spl/spl_ymodem.c b/common/spl/spl_ymodem.c
index 5402301c78..13e8e51da9 100644
--- a/common/spl/spl_ymodem.c
+++ b/common/spl/spl_ymodem.c
@@ -68,7 +68,8 @@ static ulong ymodem_read_fit(struct spl_load_info *load, ulong offset,
return size;
}
-int spl_ymodem_load_image(void)
+static int spl_ymodem_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
{
int size = 0;
int err;
@@ -102,17 +103,18 @@ int spl_ymodem_load_image(void)
info.buf = buf;
info.image_read = BUF_SIZE;
load.read = ymodem_read_fit;
- ret = spl_load_simple_fit(&load, 0, (void *)buf);
+ ret = spl_load_simple_fit(spl_image, &load, 0, (void *)buf);
size = info.image_read;
while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0)
size += res;
} else {
- spl_parse_image_header((struct image_header *)buf);
- ret = spl_parse_image_header((struct image_header *)buf);
+ spl_parse_image_header(spl_image, (struct image_header *)buf);
+ ret = spl_parse_image_header(spl_image,
+ (struct image_header *)buf);
if (ret)
return ret;
- addr = spl_image.load_addr;
+ addr = spl_image->load_addr;
memcpy((void *)addr, buf, res);
size += res;
addr += res;
@@ -131,3 +133,4 @@ end_stream:
printf("Loaded %d bytes\n", size);
return 0;
}
+SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_UART, spl_ymodem_load_image);