X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=cmd%2Felf.c;h=5e698676d5576a7f615077cd22f7b91f41a77e8f;hb=45519924a09d7818c30042b1ccd0b7526ef5e26d;hp=e4c65351118a5f5144e7b8debee93ea7dc21592a;hpb=995eab8b5b580b67394312b1621c60a71042cd18;p=u-boot diff --git a/cmd/elf.c b/cmd/elf.c index e4c6535111..5e698676d5 100644 --- a/cmd/elf.c +++ b/cmd/elf.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_X86 @@ -147,25 +148,25 @@ int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long addr; /* Address of the ELF image */ unsigned long rc; /* Return value from user code */ - char *sload, *saddr; - const char *ep = getenv("autostart"); - + char *sload = NULL; + const char *ep = env_get("autostart"); int rcode = 0; - sload = saddr = NULL; - if (argc == 3) { - sload = argv[1]; - saddr = argv[2]; - } else if (argc == 2) { - if (argv[1][0] == '-') - sload = argv[1]; - else - saddr = argv[1]; - } + /* Consume 'bootelf' */ + argc--; argv++; - if (saddr) - addr = simple_strtoul(saddr, NULL, 16); - else + /* Check for flag. */ + if (argc >= 1 && (argv[0][0] == '-' && \ + (argv[0][1] == 'p' || argv[0][1] == 's'))) { + sload = argv[0]; + /* Consume flag. */ + argc--; argv++; + } + /* Check for address. */ + if (argc >= 1 && strict_strtoul(argv[0], 16, &addr) != -EINVAL) { + /* Consume address */ + argc--; argv++; + } else addr = load_addr; if (!valid_elf_image(addr)) @@ -185,7 +186,7 @@ int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * pass address parameter as argv[0] (aka command name), * and all remaining args */ - rc = do_bootelf_exec((void *)addr, argc - 1, argv + 1); + rc = do_bootelf_exec((void *)addr, argc, argv); if (rc != 0) rcode = 1; @@ -208,8 +209,9 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) char build_buf[128]; /* Buffer for building the bootline */ int ptr = 0; #ifdef CONFIG_X86 - struct e820info *info; - struct e820entry *data; + ulong base; + struct e820_info *info; + struct e820_entry *data; #endif /* @@ -240,13 +242,9 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * from the VxWorks BSP header files. * This will vary from board to board */ -#if defined(CONFIG_WALNUT) - tmp = (char *)CONFIG_SYS_NVRAM_BASE_ADDR + 0x500; - eth_getenv_enetaddr("ethaddr", (uchar *)build_buf); - memcpy(tmp, &build_buf[3], 3); -#elif defined(CONFIG_SYS_VXWORKS_MAC_PTR) +#if defined(CONFIG_SYS_VXWORKS_MAC_PTR) tmp = (char *)CONFIG_SYS_VXWORKS_MAC_PTR; - eth_getenv_enetaddr("ethaddr", (uchar *)build_buf); + eth_env_get_enetaddr("ethaddr", (uchar *)build_buf); memcpy(tmp, build_buf, 6); #else puts("## Ethernet MAC address not copied to NV RAM\n"); @@ -258,7 +256,7 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * (LOCAL_MEM_LOCAL_ADRS + BOOT_LINE_OFFSET) as defined by * VxWorks BSP. For example, on PowerPC it defaults to 0x4200. */ - tmp = getenv("bootaddr"); + tmp = env_get("bootaddr"); if (!tmp) { printf("## VxWorks bootline address not specified\n"); } else { @@ -269,21 +267,21 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * parameter. If it is not defined, we may be able to * construct the info. */ - bootline = getenv("bootargs"); + bootline = env_get("bootargs"); if (bootline) { memcpy((void *)bootaddr, bootline, max(strlen(bootline), (size_t)255)); flush_cache(bootaddr, max(strlen(bootline), (size_t)255)); } else { - tmp = getenv("bootdev"); + tmp = env_get("bootdev"); if (tmp) { strcpy(build_buf, tmp); ptr = strlen(tmp); } else printf("## VxWorks boot device not specified\n"); - tmp = getenv("bootfile"); + tmp = env_get("bootfile"); if (tmp) ptr += sprintf(build_buf + ptr, "host:%s ", tmp); @@ -295,12 +293,12 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * The following parameters are only needed if 'bootdev' * is an ethernet device, otherwise they are optional. */ - tmp = getenv("ipaddr"); + tmp = env_get("ipaddr"); if (tmp) { ptr += sprintf(build_buf + ptr, "e=%s", tmp); - tmp = getenv("netmask"); + tmp = env_get("netmask"); if (tmp) { - u32 mask = getenv_ip("netmask").s_addr; + u32 mask = env_get_ip("netmask").s_addr; ptr += sprintf(build_buf + ptr, ":%08x ", ntohl(mask)); } else { @@ -308,19 +306,19 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } } - tmp = getenv("serverip"); + tmp = env_get("serverip"); if (tmp) ptr += sprintf(build_buf + ptr, "h=%s ", tmp); - tmp = getenv("gatewayip"); + tmp = env_get("gatewayip"); if (tmp) ptr += sprintf(build_buf + ptr, "g=%s ", tmp); - tmp = getenv("hostname"); + tmp = env_get("hostname"); if (tmp) ptr += sprintf(build_buf + ptr, "tn=%s ", tmp); - tmp = getenv("othbootargs"); + tmp = env_get("othbootargs"); if (tmp) { strcpy(build_buf + ptr, tmp); ptr += strlen(tmp); @@ -338,25 +336,25 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #ifdef CONFIG_X86 /* - * Since E820 information is critical to the kernel, if we don't - * specify these in the environments, use a default one. + * Get VxWorks's physical memory base address from environment, + * if we don't specify it in the environment, use a default one. */ - tmp = getenv("e820data"); - if (tmp) - data = (struct e820entry *)simple_strtoul(tmp, NULL, 16); - else - data = (struct e820entry *)VXWORKS_E820_DATA_ADDR; - tmp = getenv("e820info"); - if (tmp) - info = (struct e820info *)simple_strtoul(tmp, NULL, 16); - else - info = (struct e820info *)VXWORKS_E820_INFO_ADDR; + base = env_get_hex("vx_phys_mem_base", VXWORKS_PHYS_MEM_BASE); + data = (struct e820_entry *)(base + E820_DATA_OFFSET); + info = (struct e820_info *)(base + E820_INFO_OFFSET); - memset(info, 0, sizeof(struct e820info)); + memset(info, 0, sizeof(struct e820_info)); info->sign = E820_SIGNATURE; info->entries = install_e820_map(E820MAX, data); - info->addr = (info->entries - 1) * sizeof(struct e820entry) + - VXWORKS_E820_DATA_ADDR; + info->addr = (info->entries - 1) * sizeof(struct e820_entry) + + E820_DATA_OFFSET; + + /* + * Explicitly clear the bootloader image size otherwise if memory + * at this offset happens to contain some garbage data, the final + * available memory size for the kernel is insane. + */ + *(u32 *)(base + BOOT_IMAGE_SIZE_OFFSET) = 0; #endif /* @@ -365,13 +363,18 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * binary image. */ if (valid_elf_image(addr)) - addr = load_elf_image_shdr(addr); + addr = load_elf_image_phdr(addr); else puts("## Not an ELF image, assuming binary\n"); printf("## Starting vxWorks at 0x%08lx ...\n", addr); dcache_disable(); +#if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI) + armv8_setup_psci(); + smp_kick_all_cpus(); +#endif + #ifdef CONFIG_X86 /* VxWorks on x86 uses stack to pass parameters */ ((asmlinkage void (*)(int))addr)(0); @@ -385,7 +388,7 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } U_BOOT_CMD( - bootelf, 3, 0, do_bootelf, + bootelf, CONFIG_SYS_MAXARGS, 0, do_bootelf, "Boot from an ELF image in memory", "[-p|-s] [address]\n" "\t- load ELF image at [address] via program headers (-p)\n"