From ebca3df7813827e7ed8b0fe26a8eb4713a7ae140 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 7 Oct 2015 20:19:13 -0700 Subject: cmd: Clean up cmd_elf a little bit This commit cleans up cmd_elf.c per U-Boot coding convention, and removes the unnecessary DECLARE_GLOBAL_DATA_PTR and out-of-date powerpc comments (it actually supports not only powerpc targets). Signed-off-by: Bin Meng Reviewed-by: Tom Rini --- common/cmd_elf.c | 171 ++++++++++++++++++++++++------------------------------- 1 file changed, 73 insertions(+), 98 deletions(-) (limited to 'common/cmd_elf.c') diff --git a/common/cmd_elf.c b/common/cmd_elf.c index 22475dc3cb..c5e443215e 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -14,23 +14,17 @@ */ #include -#include #include -#include -#include #include +#include #include -#if defined(CONFIG_WALNUT) || defined(CONFIG_SYS_VXWORKS_MAC_PTR) -DECLARE_GLOBAL_DATA_PTR; -#endif - static unsigned long load_elf_image_phdr(unsigned long addr); static unsigned long load_elf_image_shdr(unsigned long addr); /* Allow ports to override the default behavior */ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]), - int argc, char * const argv[]) + int argc, char * const argv[]) { unsigned long ret; @@ -54,18 +48,16 @@ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]), return ret; } -/* ====================================================================== +/* * Determine if a valid ELF image exists at the given memory location. - * First looks at the ELF header magic field, the makes sure that it is - * executable and makes sure that it is for a PowerPC. - * ====================================================================== */ + * First look at the ELF header magic field, then make sure that it is + * executable. + */ int valid_elf_image(unsigned long addr) { - Elf32_Ehdr *ehdr; /* Elf header structure pointer */ - - /* -------------------------------------------------- */ + Elf32_Ehdr *ehdr; /* Elf header structure pointer */ - ehdr = (Elf32_Ehdr *) addr; + ehdr = (Elf32_Ehdr *)addr; if (!IS_ELF(*ehdr)) { printf("## No elf image at address 0x%08lx\n", addr); @@ -77,27 +69,17 @@ int valid_elf_image(unsigned long addr) return 0; } -#if 0 - if (ehdr->e_machine != EM_PPC) { - printf("## Not a PowerPC elf image at address 0x%08lx\n", addr); - return 0; - } -#endif - return 1; } -/* ====================================================================== - * Interpreter command to boot an arbitrary ELF image from memory. - * ====================================================================== */ +/* Interpreter command to boot an arbitrary ELF image from memory */ 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 */ + unsigned long addr; /* Address of the ELF image */ + unsigned long rc; /* Return value from user code */ char *sload, *saddr; const char *ep = getenv("autostart"); - /* -------------------------------------------------- */ int rcode = 0; sload = saddr = NULL; @@ -138,28 +120,27 @@ int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) rcode = 1; printf("## Application terminated, rc = 0x%lx\n", rc); + return rcode; } -/* ====================================================================== +/* * Interpreter command to boot VxWorks from a memory image. The image can * be either an ELF image or a raw binary. Will attempt to setup the * bootline and other parameters correctly. - * ====================================================================== */ + */ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - unsigned long addr; /* Address of image */ - unsigned long bootaddr; /* Address to put the bootline */ - char *bootline; /* Text of the bootline */ - char *tmp; /* Temporary char pointer */ - char build_buf[128]; /* Buffer for building the bootline */ - - /* --------------------------------------------------- - * + unsigned long addr; /* Address of image */ + unsigned long bootaddr; /* Address to put the bootline */ + char *bootline; /* Text of the bootline */ + char *tmp; /* Temporary char pointer */ + char build_buf[128]; /* Buffer for building the bootline */ + + /* * Check the loadaddr variable. * If we don't know where the image is then we're done. */ - if (argc < 2) addr = load_addr; else @@ -167,7 +148,8 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #if defined(CONFIG_CMD_NET) /* - * Check to see if we need to tftp the image ourselves before starting + * Check to see if we need to tftp the image ourselves + * before starting */ if ((argc == 2) && (strcmp(argv[1], "tftp") == 0)) { if (net_loop(TFTPGET) <= 0) @@ -177,18 +159,18 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } #endif - /* This should equate - * to NV_RAM_ADRS + NV_BOOT_OFFSET + NV_ENET_OFFSET + /* + * This should equate to + * NV_RAM_ADRS + NV_BOOT_OFFSET + NV_ENET_OFFSET * 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; + 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) - tmp = (char *) CONFIG_SYS_VXWORKS_MAC_PTR; + tmp = (char *)CONFIG_SYS_VXWORKS_MAC_PTR; eth_getenv_enetaddr("ethaddr", (uchar *)build_buf); memcpy(tmp, build_buf, 6); #else @@ -199,7 +181,7 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * Use bootaddr to find the location in memory that VxWorks * will look for the bootline string. The default value for * PowerPC is LOCAL_MEM_LOCAL_ADRS + BOOT_LINE_OFFSET which - * defaults to 0x4200 + * defaults to 0x4200. */ tmp = getenv("bootaddr"); if (!tmp) @@ -210,7 +192,7 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* * Check to see if the bootline is defined in the 'bootargs' * parameter. If it is not defined, we may be able to - * construct the info + * construct the info. */ bootline = getenv("bootargs"); if (bootline) { @@ -222,10 +204,10 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) tmp = getenv("bootfile"); if (tmp) sprintf(&build_buf[strlen(build_buf)], - "%s:%s ", CONFIG_SYS_VXWORKS_SERVERNAME, tmp); + "%s:%s ", CONFIG_SYS_VXWORKS_SERVERNAME, tmp); else sprintf(&build_buf[strlen(build_buf)], - "%s:file ", CONFIG_SYS_VXWORKS_SERVERNAME); + "%s:file ", CONFIG_SYS_VXWORKS_SERVERNAME); tmp = getenv("ipaddr"); if (tmp) @@ -241,7 +223,7 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #ifdef CONFIG_SYS_VXWORKS_ADD_PARAMS sprintf(&build_buf[strlen(build_buf)], - CONFIG_SYS_VXWORKS_ADD_PARAMS); + CONFIG_SYS_VXWORKS_ADD_PARAMS); #endif memcpy((void *)bootaddr, build_buf, @@ -252,51 +234,49 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* * If the data at the load address is an elf image, then * treat it like an elf image. Otherwise, assume that it is a - * binary image + * binary image. */ - - if (valid_elf_image(addr)) { + if (valid_elf_image(addr)) addr = load_elf_image_shdr(addr); - } else { + else puts("## Not an ELF image, assuming binary\n"); - /* leave addr as load_addr */ - } printf("## Using bootline (@ 0x%lx): %s\n", bootaddr, - (char *) bootaddr); + (char *)bootaddr); printf("## Starting vxWorks at 0x%08lx ...\n", addr); dcache_disable(); - ((void (*)(int)) addr) (0); + ((void (*)(int))addr)(0); puts("## vxWorks terminated\n"); + return 1; } -/* ====================================================================== +/* * A very simple elf loader, assumes the image is valid, returns the * entry point address. - * ====================================================================== */ + */ static unsigned long load_elf_image_phdr(unsigned long addr) { - Elf32_Ehdr *ehdr; /* Elf header structure pointer */ - Elf32_Phdr *phdr; /* Program header structure pointer */ + Elf32_Ehdr *ehdr; /* Elf header structure pointer */ + Elf32_Phdr *phdr; /* Program header structure pointer */ int i; - ehdr = (Elf32_Ehdr *) addr; - phdr = (Elf32_Phdr *) (addr + ehdr->e_phoff); + ehdr = (Elf32_Ehdr *)addr; + phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff); /* Load each program header */ for (i = 0; i < ehdr->e_phnum; ++i) { - void *dst = (void *)(uintptr_t) phdr->p_paddr; - void *src = (void *) addr + phdr->p_offset; + void *dst = (void *)(uintptr_t)phdr->p_paddr; + void *src = (void *)addr + phdr->p_offset; debug("Loading phdr %i to 0x%p (%i bytes)\n", - i, dst, phdr->p_filesz); + i, dst, phdr->p_filesz); if (phdr->p_filesz) memcpy(dst, src, phdr->p_filesz); if (phdr->p_filesz != phdr->p_memsz) memset(dst + phdr->p_filesz, 0x00, - phdr->p_memsz - phdr->p_filesz); + phdr->p_memsz - phdr->p_filesz); flush_cache((unsigned long)dst, phdr->p_filesz); ++phdr; } @@ -306,50 +286,46 @@ static unsigned long load_elf_image_phdr(unsigned long addr) static unsigned long load_elf_image_shdr(unsigned long addr) { - Elf32_Ehdr *ehdr; /* Elf header structure pointer */ - Elf32_Shdr *shdr; /* Section header structure pointer */ - unsigned char *strtab = 0; /* String table pointer */ - unsigned char *image; /* Binary image pointer */ - int i; /* Loop counter */ - - /* -------------------------------------------------- */ + Elf32_Ehdr *ehdr; /* Elf header structure pointer */ + Elf32_Shdr *shdr; /* Section header structure pointer */ + unsigned char *strtab = 0; /* String table pointer */ + unsigned char *image; /* Binary image pointer */ + int i; /* Loop counter */ - ehdr = (Elf32_Ehdr *) addr; + ehdr = (Elf32_Ehdr *)addr; /* Find the section header string table for output info */ - shdr = (Elf32_Shdr *) (addr + ehdr->e_shoff + - (ehdr->e_shstrndx * sizeof(Elf32_Shdr))); + shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff + + (ehdr->e_shstrndx * sizeof(Elf32_Shdr))); if (shdr->sh_type == SHT_STRTAB) - strtab = (unsigned char *) (addr + shdr->sh_offset); + strtab = (unsigned char *)(addr + shdr->sh_offset); /* Load each appropriate section */ for (i = 0; i < ehdr->e_shnum; ++i) { - shdr = (Elf32_Shdr *) (addr + ehdr->e_shoff + - (i * sizeof(Elf32_Shdr))); + shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff + + (i * sizeof(Elf32_Shdr))); - if (!(shdr->sh_flags & SHF_ALLOC) - || shdr->sh_addr == 0 || shdr->sh_size == 0) { + if (!(shdr->sh_flags & SHF_ALLOC) || + shdr->sh_addr == 0 || shdr->sh_size == 0) { continue; } if (strtab) { debug("%sing %s @ 0x%08lx (%ld bytes)\n", - (shdr->sh_type == SHT_NOBITS) ? - "Clear" : "Load", - &strtab[shdr->sh_name], - (unsigned long) shdr->sh_addr, - (long) shdr->sh_size); + (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load", + &strtab[shdr->sh_name], + (unsigned long)shdr->sh_addr, + (long)shdr->sh_size); } if (shdr->sh_type == SHT_NOBITS) { - memset((void *)(uintptr_t) shdr->sh_addr, 0, - shdr->sh_size); + memset((void *)(uintptr_t)shdr->sh_addr, 0, + shdr->sh_size); } else { - image = (unsigned char *) addr + shdr->sh_offset; - memcpy((void *)(uintptr_t) shdr->sh_addr, - (const void *) image, - shdr->sh_size); + image = (unsigned char *)addr + shdr->sh_offset; + memcpy((void *)(uintptr_t)shdr->sh_addr, + (const void *)image, shdr->sh_size); } flush_cache(shdr->sh_addr, shdr->sh_size); } @@ -357,9 +333,8 @@ static unsigned long load_elf_image_shdr(unsigned long addr) return ehdr->e_entry; } -/* ====================================================================== */ U_BOOT_CMD( - bootelf, 3, 0, do_bootelf, + bootelf, 3, 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" @@ -367,7 +342,7 @@ U_BOOT_CMD( ); U_BOOT_CMD( - bootvx, 2, 0, do_bootvx, + bootvx, 2, 0, do_bootvx, "Boot vxWorks from an ELF image", " [address] - load address of vxWorks ELF image." ); -- cgit v1.2.3 From 9dffa52da8f3fd23fe38ee184512b2a08678d933 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 7 Oct 2015 20:19:14 -0700 Subject: cmd: elf: Reorder load_elf_image_phdr() and load_elf_image_shdr() Move load_elf_image_phdr() and load_elf_image_shdr() to the beginning of the cmd_elf.c so that forward declaration is not needed. Signed-off-by: Bin Meng Reviewed-by: Tom Rini --- common/cmd_elf.c | 161 +++++++++++++++++++++++++++---------------------------- 1 file changed, 79 insertions(+), 82 deletions(-) (limited to 'common/cmd_elf.c') diff --git a/common/cmd_elf.c b/common/cmd_elf.c index c5e443215e..62863df412 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -19,8 +19,85 @@ #include #include -static unsigned long load_elf_image_phdr(unsigned long addr); -static unsigned long load_elf_image_shdr(unsigned long addr); +/* + * A very simple elf loader, assumes the image is valid, returns the + * entry point address. + */ +static unsigned long load_elf_image_phdr(unsigned long addr) +{ + Elf32_Ehdr *ehdr; /* Elf header structure pointer */ + Elf32_Phdr *phdr; /* Program header structure pointer */ + int i; + + ehdr = (Elf32_Ehdr *)addr; + phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff); + + /* Load each program header */ + for (i = 0; i < ehdr->e_phnum; ++i) { + void *dst = (void *)(uintptr_t)phdr->p_paddr; + void *src = (void *)addr + phdr->p_offset; + debug("Loading phdr %i to 0x%p (%i bytes)\n", + i, dst, phdr->p_filesz); + if (phdr->p_filesz) + memcpy(dst, src, phdr->p_filesz); + if (phdr->p_filesz != phdr->p_memsz) + memset(dst + phdr->p_filesz, 0x00, + phdr->p_memsz - phdr->p_filesz); + flush_cache((unsigned long)dst, phdr->p_filesz); + ++phdr; + } + + return ehdr->e_entry; +} + +static unsigned long load_elf_image_shdr(unsigned long addr) +{ + Elf32_Ehdr *ehdr; /* Elf header structure pointer */ + Elf32_Shdr *shdr; /* Section header structure pointer */ + unsigned char *strtab = 0; /* String table pointer */ + unsigned char *image; /* Binary image pointer */ + int i; /* Loop counter */ + + ehdr = (Elf32_Ehdr *)addr; + + /* Find the section header string table for output info */ + shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff + + (ehdr->e_shstrndx * sizeof(Elf32_Shdr))); + + if (shdr->sh_type == SHT_STRTAB) + strtab = (unsigned char *)(addr + shdr->sh_offset); + + /* Load each appropriate section */ + for (i = 0; i < ehdr->e_shnum; ++i) { + shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff + + (i * sizeof(Elf32_Shdr))); + + if (!(shdr->sh_flags & SHF_ALLOC) || + shdr->sh_addr == 0 || shdr->sh_size == 0) { + continue; + } + + if (strtab) { + debug("%sing %s @ 0x%08lx (%ld bytes)\n", + (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load", + &strtab[shdr->sh_name], + (unsigned long)shdr->sh_addr, + (long)shdr->sh_size); + } + + if (shdr->sh_type == SHT_NOBITS) { + memset((void *)(uintptr_t)shdr->sh_addr, 0, + shdr->sh_size); + } else { + image = (unsigned char *)addr + shdr->sh_offset; + memcpy((void *)(uintptr_t)shdr->sh_addr, + (const void *)image, shdr->sh_size); + } + flush_cache(shdr->sh_addr, shdr->sh_size); + } + + return ehdr->e_entry; +} /* Allow ports to override the default behavior */ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]), @@ -253,86 +330,6 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } -/* - * A very simple elf loader, assumes the image is valid, returns the - * entry point address. - */ -static unsigned long load_elf_image_phdr(unsigned long addr) -{ - Elf32_Ehdr *ehdr; /* Elf header structure pointer */ - Elf32_Phdr *phdr; /* Program header structure pointer */ - int i; - - ehdr = (Elf32_Ehdr *)addr; - phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff); - - /* Load each program header */ - for (i = 0; i < ehdr->e_phnum; ++i) { - void *dst = (void *)(uintptr_t)phdr->p_paddr; - void *src = (void *)addr + phdr->p_offset; - debug("Loading phdr %i to 0x%p (%i bytes)\n", - i, dst, phdr->p_filesz); - if (phdr->p_filesz) - memcpy(dst, src, phdr->p_filesz); - if (phdr->p_filesz != phdr->p_memsz) - memset(dst + phdr->p_filesz, 0x00, - phdr->p_memsz - phdr->p_filesz); - flush_cache((unsigned long)dst, phdr->p_filesz); - ++phdr; - } - - return ehdr->e_entry; -} - -static unsigned long load_elf_image_shdr(unsigned long addr) -{ - Elf32_Ehdr *ehdr; /* Elf header structure pointer */ - Elf32_Shdr *shdr; /* Section header structure pointer */ - unsigned char *strtab = 0; /* String table pointer */ - unsigned char *image; /* Binary image pointer */ - int i; /* Loop counter */ - - ehdr = (Elf32_Ehdr *)addr; - - /* Find the section header string table for output info */ - shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff + - (ehdr->e_shstrndx * sizeof(Elf32_Shdr))); - - if (shdr->sh_type == SHT_STRTAB) - strtab = (unsigned char *)(addr + shdr->sh_offset); - - /* Load each appropriate section */ - for (i = 0; i < ehdr->e_shnum; ++i) { - shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff + - (i * sizeof(Elf32_Shdr))); - - if (!(shdr->sh_flags & SHF_ALLOC) || - shdr->sh_addr == 0 || shdr->sh_size == 0) { - continue; - } - - if (strtab) { - debug("%sing %s @ 0x%08lx (%ld bytes)\n", - (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load", - &strtab[shdr->sh_name], - (unsigned long)shdr->sh_addr, - (long)shdr->sh_size); - } - - if (shdr->sh_type == SHT_NOBITS) { - memset((void *)(uintptr_t)shdr->sh_addr, 0, - shdr->sh_size); - } else { - image = (unsigned char *)addr + shdr->sh_offset; - memcpy((void *)(uintptr_t)shdr->sh_addr, - (const void *)image, shdr->sh_size); - } - flush_cache(shdr->sh_addr, shdr->sh_size); - } - - return ehdr->e_entry; -} - U_BOOT_CMD( bootelf, 3, 0, do_bootelf, "Boot from an ELF image in memory", -- cgit v1.2.3 From 7f0c3c51c2d455b7e12196ed91aa461cf86b9790 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 7 Oct 2015 20:19:15 -0700 Subject: cmd: bootvx: Avoid strlen() calls when constructing VxWorks bootline Remember the position in the VxWorks bootline buffer to avoid the call to strlen() each time. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- common/cmd_elf.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'common/cmd_elf.c') diff --git a/common/cmd_elf.c b/common/cmd_elf.c index 62863df412..6c95851642 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -213,6 +213,7 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) char *bootline; /* Text of the bootline */ char *tmp; /* Temporary char pointer */ char build_buf[128]; /* Buffer for building the bootline */ + int ptr = 0; /* * Check the loadaddr variable. @@ -277,30 +278,29 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) max(strlen(bootline), (size_t)255)); flush_cache(bootaddr, max(strlen(bootline), (size_t)255)); } else { - sprintf(build_buf, CONFIG_SYS_VXWORKS_BOOT_DEVICE); + ptr = sprintf(build_buf, CONFIG_SYS_VXWORKS_BOOT_DEVICE); tmp = getenv("bootfile"); if (tmp) - sprintf(&build_buf[strlen(build_buf)], - "%s:%s ", CONFIG_SYS_VXWORKS_SERVERNAME, tmp); + ptr += sprintf(build_buf + ptr, "%s:%s ", + CONFIG_SYS_VXWORKS_SERVERNAME, tmp); else - sprintf(&build_buf[strlen(build_buf)], - "%s:file ", CONFIG_SYS_VXWORKS_SERVERNAME); + ptr += sprintf(build_buf + ptr, "%s:file ", + CONFIG_SYS_VXWORKS_SERVERNAME); tmp = getenv("ipaddr"); if (tmp) - sprintf(&build_buf[strlen(build_buf)], "e=%s ", tmp); + ptr += sprintf(build_buf + ptr, "e=%s ", tmp); tmp = getenv("serverip"); if (tmp) - sprintf(&build_buf[strlen(build_buf)], "h=%s ", tmp); + ptr += sprintf(build_buf + ptr, "h=%s ", tmp); tmp = getenv("hostname"); if (tmp) - sprintf(&build_buf[strlen(build_buf)], "tn=%s ", tmp); + ptr += sprintf(build_buf + ptr, "tn=%s ", tmp); #ifdef CONFIG_SYS_VXWORKS_ADD_PARAMS - sprintf(&build_buf[strlen(build_buf)], - CONFIG_SYS_VXWORKS_ADD_PARAMS); + ptr += sprintf(build_buf + ptr, CONFIG_SYS_VXWORKS_ADD_PARAMS); #endif memcpy((void *)bootaddr, build_buf, -- cgit v1.2.3 From a4092dbd81ad8bcd7d405304f579b0b5b0c402ce Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 7 Oct 2015 20:19:16 -0700 Subject: cmd: bootvx: Pass netmask and gatewayip to VxWorks bootline There are fields in VxWorks bootline for netmask and gatewayip. We can get these from U-Boot environment variables and pass them to VxWorks, just like ipaddr and serverip. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- common/cmd_elf.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'common/cmd_elf.c') diff --git a/common/cmd_elf.c b/common/cmd_elf.c index 6c95851642..6a0937823f 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -288,13 +288,26 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) CONFIG_SYS_VXWORKS_SERVERNAME); tmp = getenv("ipaddr"); - if (tmp) - ptr += sprintf(build_buf + ptr, "e=%s ", tmp); + if (tmp) { + ptr += sprintf(build_buf + ptr, "e=%s", tmp); + tmp = getenv("netmask"); + if (tmp) { + __be32 addr = getenv_ip("netmask").s_addr; + ptr += sprintf(build_buf + ptr, ":%08x ", + ntohl(addr)); + } else { + ptr += sprintf(build_buf + ptr, " "); + } + } tmp = getenv("serverip"); if (tmp) ptr += sprintf(build_buf + ptr, "h=%s ", tmp); + tmp = getenv("gatewayip"); + if (tmp) + ptr += sprintf(build_buf + ptr, "g=%s ", tmp); + tmp = getenv("hostname"); if (tmp) ptr += sprintf(build_buf + ptr, "tn=%s ", tmp); -- cgit v1.2.3 From 9e98b7e3c5010e918d0fdfae75ab7d6995c1fa75 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 7 Oct 2015 20:19:17 -0700 Subject: cmd: bootvx: Always get VxWorks bootline from env So far VxWorks bootline can be contructed from various environment variables, but when these variables do not exist we get these from corresponding config macros. This is not helpful as it requires rebuilding U-Boot, and to make sure these config macros take effect we should not have these environment variables. This is a little bit complex and confusing. Now we change the logic to always contruct the bootline from environments (the only single source), by adding two new variables "bootdev" and "othbootargs", and adding some comments about network related settings mentioning they are optional. The doc about the bootline handling is also updated. Signed-off-by: Bin Meng Reviewed-by: Tom Rini Tested-by: Hannes Schmelzer --- README | 12 +----- common/cmd_elf.c | 119 ++++++++++++++++++++++++++++++------------------------ include/vxworks.h | 22 ---------- 3 files changed, 68 insertions(+), 85 deletions(-) (limited to 'common/cmd_elf.c') diff --git a/README b/README index 0dc657d0a5..d18df54ec9 100644 --- a/README +++ b/README @@ -796,18 +796,10 @@ The following options need to be configured: - vxWorks boot parameters: bootvx constructs a valid bootline using the following - environments variables: bootfile, ipaddr, serverip, hostname. + environments variables: bootdev, bootfile, ipaddr, netmask, + serverip, gatewayip, hostname, othbootargs. It loads the vxWorks image pointed bootfile. - CONFIG_SYS_VXWORKS_BOOT_DEVICE - The vxworks device name - CONFIG_SYS_VXWORKS_MAC_PTR - Ethernet 6 byte MA -address - CONFIG_SYS_VXWORKS_SERVERNAME - Name of the server - CONFIG_SYS_VXWORKS_BOOT_ADDR - Address of boot parameters - - CONFIG_SYS_VXWORKS_ADD_PARAMS - - Add it at the end of the bootline. E.g "u=username pw=secret" - Note: If a "bootargs" environment is defined, it will overwride the defaults discussed just above. diff --git a/common/cmd_elf.c b/common/cmd_elf.c index 6a0937823f..da70ef3e81 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -257,68 +257,83 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* * Use bootaddr to find the location in memory that VxWorks - * will look for the bootline string. The default value for - * PowerPC is LOCAL_MEM_LOCAL_ADRS + BOOT_LINE_OFFSET which - * defaults to 0x4200. + * will look for the bootline string. The default value is + * (LOCAL_MEM_LOCAL_ADRS + BOOT_LINE_OFFSET) as defined by + * VxWorks BSP. For example, on PowerPC it defaults to 0x4200. */ tmp = getenv("bootaddr"); - if (!tmp) - bootaddr = CONFIG_SYS_VXWORKS_BOOT_ADDR; - else - bootaddr = simple_strtoul(tmp, NULL, 16); - - /* - * Check to see if the bootline is defined in the 'bootargs' - * parameter. If it is not defined, we may be able to - * construct the info. - */ - bootline = getenv("bootargs"); - if (bootline) { - memcpy((void *)bootaddr, bootline, - max(strlen(bootline), (size_t)255)); - flush_cache(bootaddr, max(strlen(bootline), (size_t)255)); + if (!tmp) { + printf("## VxWorks bootline address not specified\n"); } else { - ptr = sprintf(build_buf, CONFIG_SYS_VXWORKS_BOOT_DEVICE); - tmp = getenv("bootfile"); - if (tmp) - ptr += sprintf(build_buf + ptr, "%s:%s ", - CONFIG_SYS_VXWORKS_SERVERNAME, tmp); - else - ptr += sprintf(build_buf + ptr, "%s:file ", - CONFIG_SYS_VXWORKS_SERVERNAME); + bootaddr = simple_strtoul(tmp, NULL, 16); - tmp = getenv("ipaddr"); - if (tmp) { - ptr += sprintf(build_buf + ptr, "e=%s", tmp); - tmp = getenv("netmask"); + /* + * Check to see if the bootline is defined in the 'bootargs' + * parameter. If it is not defined, we may be able to + * construct the info. + */ + bootline = getenv("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"); + if (tmp) + ptr = sprintf(build_buf, tmp); + else + printf("## VxWorks boot device not specified\n"); + + tmp = getenv("bootfile"); + if (tmp) + ptr += sprintf(build_buf + ptr, + "host:%s ", tmp); + else + ptr += sprintf(build_buf + ptr, + "host:vxWorks "); + + /* + * The following parameters are only needed if 'bootdev' + * is an ethernet device, otherwise they are optional. + */ + tmp = getenv("ipaddr"); if (tmp) { - __be32 addr = getenv_ip("netmask").s_addr; - ptr += sprintf(build_buf + ptr, ":%08x ", - ntohl(addr)); - } else { - ptr += sprintf(build_buf + ptr, " "); + ptr += sprintf(build_buf + ptr, "e=%s", tmp); + tmp = getenv("netmask"); + if (tmp) { + u32 mask = getenv_ip("netmask").s_addr; + ptr += sprintf(build_buf + ptr, + ":%08x ", ntohl(mask)); + } else { + ptr += sprintf(build_buf + ptr, " "); + } } - } - tmp = getenv("serverip"); - if (tmp) - ptr += sprintf(build_buf + ptr, "h=%s ", tmp); + tmp = getenv("serverip"); + if (tmp) + ptr += sprintf(build_buf + ptr, "h=%s ", tmp); - tmp = getenv("gatewayip"); - if (tmp) - ptr += sprintf(build_buf + ptr, "g=%s ", tmp); + tmp = getenv("gatewayip"); + if (tmp) + ptr += sprintf(build_buf + ptr, "g=%s ", tmp); - tmp = getenv("hostname"); - if (tmp) - ptr += sprintf(build_buf + ptr, "tn=%s ", tmp); + tmp = getenv("hostname"); + if (tmp) + ptr += sprintf(build_buf + ptr, "tn=%s ", tmp); -#ifdef CONFIG_SYS_VXWORKS_ADD_PARAMS - ptr += sprintf(build_buf + ptr, CONFIG_SYS_VXWORKS_ADD_PARAMS); -#endif + tmp = getenv("othbootargs"); + if (tmp) + ptr += sprintf(build_buf + ptr, tmp); + + memcpy((void *)bootaddr, build_buf, + max(strlen(build_buf), (size_t)255)); + flush_cache(bootaddr, max(strlen(build_buf), + (size_t)255)); + } - memcpy((void *)bootaddr, build_buf, - max(strlen(build_buf), (size_t)255)); - flush_cache(bootaddr, max(strlen(build_buf), (size_t)255)); + printf("## Using bootline (@ 0x%lx): %s\n", bootaddr, + (char *)bootaddr); } /* @@ -331,8 +346,6 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) else puts("## Not an ELF image, assuming binary\n"); - printf("## Using bootline (@ 0x%lx): %s\n", bootaddr, - (char *)bootaddr); printf("## Starting vxWorks at 0x%08lx ...\n", addr); dcache_disable(); diff --git a/include/vxworks.h b/include/vxworks.h index 122043c941..297a70f519 100644 --- a/include/vxworks.h +++ b/include/vxworks.h @@ -13,26 +13,4 @@ void boot_prep_vxworks(bootm_headers_t *images); void boot_jump_vxworks(bootm_headers_t *images); void do_bootvx_fdt(bootm_headers_t *images); -/* - * Use bootaddr to find the location in memory that VxWorks - * will look for the bootline string. The default value for - * PowerPC is LOCAL_MEM_LOCAL_ADRS + BOOT_LINE_OFFSET which - * defaults to 0x4200 - */ -#ifndef CONFIG_SYS_VXWORKS_BOOT_ADDR -#define CONFIG_SYS_VXWORKS_BOOT_ADDR 0x4200 -#endif - -#ifndef CONFIG_SYS_VXWORKS_BOOT_DEVICE -#if defined(CONFIG_4xx) -#define CONFIG_SYS_VXWORKS_BOOT_DEVICE "emac(0,0)" -#else -#define CONFIG_SYS_VXWORKS_BOOT_DEVICE "eth(0,0)" -#endif -#endif - -#ifndef CONFIG_SYS_VXWORKS_SERVERNAME -#define CONFIG_SYS_VXWORKS_SERVERNAME "srv" -#endif - #endif -- cgit v1.2.3 From b90ff0fdaadc4de096afed605b36aac1185fc1dc Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 7 Oct 2015 20:19:18 -0700 Subject: cmd: bootvx: Pass E820 information to an x86 VxWorks kernel E820 is critical to the kernel as it provides system memory map information. Pass it to an x86 VxWorks kernel. Signed-off-by: Bin Meng Acked-by: Simon Glass Reviewed-by: Tom Rini Tested-by: Jian Luo --- common/cmd_elf.c | 30 ++++++++++++++++++++++++++++++ include/vxworks.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) (limited to 'common/cmd_elf.c') diff --git a/common/cmd_elf.c b/common/cmd_elf.c index da70ef3e81..d6a2036a99 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -18,6 +18,9 @@ #include #include #include +#ifdef CONFIG_X86 +#include +#endif /* * A very simple elf loader, assumes the image is valid, returns the @@ -214,6 +217,10 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) char *tmp; /* Temporary char pointer */ char build_buf[128]; /* Buffer for building the bootline */ int ptr = 0; +#ifdef CONFIG_X86 + struct e820info *info; + struct e820entry *data; +#endif /* * Check the loadaddr variable. @@ -336,6 +343,29 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) (char *)bootaddr); } +#ifdef CONFIG_X86 + /* + * Since E820 information is critical to the kernel, if we don't + * specify these in the environments, 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; + + memset(info, 0, sizeof(struct e820info)); + info->sign = E820_SIGNATURE; + info->entries = install_e820_map(E820MAX, data); + info->addr = (info->entries - 1) * sizeof(struct e820entry) + + VXWORKS_E820_DATA_ADDR; +#endif + /* * If the data at the load address is an elf image, then * treat it like an elf image. Otherwise, assume that it is a diff --git a/include/vxworks.h b/include/vxworks.h index 297a70f519..f69b0084ff 100644 --- a/include/vxworks.h +++ b/include/vxworks.h @@ -8,6 +8,35 @@ #ifndef _VXWORKS_H_ #define _VXWORKS_H_ +/* + * VxWorks x86 E820 related stuff + * + * VxWorks on x86 gets E820 information from pre-defined address @ + * 0x4a00 and 0x4000. At 0x4a00 it's an information table defined + * by VxWorks and the actual E820 table entries starts from 0x4000. + * As defined by the BIOS E820 spec, the maximum number of E820 table + * entries is 128 and each entry occupies 20 bytes, so it's 128 * 20 + * = 2560 (0xa00) bytes in total. That's where VxWorks stores some + * information that is retrieved from the BIOS E820 call and saved + * later for sanity test during the kernel boot-up. + */ +#define VXWORKS_E820_DATA_ADDR 0x4000 +#define VXWORKS_E820_INFO_ADDR 0x4a00 + +/* E820 info signatiure "SMAP" - System MAP */ +#define E820_SIGNATURE 0x534d4150 + +struct e820info { + u32 sign; /* "SMAP" signature */ + u32 x0; /* don't care, used by VxWorks */ + u32 x1; /* don't care, used by VxWorks */ + u32 x2; /* don't care, used by VxWorks */ + u32 addr; /* last e820 table entry addr */ + u32 x3; /* don't care, used by VxWorks */ + u32 entries; /* e820 table entry count */ + u32 error; /* must be zero */ +}; + int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); void boot_prep_vxworks(bootm_headers_t *images); void boot_jump_vxworks(bootm_headers_t *images); -- cgit v1.2.3 From 9aa1280a5644a1d05859b862ebc7b60a862e0ef3 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 7 Oct 2015 20:19:19 -0700 Subject: cmd: bootvx: Add asmlinkage to the VxWorks x86 entry VxWorks on x86 uses stack to pass parameters. Reported-by: Jian Luo Signed-off-by: Bin Meng Acked-by: Simon Glass --- common/cmd_elf.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'common/cmd_elf.c') diff --git a/common/cmd_elf.c b/common/cmd_elf.c index d6a2036a99..86e694ac69 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -20,6 +20,7 @@ #include #ifdef CONFIG_X86 #include +#include #endif /* @@ -379,7 +380,12 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("## Starting vxWorks at 0x%08lx ...\n", addr); dcache_disable(); +#ifdef CONFIG_X86 + /* VxWorks on x86 uses stack to pass parameters */ + ((asmlinkage void (*)(int))addr)(0); +#else ((void (*)(int))addr)(0); +#endif puts("## vxWorks terminated\n"); -- cgit v1.2.3