Stefan Bosch | 6563ea2 | 2020-07-10 19:07:26 +0200 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0+ |
| 2 | /* |
| 3 | * (C) Copyright 2016 nexell |
| 4 | * jhkim <jhkim@nexell.co.kr> |
| 5 | */ |
| 6 | |
| 7 | #include <common.h> |
| 8 | #include <bootm.h> |
| 9 | #include <command.h> |
| 10 | #include <environment.h> |
| 11 | #include <errno.h> |
| 12 | #include <image.h> |
| 13 | #include <fdt_support.h> |
| 14 | |
| 15 | #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_CLI_FRAMEWORK) |
| 16 | |
| 17 | DECLARE_GLOBAL_DATA_PTR; |
| 18 | |
| 19 | static bootm_headers_t linux_images; |
| 20 | |
| 21 | static void boot_go_set_os(cmd_tbl_t *cmdtp, int flag, int argc, |
| 22 | char * const argv[], |
| 23 | bootm_headers_t *images) |
| 24 | { |
| 25 | char * const img_addr = argv[0]; |
| 26 | |
| 27 | images->os.type = IH_TYPE_KERNEL; |
| 28 | images->os.comp = IH_COMP_NONE; |
| 29 | images->os.os = IH_OS_LINUX; |
| 30 | images->os.load = simple_strtoul(img_addr, NULL, 16); |
| 31 | images->ep = images->os.load; |
| 32 | #if defined(CONFIG_ARM) |
| 33 | images->os.arch = IH_ARCH_ARM; |
| 34 | #elif defined(CONFIG_ARM64) |
| 35 | images->os.arch = IH_ARCH_ARM64; |
| 36 | #else |
| 37 | #error "Not support architecture ..." |
| 38 | #endif |
| 39 | if (!IS_ENABLED(CONFIG_OF_LIBFDT) && !IS_ENABLED(CONFIG_SPL_BUILD)) { |
| 40 | /* set DTB address for linux kernel */ |
| 41 | if (argc > 2) { |
| 42 | unsigned long ft_addr; |
| 43 | |
| 44 | ft_addr = simple_strtol(argv[2], NULL, 16); |
| 45 | images->ft_addr = (char *)ft_addr; |
| 46 | |
| 47 | /* |
| 48 | * if not defined IMAGE_ENABLE_OF_LIBFDT, |
| 49 | * must be set to fdt address |
| 50 | */ |
| 51 | if (!IMAGE_ENABLE_OF_LIBFDT) |
| 52 | gd->bd->bi_boot_params = ft_addr; |
| 53 | |
| 54 | debug("## set ft:%08lx and boot params:%08lx [control of:%s]" |
| 55 | "...\n", ft_addr, gd->bd->bi_boot_params, |
| 56 | IMAGE_ENABLE_OF_LIBFDT ? "on" : "off"); |
| 57 | } |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB) |
| 62 | static void boot_start_lmb(bootm_headers_t *images) |
| 63 | { |
| 64 | ulong mem_start; |
| 65 | phys_size_t mem_size; |
| 66 | |
| 67 | lmb_init(&images->lmb); |
| 68 | |
| 69 | mem_start = getenv_bootm_low(); |
| 70 | mem_size = getenv_bootm_size(); |
| 71 | |
| 72 | lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size); |
| 73 | |
| 74 | arch_lmb_reserve(&images->lmb); |
| 75 | board_lmb_reserve(&images->lmb); |
| 76 | } |
| 77 | #else |
| 78 | #define lmb_reserve(lmb, base, size) |
| 79 | static inline void boot_start_lmb(bootm_headers_t *images) { } |
| 80 | #endif |
| 81 | |
| 82 | int do_boot_linux(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
| 83 | { |
| 84 | boot_os_fn *boot_fn; |
| 85 | bootm_headers_t *images = &linux_images; |
| 86 | int flags; |
| 87 | int ret; |
| 88 | |
| 89 | boot_start_lmb(images); |
| 90 | |
| 91 | flags = BOOTM_STATE_START; |
| 92 | |
| 93 | argc--; argv++; |
| 94 | boot_go_set_os(cmdtp, flag, argc, argv, images); |
| 95 | |
| 96 | if (IS_ENABLED(CONFIG_OF_LIBFDT)) { |
| 97 | /* find flattened device tree */ |
| 98 | ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, images, |
| 99 | &images->ft_addr, &images->ft_len); |
| 100 | if (ret) { |
| 101 | puts("Could not find a valid device tree\n"); |
| 102 | return 1; |
| 103 | } |
| 104 | set_working_fdt_addr((ulong)images->ft_addr); |
| 105 | } |
| 106 | |
| 107 | if (!IS_ENABLED(CONFIG_OF_LIBFDT)) |
| 108 | flags |= BOOTM_STATE_OS_GO; |
| 109 | |
| 110 | boot_fn = do_bootm_linux; |
| 111 | ret = boot_fn(flags, argc, argv, images); |
| 112 | |
| 113 | if (ret == BOOTM_ERR_UNIMPLEMENTED) |
| 114 | show_boot_progress(BOOTSTAGE_ID_DECOMP_UNIMPL); |
| 115 | else if (ret == BOOTM_ERR_RESET) |
| 116 | do_reset(cmdtp, flag, argc, argv); |
| 117 | |
| 118 | return ret; |
| 119 | } |
| 120 | |
| 121 | U_BOOT_CMD(bootl, CONFIG_SYS_MAXARGS, 1, do_boot_linux, |
| 122 | "boot linux image from memory", |
| 123 | "[addr [arg ...]]\n - boot linux image stored in memory\n" |
| 124 | "\tuse a '-' for the DTB address\n" |
| 125 | ); |
| 126 | #endif |
| 127 | |
| 128 | #if defined(CONFIG_CMD_BOOTD) && !defined(CONFIG_CMD_BOOTM) |
| 129 | int do_bootd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
| 130 | { |
| 131 | return run_command(env_get("bootcmd"), flag); |
| 132 | } |
| 133 | |
| 134 | U_BOOT_CMD(boot, 1, 1, do_bootd, |
| 135 | "boot default, i.e., run 'bootcmd'", |
| 136 | "" |
| 137 | ); |
| 138 | |
| 139 | /* keep old command name "bootd" for backward compatibility */ |
| 140 | U_BOOT_CMD(bootd, 1, 1, do_bootd, |
| 141 | "boot default, i.e., run 'bootcmd'", |
| 142 | "" |
| 143 | ); |
| 144 | #endif |