diff options
Diffstat (limited to 'common/spl/spl.c')
-rw-r--r-- | common/spl/spl.c | 191 |
1 files changed, 79 insertions, 112 deletions
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"); |