X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fspl%2Fspl.c;h=50828e6021812909c65aec01c1bc1d868ddf560d;hb=ddbe1812421a7bf7febd1a678efad69546eb04ab;hp=57b73af4a740b5011264a5b928a53fd58122994a;hpb=6f8387f120362bfa62d7b99760881736162b57da;p=oweals%2Fu-boot.git diff --git a/common/spl/spl.c b/common/spl/spl.c index 57b73af4a7..50828e6021 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,52 @@ __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; +#ifdef CONFIG_CPU_V7M + spl_image->entry_point |= 0x1; +#endif + 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) { +#ifdef CONFIG_SPL_LEGACY_IMAGE_SUPPORT + u32 header_size = sizeof(struct image_header); + + 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); - 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); + spl_image->os = image_get_os(header); + spl_image->name = image_get_name(header); + debug("spl: payload image: %.*s load addr: 0x%lx size: %d\n", + (int)sizeof(spl_image->name), spl_image->name, + spl_image->load_addr, spl_image->size); +#else + /* LEGACY image not supported */ + debug("Legacy boot image support not enabled, proceeding to other boot methods"); + return -EINVAL; +#endif } else { #ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE /* @@ -135,27 +144,29 @@ 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; - debug("spl: payload zImage, load addr: 0x%x size: %d\n", - spl_image.load_addr, spl_image.size); + 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%lx size: %d\n", + spl_image->load_addr, spl_image->size); return 0; } #endif -#ifdef CONFIG_SPL_ABORT_ON_RAW_IMAGE - /* Signature not found, proceed to other boot methods. */ - return -EINVAL; -#else +#ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT /* 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); +#else + /* RAW image not supported, proceed to other boot methods. */ + debug("Raw boot image support not enabled, proceeding to other boot methods"); + return -EINVAL; #endif } + return 0; } @@ -164,69 +175,26 @@ __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) typedef void __noreturn (*image_entry_noargs_t)(void); image_entry_noargs_t image_entry = - (image_entry_noargs_t)(unsigned long)spl_image->entry_point; + (image_entry_noargs_t)spl_image->entry_point; - debug("image entry point: 0x%X\n", spl_image->entry_point); + debug("image entry point: 0x%lX\n", spl_image->entry_point); image_entry(); } -#ifndef CONFIG_SPL_LOAD_FIT_ADDRESS -# define CONFIG_SPL_LOAD_FIT_ADDRESS 0 -#endif - -#if defined(CONFIG_SPL_RAM_DEVICE) || defined(CONFIG_SPL_DFU_SUPPORT) -static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector, - ulong count, void *buf) -{ - debug("%s: sector %lx, count %lx, buf %lx\n", - __func__, sector, count, (ulong)buf); - memcpy(buf, (void *)(CONFIG_SPL_LOAD_FIT_ADDRESS + sector), count); - return count; -} - -static int spl_ram_load_image(void) -{ - struct image_header *header; - - header = (struct image_header *)CONFIG_SPL_LOAD_FIT_ADDRESS; - - if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && - image_get_magic(header) == FDT_MAGIC) { - struct spl_load_info load; - - debug("Found FIT\n"); - load.bl_len = 1; - load.read = spl_ram_load_read; - spl_load_simple_fit(&load, 0, header); - } else { - debug("Legacy image\n"); - /* - * Get the header. It will point to an address defined by - * handoff which will tell where the image located inside - * the flash. For now, it will temporary fixed to address - * pointed by U-Boot. - */ - header = (struct image_header *) - (CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); - - spl_parse_image_header(header); - } - - return 0; -} -#endif - -int spl_init(void) +static int spl_common_init(bool setup_malloc) { int ret; - debug("spl_init()\n"); + debug("spl_early_init()\n"); + #if defined(CONFIG_SYS_MALLOC_F_LEN) + if (setup_malloc) { #ifdef CONFIG_MALLOC_F_ADDR - gd->malloc_base = CONFIG_MALLOC_F_ADDR; + gd->malloc_base = CONFIG_MALLOC_F_ADDR; #endif - gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN; - gd->malloc_ptr = 0; + gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN; + gd->malloc_ptr = 0; + } #endif if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { ret = fdtdec_setup(); @@ -236,13 +204,40 @@ int spl_init(void) } } if (IS_ENABLED(CONFIG_SPL_DM)) { - /* With CONFIG_OF_PLATDATA, bring in all devices */ + /* With CONFIG_SPL_OF_PLATDATA, bring in all devices */ ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA)); if (ret) { debug("dm_init_and_scan() returned error %d\n", ret); return ret; } } + + return 0; +} + +int spl_early_init(void) +{ + int ret; + + ret = spl_common_init(true); + if (ret) + return ret; + gd->flags |= GD_FLG_SPL_EARLY_INIT; + + return 0; +} + +int spl_init(void) +{ + int ret; + bool setup_malloc = !(IS_ENABLED(CONFIG_SPL_STACK_R) && + IS_ENABLED(CONFIG_SPL_SYS_MALLOC_SIMPLE)); + + if (!(gd->flags & GD_FLG_SPL_EARLY_INIT)) { + ret = spl_common_init(setup_malloc); + if (ret) + return ret; + } gd->flags |= GD_FLG_SPL_INIT; return 0; @@ -252,181 +247,79 @@ 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(); } -#ifdef CONFIG_SPL_BOARD_LOAD_IMAGE -__weak void spl_board_announce_boot_device(void) { } -#endif - -#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT -struct boot_device_name { - u32 boot_dev; - const char *name; -}; +static struct spl_image_loader *spl_ll_find_loader(uint boot_device) +{ + 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; + } -struct boot_device_name boot_name_table[] = { -#ifdef CONFIG_SPL_RAM_DEVICE - { BOOT_DEVICE_RAM, "RAM" }, -#endif -#ifdef CONFIG_SPL_MMC_SUPPORT - { BOOT_DEVICE_MMC1, "MMC1" }, - { BOOT_DEVICE_MMC2, "MMC2" }, - { BOOT_DEVICE_MMC2_2, "MMC2_2" }, -#endif -#ifdef CONFIG_SPL_NAND_SUPPORT - { BOOT_DEVICE_NAND, "NAND" }, -#endif -#ifdef CONFIG_SPL_ONENAND_SUPPORT - { BOOT_DEVICE_ONENAND, "OneNAND" }, -#endif -#ifdef CONFIG_SPL_NOR_SUPPORT - { BOOT_DEVICE_NOR, "NOR" }, -#endif -#ifdef CONFIG_SPL_YMODEM_SUPPORT - { BOOT_DEVICE_UART, "UART" }, -#endif -#if defined(CONFIG_SPL_SPI_SUPPORT) || defined(CONFIG_SPL_SPI_FLASH_SUPPORT) - { BOOT_DEVICE_SPI, "SPI" }, -#endif -#ifdef CONFIG_SPL_ETH_SUPPORT -#ifdef CONFIG_SPL_ETH_DEVICE - { BOOT_DEVICE_CPGMAC, "eth device" }, -#else - { BOOT_DEVICE_CPGMAC, "net" }, -#endif -#endif -#ifdef CONFIG_SPL_USBETH_SUPPORT - { BOOT_DEVICE_USBETH, "USB eth" }, -#endif -#ifdef CONFIG_SPL_USB_SUPPORT - { BOOT_DEVICE_USB, "USB" }, -#endif -#ifdef CONFIG_SPL_DFU_SUPPORT - { BOOT_DEVICE_DFU, "USB DFU" }, -#endif -#ifdef CONFIG_SPL_SATA_SUPPORT - { BOOT_DEVICE_SATA, "SATA" }, -#endif - /* Keep this entry last */ - { BOOT_DEVICE_NONE, "unknown boot device" }, -}; + /* Not found */ + return NULL; +} -static void announce_boot_device(u32 boot_device) +static int spl_load_image(struct spl_image_info *spl_image, + struct spl_image_loader *loader) { - int i; + struct spl_boot_device bootdev; - puts("Trying to boot from "); + bootdev.boot_device = loader->boot_device; + bootdev.boot_device_name = NULL; -#ifdef CONFIG_SPL_BOARD_LOAD_IMAGE - if (boot_device == BOOT_DEVICE_BOARD) { - spl_board_announce_boot_device(); - puts("\n"); - return; - } -#endif - for (i = 0; i < ARRAY_SIZE(boot_name_table) - 1; i++) { - if (boot_name_table[i].boot_dev == boot_device) - break; - } - - printf("%s\n", boot_name_table[i].name); + return loader->load_image(spl_image, &bootdev); } -#else -static inline void announce_boot_device(u32 boot_device) { } -#endif -static int spl_load_image(u32 boot_device) +/** + * boot_from_devices() - Try loading an booting U-Boot from a list of devices + * + * @spl_image: Place to put the image details if successful + * @spl_boot_list: List of boot devices to try + * @count: Number of elements in spl_boot_list + * @return 0 if OK, -ve on error + */ +static int boot_from_devices(struct spl_image_info *spl_image, + u32 spl_boot_list[], int count) { - 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: + int i; + + for (i = 0; i < count && spl_boot_list[i] != BOOT_DEVICE_NONE; i++) { + struct spl_image_loader *loader; + + loader = spl_ll_find_loader(spl_boot_list[i]); #if defined(CONFIG_SPL_SERIAL_SUPPORT) && defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - puts("SPL: Unsupported Boot Device!\n"); + if (loader) + printf("Trying to boot from %s\n", loader->name); + else + puts("SPL: Unsupported Boot Device!\n"); #endif - return -ENODEV; + if (loader && !spl_load_image(spl_image, loader)) + return 0; } - return -EINVAL; + return -ENODEV; } void board_init_r(gd_t *dummy1, ulong dummy2) { - int i; + 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; debug(">>spl:board_init_r()\n"); @@ -451,16 +344,14 @@ void board_init_r(gd_t *dummy1, ulong dummy2) spl_board_init(); #endif + memset(&spl_image, '\0', sizeof(spl_image)); +#ifdef CONFIG_SYS_SPL_ARGS_ADDR + spl_image.arg = (void *)CONFIG_SYS_SPL_ARGS_ADDR; +#endif 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])) - break; - } - if (i == ARRAY_SIZE(spl_boot_list) || - spl_boot_list[i] == BOOT_DEVICE_NONE) { + if (boot_from_devices(&spl_image, spl_boot_list, + ARRAY_SIZE(spl_boot_list))) { puts("SPL: failed to boot from all boot devices\n"); hang(); } @@ -473,7 +364,7 @@ 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); #endif default: debug("Unsupported OS image.. Jumping nevertheless..\n"); @@ -483,7 +374,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) gd->malloc_ptr / 1024); #endif - debug("loaded - jumping to U-Boot..."); + debug("loaded - jumping to U-Boot...\n"); spl_board_prepare_for_boot(); jump_to_image_no_args(&spl_image); } @@ -544,6 +435,9 @@ ulong spl_relocate_stack_gd(void) ptr = CONFIG_SPL_STACK_R_ADDR - roundup(sizeof(gd_t),16); new_gd = (gd_t *)ptr; memcpy(new_gd, (void *)gd, sizeof(gd_t)); +#if CONFIG_IS_ENABLED(DM) + dm_fixup_for_gd_move(new_gd); +#endif #if !defined(CONFIG_ARM) gd = new_gd; #endif