armv8: semihosting: add a command to load semihosted images

Instead of sprinkling custom code and calls over the Vexpress64
boardfile, create a command that loads images using semihosting
just like we would load from flash memory of over the network,
using a special command:

    smhload <image> <address>

This will make it possible to remove some custom calls and
code and make the boot easier.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
Linus Walleij 2015-03-23 11:06:11 +01:00 committed by Tom Rini
parent e769f68613
commit 202a674bb8
2 changed files with 75 additions and 20 deletions

View File

@ -13,6 +13,7 @@
* for them.
*/
#include <common.h>
#include <command.h>
#include <asm/semihosting.h>
#define SYSOPEN 0x01
@ -234,3 +235,72 @@ long smh_len(const char *fname)
/* Return the file length (or -1 error indication) */
return len;
}
static int smh_load_file(const char * const name, ulong load_addr,
ulong *end_addr)
{
long fd;
long len;
long ret;
fd = smh_open(name, "rb");
if (fd == -1)
return -1;
len = smh_len_fd(fd);
if (len < 0) {
smh_close(fd);
return -1;
}
ret = smh_read(fd, (void *)load_addr, len);
smh_close(fd);
if (ret == 0) {
*end_addr = load_addr + len - 1;
printf("loaded file %s from %08lX to %08lX, %08lX bytes\n",
name,
load_addr,
*end_addr,
len);
} else {
printf("read failed\n");
return 0;
}
return 0;
}
static int do_smhload(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
if (argc == 3 || argc == 4) {
ulong load_addr;
ulong end_addr = 0;
ulong ret;
char end_str[64];
load_addr = simple_strtoul(argv[2], NULL, 16);
if (!load_addr)
return -1;
ret = smh_load_file(argv[1], load_addr, &end_addr);
if (ret < 0)
return 1;
/* Optionally save returned end to the environment */
if (argc == 4) {
sprintf(end_str, "0x%08lx", end_addr);
setenv(argv[3], end_str);
}
} else {
return CMD_RET_USAGE;
}
return 0;
}
U_BOOT_CMD(smhload, 4, 0, do_smhload, "load a file using semihosting",
"<file> 0x<address> [end var]\n"
" - load a semihosted file to the address specified\n"
" if the optional [end var] is specified, the end\n"
" address of the file will be stored in this environment\n"
" variable.\n");

View File

@ -30,25 +30,10 @@ vexpress_aemv8a.h but differentiate the two models by the presence or
absence of CONFIG_BASE_FVP. This change is tested and works on both the
Foundation and Base fastmodel simulators.
The level of semihosting support is minimal, restricted to just what it
takes to load images to memory. If more semihosting functionality is
required, such as file seek, outputting strings, reading characters, etc,
then it can be easily added later.
The semihosting code adds a command:
We require that the board include file define these env variables:
- kernel_name e.g. "uImage"
- kernel_addr_r e.g. "0x80000000"
- initrd_name e.g. "ramdisk.img"
- initrd_addr_r e.g. "0x88000000"
- fdt_name e.g. "devtree.dtb"
- fdt_addr_r e.g. "0x83000000"
smhload <image> <address> [env var]
Optionally, "fdt_high" and "initrd_high" can be specified as per
their rules for allowing or preventing copying of these images.
For the "fdt chosen" startup macro, this code will then define:
- initrd_end (based on retrieving initrd_addr_r plus actual initrd_size)
We will then load the kernel, initrd, and fdt into the specified
locations in memory in a similar way that the ATF fastmodel code
uses semihosting calls to load other boot stages and u-boot itself.
That will load an image from the host filesystem into RAM at the specified
address and optionally store the load end address in the specified
environment variable.