-/* Allow for arch specific config before we boot */
-static void __arch_preboot_os(void)
-{
- /* please define platform specific arch_preboot_os() */
-}
-void arch_preboot_os(void) __attribute__((weak, alias("__arch_preboot_os")));
-
-#define IH_INITRD_ARCH IH_ARCH_DEFAULT
-
-#ifdef CONFIG_LMB
-static void boot_start_lmb(bootm_headers_t *images)
-{
- ulong mem_start;
- phys_size_t mem_size;
-
- lmb_init(&images->lmb);
-
- mem_start = getenv_bootm_low();
- mem_size = getenv_bootm_size();
-
- lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size);
-
- arch_lmb_reserve(&images->lmb);
- board_lmb_reserve(&images->lmb);
-}
-#else
-#define lmb_reserve(lmb, base, size)
-static inline void boot_start_lmb(bootm_headers_t *images) { }
-#endif
-
-static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- memset((void *)&images, 0, sizeof(images));
- images.verify = getenv_yesno("verify");
-
- boot_start_lmb(&images);
-
- bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start");
- images.state = BOOTM_STATE_START;
-
- return 0;
-}
-
-static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
-{
- const void *os_hdr;
-
- /* get kernel image header, start address and length */
- os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
- &images, &images.os.image_start, &images.os.image_len);
- if (images.os.image_len == 0) {
- puts("ERROR: can't get kernel image!\n");
- return 1;
- }
-
- /* get image parameters */
- switch (genimg_get_format(os_hdr)) {
- case IMAGE_FORMAT_LEGACY:
- images.os.type = image_get_type(os_hdr);
- images.os.comp = image_get_comp(os_hdr);
- images.os.os = image_get_os(os_hdr);
-
- images.os.end = image_get_image_end(os_hdr);
- images.os.load = image_get_load(os_hdr);
- break;
-#if defined(CONFIG_FIT)
- case IMAGE_FORMAT_FIT:
- if (fit_image_get_type(images.fit_hdr_os,
- images.fit_noffset_os, &images.os.type)) {
- puts("Can't get image type!\n");
- bootstage_error(BOOTSTAGE_ID_FIT_TYPE);
- return 1;
- }
-
- if (fit_image_get_comp(images.fit_hdr_os,
- images.fit_noffset_os, &images.os.comp)) {
- puts("Can't get image compression!\n");
- bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION);
- return 1;
- }
-
- if (fit_image_get_os(images.fit_hdr_os,
- images.fit_noffset_os, &images.os.os)) {
- puts("Can't get image OS!\n");
- bootstage_error(BOOTSTAGE_ID_FIT_OS);
- return 1;
- }
-
- images.os.end = fit_get_end(images.fit_hdr_os);
-
- if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
- &images.os.load)) {
- puts("Can't get image load address!\n");
- bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR);
- return 1;
- }
- break;
-#endif
- default:
- puts("ERROR: unknown image format type!\n");
- return 1;
- }
-
- /* find kernel entry point */
- if (images.legacy_hdr_valid) {
- images.ep = image_get_ep(&images.legacy_hdr_os_copy);
-#if defined(CONFIG_FIT)
- } else if (images.fit_uname_os) {
- int ret;
-
- ret = fit_image_get_entry(images.fit_hdr_os,
- images.fit_noffset_os, &images.ep);
- if (ret) {
- puts("Can't get entry point property!\n");
- return 1;
- }
-#endif
- } else {
- puts("Could not find kernel entry point!\n");
- return 1;
- }
-
- if (images.os.type == IH_TYPE_KERNEL_NOLOAD) {
- images.os.load = images.os.image_start;
- images.ep += images.os.load;
- }
-
- images.os.start = (ulong)os_hdr;
-
- return 0;
-}
-
-static int bootm_find_ramdisk(int flag, int argc, char * const argv[])
-{
- int ret;
-
- /* find ramdisk */
- ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH,
- &images.rd_start, &images.rd_end);
- if (ret) {
- puts("Ramdisk image is corrupt or invalid\n");
- return 1;
- }
-
- return 0;
-}
-
-#if defined(CONFIG_OF_LIBFDT)
-static int bootm_find_fdt(int flag, int argc, char * const argv[])
-{
- int ret;
-
- /* find flattened device tree */
- ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
- &images.ft_addr, &images.ft_len);
- if (ret) {
- puts("Could not find a valid device tree\n");
- return 1;
- }
-
- set_working_fdt_addr(images.ft_addr);
-
- return 0;
-}
-#endif
-
-static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
-{
- if (((images.os.type == IH_TYPE_KERNEL) ||
- (images.os.type == IH_TYPE_KERNEL_NOLOAD) ||
- (images.os.type == IH_TYPE_MULTI)) &&
- (images.os.os == IH_OS_LINUX ||
- images.os.os == IH_OS_VXWORKS)) {
- if (bootm_find_ramdisk(flag, argc, argv))
- return 1;
-
-#if defined(CONFIG_OF_LIBFDT)
- if (bootm_find_fdt(flag, argc, argv))
- return 1;
-#endif
- }
-
- return 0;
-}
-
-#define BOOTM_ERR_RESET -1
-#define BOOTM_ERR_OVERLAP -2
-#define BOOTM_ERR_UNIMPLEMENTED -3
-static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
- int boot_progress)
-{
- image_info_t os = images->os;
- uint8_t comp = os.comp;
- ulong load = os.load;
- ulong blob_start = os.start;
- ulong blob_end = os.end;
- ulong image_start = os.image_start;
- ulong image_len = os.image_len;
- __maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN;
- int no_overlap = 0;
- void *load_buf, *image_buf;
-#if defined(CONFIG_LZMA) || defined(CONFIG_LZO)
- int ret;
-#endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */
-
- const char *type_name = genimg_get_type_name(os.type);
-
- load_buf = map_sysmem(load, unc_len);
- image_buf = map_sysmem(image_start, image_len);
- switch (comp) {
- case IH_COMP_NONE:
- if (load == blob_start || load == image_start) {
- printf(" XIP %s ... ", type_name);
- no_overlap = 1;
- } else {
- printf(" Loading %s ... ", type_name);
- memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
- }
- *load_end = load + image_len;
- break;
-#ifdef CONFIG_GZIP
- case IH_COMP_GZIP:
- printf(" Uncompressing %s ... ", type_name);
- if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) {
- puts("GUNZIP: uncompress, out-of-mem or overwrite "
- "error - must RESET board to recover\n");
- if (boot_progress)
- bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
- return BOOTM_ERR_RESET;
- }
-
- *load_end = load + image_len;
- break;
-#endif /* CONFIG_GZIP */
-#ifdef CONFIG_BZIP2
- case IH_COMP_BZIP2:
- printf(" Uncompressing %s ... ", type_name);
- /*
- * If we've got less than 4 MB of malloc() space,
- * use slower decompression algorithm which requires
- * at most 2300 KB of memory.
- */
- int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len,
- image_buf, image_len,
- CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
- if (i != BZ_OK) {
- printf("BUNZIP2: uncompress or overwrite error %d "
- "- must RESET board to recover\n", i);
- if (boot_progress)
- bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
- return BOOTM_ERR_RESET;
- }
-
- *load_end = load + unc_len;
- break;
-#endif /* CONFIG_BZIP2 */
-#ifdef CONFIG_LZMA
- case IH_COMP_LZMA: {
- SizeT lzma_len = unc_len;
- printf(" Uncompressing %s ... ", type_name);
-
- ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
- image_buf, image_len);
- unc_len = lzma_len;
- if (ret != SZ_OK) {
- printf("LZMA: uncompress or overwrite error %d "
- "- must RESET board to recover\n", ret);
- bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
- return BOOTM_ERR_RESET;
- }
- *load_end = load + unc_len;
- break;
- }
-#endif /* CONFIG_LZMA */
-#ifdef CONFIG_LZO
- case IH_COMP_LZO: {
- size_t size;
-
- printf(" Uncompressing %s ... ", type_name);
-
- ret = lzop_decompress(image_buf, image_len, load_buf, &size);
- if (ret != LZO_E_OK) {
- printf("LZO: uncompress or overwrite error %d "
- "- must RESET board to recover\n", ret);
- if (boot_progress)
- bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
- return BOOTM_ERR_RESET;
- }
-
- *load_end = load + size;
- break;
- }
-#endif /* CONFIG_LZO */
- default:
- printf("Unimplemented compression type %d\n", comp);
- return BOOTM_ERR_UNIMPLEMENTED;
- }
-
- flush_cache(load, (*load_end - load) * sizeof(ulong));
-
- puts("OK\n");
- debug(" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
- bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);
-
- if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) {
- debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
- blob_start, blob_end);
- debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
- *load_end);
-
- /* Check what type of image this is. */
- if (images->legacy_hdr_valid) {
- if (image_get_type(&images->legacy_hdr_os_copy)
- == IH_TYPE_MULTI)
- puts("WARNING: legacy format multi component image overwritten\n");
- return BOOTM_ERR_OVERLAP;
- } else {
- puts("ERROR: new format image overwritten - must RESET the board to recover\n");
- bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
- return BOOTM_ERR_RESET;
- }
- }
-
- return 0;
-}
-
-static int do_bootm_standalone(int flag, int argc, char * const argv[],
- bootm_headers_t *images)
-{
- char *s;
- int (*appl)(int, char * const []);
-
- /* Don't start if "autostart" is set to "no" */
- if (((s = getenv("autostart")) != NULL) && (strcmp(s, "no") == 0)) {
- setenv_hex("filesize", images->os.image_len);
- return 0;
- }
- appl = (int (*)(int, char * const []))(ulong)ntohl(images->ep);
- (*appl)(argc, argv);
- return 0;
-}
-