Message ID | 1395688573-28855-1-git-send-email-drambo@broadcom.com |
---|---|
State | New |
Headers | show |
Hi Darwin, > -----Original Message----- > From: Darwin Rambo [mailto:drambo@broadcom.com] > Sent: Tuesday, March 25, 2014 12:46 AM > To: u-boot@lists.denx.de > Cc: Darwin Rambo; Albert Aribaud; Tom Rini; fenghua@phytium.com.cn; > Sharma Bhupesh-B45370 > Subject: [PATCH v3] arm: Add support for semihosting for armv8 fastmodel > targets. > > The reason for this change is to be able to use the ARM Trusted Firmware > (ATF) to load the various ATF images, plus u-boot, which can then load > the kernel/ramdisk/dtb with calls to an external host from a standard > fastmodel armv8 board file using semihosting, and then launch the kernel > without a bootwrapper. This gives us a more realistic boot sequence. > > There are two main ARM virtual Fixed Virtual Platform (FVP) models, > Versatile Express (VE) FVP and BASE FVP (See > http://www.arm.com/products/tools/models/fast-models/foundation- > model.php) > The initial vexpress64 u-boot board created here runs on the VE virtual > platform using the license-free Foundation_v8 simulator. Fortunately, the > Foundation_v8 simulator also supports the BASE_FVP model which companies > can purchase licenses for and contain much more functionality. > So we can, in u-boot, run either model by either using the VE FVP > (default), or turning on CONFIG_BASE_FVP for the more full featured > model. > > Rather than create a new armv8 board similar to armltd/vexpress64, add > semihosting calls to the existing one, enabled with CONFIG_SEMIHOSTING > and CONFIG_BASE_FVP both set. Also reuse the existing board config file > 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. > > Support for armv7 in fastmodel is less useful due to the wide range of > available silicon and the lack of a free armv7 fastmodel, so this change > contains an untested armv7 placeholder for the service trap opcode. > > 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. Sorry for the late reply. We are using ARMv8 foundation model (the free version) to launch u-boot via the ARM Trusted Firmware (ATF). We are using a older u-boot version and cannot see the ATF launching the u-boot.bin. Please find the details of the ARMv8 foundation model command line and ATF, u-boot commit logs below (Host machine is a ubuntu-64 bit). ARMv8 foundation model Command Line used ----------------------------------------- $ ./Foundation_v8 --cores=1 --no-secure-memory --visualization --gicv3 --data="bl1.bin"@0x00000000 --data="fip.bin"@0x80000000 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Booting trusted firmware boot loader stage 1 Built : 12:58:21, May 22 2014 ERROR: Firmware Image Package header check failed. Booting trusted firmware boot loader stage 2 BL2 Built : 12:58:22, May 22 2014 ERROR: Firmware Image Package header check failed. ERROR: Firmware Image Package header check failed. Booting trusted firmware boot loader stage 3 BL31 Built : 12:58:23, May 22 2014 ATF latest commit ----------------- commit ca823d2c881d9d8c7db364de7e362d2e75ad55df Author: Achin Gupta <achin.gupta@arm.com> Date: Sun Feb 2 13:04:00 2014 +0000 Increase coherent stack sizes This patch increases coherent stack size for both debug and release builds in order to accommodate stack-heavy printf() and extended EL3 functionality Change-Id: I30ef30530a01517a97e63d703873374828c09f20 u-boot commit ------------- commit 22a240c32c1340183fce12867ae5f8736b92a638 Author: Alexey Brodkin <Alexey.Brodkin@synopsys.com> Date: Fri Dec 13 10:35:11 2013 +0400 serial/serial_arc - add driver for ARC UART Driver for non-standard on-chip UART, instantiated in the ARC (Synopsys) FPGA Boards such as ARCAngel4/ML50x Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com Regards, Bhupesh > Signed-off-by: Darwin Rambo <drambo@broadcom.com> > --- > > Changes in v3: > - minor format fixup in board file > > Changes in v2: > - use kernel_addr_r, fdt_addr_r, initrd_addr_r convention. > - Use env variables for kernel/fdt/initrd file names. > - Add CONFIG_BASE_FVP to differentiate VE and BASE FVP models. > - CONFIG_SEMIHOSTING only refers to bringing in semihosting code now. > - Remove unnecessary CONFIG_SYS_BAUDRATE_TABLE, > CONFIG_SYS_PROMPT_HUSH_PS2 > - Remove vexpress_aemv8a_semi.h and replace with CONFIG_BASE_FVP > - Update boards.cfg with option SEMIHOSTING and BASE_FVP > - Add doc/README.semihosting > > Changes in v1: > - Initial code > - Remove empty timer_init() function. > > arch/arm/include/asm/semihosting.h | 21 +++ > arch/arm/lib/Makefile | 1 + > arch/arm/lib/semihosting.c | 235 > ++++++++++++++++++++++++++++++++++ > board/armltd/vexpress64/vexpress64.c | 101 ++++++++++++++- > boards.cfg | 1 + > doc/README.semihosting | 35 +++++ > include/configs/vexpress_aemv8a.h | 59 ++++++++- > 7 files changed, 441 insertions(+), 12 deletions(-) create mode 100644 > arch/arm/include/asm/semihosting.h > create mode 100644 arch/arm/lib/semihosting.c create mode 100644 > doc/README.semihosting > > diff --git a/arch/arm/include/asm/semihosting.h > b/arch/arm/include/asm/semihosting.h > new file mode 100644 > index 0000000..74111dc > --- /dev/null > +++ b/arch/arm/include/asm/semihosting.h > @@ -0,0 +1,21 @@ > +/* > + * Copyright 2014 Broadcom Corporation > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#ifndef __SEMIHOSTING_H__ > +#define __SEMIHOSTING_H__ > + > +/* > + * ARM semihosting functions for loading images to memory. See the > +source > + * code for more information. > + */ > +int smh_load(const char *fname, void *memp, int avail, int verbose); > +int smh_read(int fd, void *memp, int len); int smh_open(const char > +*fname, char *modestr); int smh_close(int fd); int smh_len_fd(int fd); > +int smh_len(const char *fname); > + > +#endif /* __SEMIHOSTING_H__ */ > diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index > 9fc81cd..0ba929d 100644 > --- a/arch/arm/lib/Makefile > +++ b/arch/arm/lib/Makefile > @@ -32,6 +32,7 @@ obj-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o else > obj-$(CONFIG_SPL_FRAMEWORK) += spl.o > endif > +obj-$(CONFIG_SEMIHOSTING) += semihosting.o > > obj-y += sections.o > ifdef CONFIG_ARM64 > diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c new > file mode 100644 index 0000000..d603789 > --- /dev/null > +++ b/arch/arm/lib/semihosting.c > @@ -0,0 +1,235 @@ > +/* > + * Copyright 2014 Broadcom Corporation > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +/* > + * Minimal semihosting implementation for reading files into memory. If > +more > + * features like writing files or console output are required they can > +be > + * added later. This code has been tested on arm64/aarch64 fastmodel > only. > + * An untested placeholder exists for armv7 architectures, but since > +they > + * are commonly available in silicon now, fastmodel usage makes less > +sense > + * for them. > + */ > +#include <common.h> > +#include <asm/semihosting.h> > + > +#define SYSOPEN 0x01 > +#define SYSCLOSE 0x02 > +#define SYSREAD 0x06 > +#define SYSFLEN 0x0C > + > +#define MODE_READ 0x0 > +#define MODE_READBIN 0x1 > + > +/* > + * Call the handler > + */ > +static int smh_trap(unsigned int sysnum, void *addr) { > + register int result asm("r0"); > +#if defined(CONFIG_ARM64) > + asm volatile ("hlt #0xf000" : "=r" (result) : "0"(sysnum), > "r"(addr)); > +#else > + /* Note - untested placeholder */ > + asm volatile ("svc #0x123456" : "=r" (result) : "0"(sysnum), > +"r"(addr)); #endif > + return result; > +} > + > +/* > + * Open, load a file into memory, and close it. Check that the > +available space > + * is sufficient to store the entire file. Return the bytes actually > +read from > + * the file as seen by the read function. The verbose flag enables some > +extra > + * printing of successful read status. > + */ > +int smh_load(const char *fname, void *memp, int avail, int verbose) { > + int ret, fd, len; > + > + ret = -1; > + > + debug("%s: fname \'%s\', avail %u, memp %p\n", __func__, fname, > + avail, memp); > + > + /* Open the file */ > + fd = smh_open(fname, "rb"); > + if (fd == -1) > + return ret; > + > + /* Get the file length */ > + ret = smh_len_fd(fd); > + if (ret == -1) { > + smh_close(fd); > + return ret; > + } > + > + /* Check that the file will fit in the supplied buffer */ > + if (ret > avail) { > + printf("%s: ERROR ret %d, avail %u\n", __func__, ret, > + avail); > + smh_close(fd); > + return ret; > + } > + > + len = ret; > + > + /* Read the file into the buffer */ > + ret = smh_read(fd, memp, len); > + if (ret == 0) { > + /* Print successful load information if requested */ > + if (verbose) { > + printf("\n%s\n", fname); > + printf(" 0x%8p dest\n", memp); > + printf(" 0x%08x size\n", len); > + printf(" 0x%08x avail\n", avail); > + } > + } > + > + /* Close the file */ > + smh_close(fd); > + > + return ret; > +} > + > +/* > + * Read 'len' bytes of file into 'memp'. Returns 0 on success, else > +failure */ int smh_read(int fd, void *memp, int len) { > + int ret; > + struct smh_read_s { > + int fd; > + void *memp; > + int len; > + } read; > + > + debug("%s: fd %d, memp %p, len %d\n", __func__, fd, memp, len); > + > + read.fd = fd; > + read.memp = memp; > + read.len = len; > + > + ret = smh_trap(SYSREAD, &read); > + if (ret == 0) { > + return 0; > + } else { > + /* > + * The ARM handler allows for returning partial lengths, > + * but if this ever happens, it is a bug in the fastmodel > + * implementation. The Linux fastmodel doesn't show this > + * issue, and any Windows fastmodel bugs need to be fixed. > + * So rather than create ugly unmaintainable partial read > + * loops and such, just fail with an error message. > + */ > + printf("%s: ERROR ret %d, fd %d, len %u memp %p\n", > + __func__, ret, fd, len, memp); > + } > + return ret; > +} > + > +/* > + * Open a file on the host. Mode is "r" or "rb" currently. Returns a > +file > + * descriptor or -1 on error. > + */ > +int smh_open(const char *fname, char *modestr) { > + int ret, fd, mode; > + struct smh_open_s { > + const char *fname; > + unsigned int mode; > + unsigned int len; > + } open; > + > + debug("%s: file \'%s\', mode \'%s\'\n", __func__, fname, modestr); > + > + ret = -1; > + > + /* Check the file mode */ > + if (!(strcmp(modestr, "r"))) { > + mode = MODE_READ; > + } else if (!(strcmp(modestr, "rb"))) { > + mode = MODE_READBIN; > + } else { > + printf("%s: ERROR mode \'%s\' not supported\n", __func__, > + modestr); > + return ret; > + } > + > + open.fname = fname; > + open.len = strlen(fname); > + open.mode = mode; > + > + /* Open the file on the host */ > + fd = smh_trap(SYSOPEN, &open); > + if (fd == -1) > + printf("%s: ERROR fd %d for file \'%s\'\n", __func__, fd, > + fname); > + > + return fd; > +} > + > +/* > + * Close the file using the file descriptor */ int smh_close(int fd) { > + int ret; > + long fdlong; > + > + debug("%s: fd %d\n", __func__, fd); > + > + fdlong = (long)fd; > + ret = smh_trap(SYSCLOSE, &fdlong); > + if (ret == -1) > + printf("%s: ERROR fd %d\n", __func__, fd); > + > + return ret; > +} > + > +/* > + * Get the file length from the file descriptor */ int smh_len_fd(int > +fd) { > + int ret; > + long fdlong; > + > + debug("%s: fd %d\n", __func__, fd); > + > + fdlong = (long)fd; > + ret = smh_trap(SYSFLEN, &fdlong); > + if (ret == -1) > + printf("%s: ERROR ret %d\n", __func__, ret); > + > + return ret; > +} > + > +/* > + * Get the file length from the filename */ int smh_len(const char > +*fname) { > + int ret, fd, len; > + > + debug("%s: file \'%s\'\n", __func__, fname); > + > + /* Open the file */ > + fd = smh_open(fname, "rb"); > + if (fd == -1) > + return fd; > + > + /* Get the file length */ > + len = smh_len_fd(fd); > + > + /* Close the file */ > + ret = smh_close(fd); > + if (ret == -1) > + return ret; > + > + debug("%s: returning len %d\n", __func__, len); > + > + /* Return the file length (or -1 error indication) */ > + return len; > +} > diff --git a/board/armltd/vexpress64/vexpress64.c > b/board/armltd/vexpress64/vexpress64.c > index 2ec3bc9..5897318 100644 > --- a/board/armltd/vexpress64/vexpress64.c > +++ b/board/armltd/vexpress64/vexpress64.c > @@ -11,6 +11,7 @@ > #include <netdev.h> > #include <asm/io.h> > #include <linux/compiler.h> > +#include <asm/semihosting.h> > > DECLARE_GLOBAL_DATA_PTR; > > @@ -31,11 +32,6 @@ int dram_init(void) > return 0; > } > > -int timer_init(void) > -{ > - return 0; > -} > - > /* > * Board specific reset that is system reset. > */ > @@ -43,6 +39,101 @@ void reset_cpu(ulong addr) { } > > +#ifdef CONFIG_BOARD_LATE_INIT > +int board_late_init(void) > +{ > +#ifdef CONFIG_SEMIHOSTING > + /* > + * Please refer to doc/README.semihosting for a more complete > + * description. > + * > + * We require that the board include file defines these env > variables: > + * - kernel_name > + * - kernel_addr_r > + * - initrd_name > + * - initrd_addr_r > + * - fdt_name > + * - fdt_addr_r > + * > + * For the "fdt chosen" startup macro, this code will then define: > + * - initrd_end (based on 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. > + */ > + > + /* Env variable strings */ > + char *kernel_name = getenv("kernel_name"); > + char *kernel_addr_str = getenv("kernel_addr_r"); > + char *initrd_name = getenv("initrd_name"); > + char *initrd_addr_str = getenv("initrd_addr_r"); > + char *fdt_name = getenv("fdt_name"); > + char *fdt_addr_str = getenv("fdt_addr_r"); > + char initrd_end_str[64]; > + > + /* Actual addresses converted from env variables */ > + void *kernel_addr_r; > + void *initrd_addr_r; > + void *fdt_addr_r; > + > + /* Actual initrd base and size */ > + unsigned long initrd_base; > + unsigned long initrd_size; > + > + /* Space available */ > + int avail; > + > + /* Make sure the environment variables needed are set */ > + if (!(kernel_addr_str && initrd_addr_str && fdt_addr_str)) { > + printf("%s: Define {kernel/initrd/fdt}_addr_r\n", __func__); > + return -1; > + } > + if (!(kernel_name && initrd_name && fdt_name)) { > + printf("%s: Define {kernel/initrd/fdt}_name\n", __func__); > + return -1; > + } > + > + /* Get exact initrd_size */ > + initrd_size = smh_len(initrd_name); > + if (initrd_size == -1) { > + printf("%s: Can't get file size for \'%s\'\n", __func__, > + initrd_name); > + return -1; > + } > + > + /* Set initrd_end */ > + initrd_base = simple_strtoul(initrd_addr_str, NULL, 16); > + initrd_addr_r = (void *)initrd_base; > + sprintf(initrd_end_str, "0x%lx", initrd_base + initrd_size - 1); > + setenv("initrd_end", initrd_end_str); > + > + /* Load kernel to memory */ > + fdt_addr_r = (void *)simple_strtoul(fdt_addr_str, NULL, 16); > + kernel_addr_r = (void *)simple_strtoul(kernel_addr_str, NULL, 16); > + > + /* > + * The kernel must be lower in memory than fdt and loading the > + * kernel must not trample the fdt or vice versa. > + */ > + avail = fdt_addr_r - kernel_addr_r; > + if (avail < 0) { > + printf("%s: fdt must be after kernel\n", __func__); > + return -1; > + } > + smh_load(kernel_name, kernel_addr_r, avail, 1); > + > + /* Load fdt to memory */ > + smh_load(fdt_name, fdt_addr_r, 0x20000, 1); > + > + /* Load initrd to memory */ > + smh_load(initrd_name, initrd_addr_r, initrd_size, 1); > + > +#endif /* CONFIG_SEMIHOSTING */ > + return 0; > +} > +#endif /* CONFIG_BOARD_LATE_INIT */ > + > /* > * Board specific ethernet initialization routine. > */ > diff --git a/boards.cfg b/boards.cfg > index 69c8936..d142b10 100644 > --- a/boards.cfg > +++ b/boards.cfg > @@ -44,6 +44,7 @@ > > ######################################################################### > ################################## > > Active aarch64 armv8 - armltd > vexpress64 vexpress_aemv8a > vexpress_aemv8a:ARM64 > David Feng <fenghua@phytium.com.cn> > +Active aarch64 armv8 - armltd > vexpress64 vexpress_aemv8a_semi > vexpress_aemv8a:ARM64,SEMIHOSTING,BASE_FVP > Darwin Rambo <drambo@broadcom.com> > Active arc arc700 - synopsys - > axs101 - > Alexey Brodkin <abrodkin@synopsys.com> > Active arc arc700 - synopsys <none> > arcangel4 - > Alexey Brodkin <abrodkin@synopsys.com> > Active arc arc700 - synopsys <none> > arcangel4-be - > Alexey Brodkin <abrodkin@synopsys.com> > diff --git a/doc/README.semihosting b/doc/README.semihosting new file > mode 100644 index 0000000..c999a27 > --- /dev/null > +++ b/doc/README.semihosting > @@ -0,0 +1,35 @@ > +/* > + * Copyright 2014 Broadcom Corporation. > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +Semihosting is ARM's way of having a real or virtual target communicate > +with a host or host debugger for basic operations such as file I/O, > +console I/O, etc. Please see > +http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0471c/Bgb > jjgij.html for more information. > + > +For developing on armv8 virtual fastmodel platforms, semihosting is a > +valuable tool since it allows access to image/configuration files > +before eMMC or other NV media are available. > + > +For reference, the current example is enabled by setting > +CONFIG_SEMIHOSTING for the "vexpress_aemv8a" board. > + > +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" > + > +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. > diff --git a/include/configs/vexpress_aemv8a.h > b/include/configs/vexpress_aemv8a.h > index e851702..96978f5 100644 > --- a/include/configs/vexpress_aemv8a.h > +++ b/include/configs/vexpress_aemv8a.h > @@ -10,6 +10,14 @@ > > #define DEBUG > > +#ifdef CONFIG_BASE_FVP > +#ifndef CONFIG_SEMIHOSTING > +#error CONFIG_BASE_FVP requires CONFIG_SEMIHOSTING #endif #define > +CONFIG_BOARD_LATE_INIT #define CONFIG_ARMV8_SWITCH_TO_EL1 #endif > + > #define CONFIG_REMAKE_ELF > > /*#define CONFIG_ARMV8_SWITCH_TO_EL1*/ > @@ -28,8 +36,14 @@ > #define CONFIG_BOOTP_VCI_STRING "U-boot.armv8.vexpress_aemv8a" > > /* Link Definitions */ > +#ifdef CONFIG_BASE_FVP > +/* ATF loads u-boot here for BASE_FVP model */ > +#define CONFIG_SYS_TEXT_BASE 0x88000000 > +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + > 0x03f00000) > +#else > #define CONFIG_SYS_TEXT_BASE 0x80000000 > #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + > 0x7fff0) > +#endif > > /* Flat Device Tree Definitions */ > #define CONFIG_OF_LIBFDT > @@ -37,7 +51,11 @@ > #define CONFIG_DEFAULT_DEVICE_TREE vexpress64 > > /* SMP Spin Table Definitions */ > +#ifdef CONFIG_BASE_FVP > +#define CPU_RELEASE_ADDR (CONFIG_SYS_SDRAM_BASE + 0x03f00000) > +#else > #define CPU_RELEASE_ADDR (CONFIG_SYS_SDRAM_BASE + 0x7fff0) > +#endif > > /* CS register bases for the original memory map. */ > #define V2M_PA_CS0 0x00000000 > @@ -93,8 +111,13 @@ > #define COUNTER_FREQUENCY (0x1800000) /* 24MHz */ > > /* Generic Interrupt Controller Definitions */ > +#ifdef CONFIG_BASE_FVP > +#define GICD_BASE (0x2f000000) > +#define GICC_BASE (0x2c000000) > +#else > #define GICD_BASE (0x2C001000) > #define GICC_BASE (0x2C002000) > +#endif > > #define CONFIG_SYS_MEMTEST_START V2M_BASE > #define CONFIG_SYS_MEMTEST_END (V2M_BASE + 0x80000000) > @@ -114,7 +137,6 @@ > #define CONFIG_CONS_INDEX 0 > > #define CONFIG_BAUDRATE 115200 > -#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } > #define CONFIG_SYS_SERIAL0 V2M_UART0 > #define CONFIG_SYS_SERIAL1 V2M_UART1 > > @@ -158,17 +180,41 @@ > #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 > > /* Initial environment variables */ > +#ifdef CONFIG_BASE_FVP > +#define CONFIG_EXTRA_ENV_SETTINGS \ > + "kernel_name=uImage\0" \ > + "kernel_addr_r=0x80000000\0" \ > + "initrd_name=ramdisk.img\0" \ > + "initrd_addr_r=0x88000000\0" \ > + "fdt_name=devtree.dtb\0" \ > + "fdt_addr_r=0x83000000\0" \ > + "fdt_high=0xffffffffffffffff\0" \ > + "initrd_high=0xffffffffffffffff\0" > + > +#define CONFIG_BOOTARGS "console=ttyAMA0 earlyprintk=pl011,"\ > + "0x1c090000 debug user_debug=31 "\ > + "loglevel=9" > + > +#define CONFIG_BOOTCOMMAND "fdt addr $fdt_addr_r; fdt resize; " \ > + "fdt chosen $initrd_addr_r $initrd_end; " \ > + "bootm $kernel_addr_r - $fdt_addr_r" > + > +#define CONFIG_BOOTDELAY 1 > + > +#else > + > #define CONFIG_EXTRA_ENV_SETTINGS \ > - "kernel_addr=0x200000\0" \ > - "initrd_addr=0xa00000\0" \ > + "kernel_addr_r=0x200000\0" \ > + "initrd_addr_r=0xa00000\0" \ > "initrd_size=0x2000000\0" \ > - "fdt_addr=0x100000\0" \ > + "fdt_addr_r=0x100000\0" \ > "fdt_high=0xa0000000\0" > > #define CONFIG_BOOTARGS "console=ttyAMA0 > root=/dev/ram0" > -#define CONFIG_BOOTCOMMAND "bootm $kernel_addr " \ > - "$initrd_addr:$initrd_size $fdt_addr" > +#define CONFIG_BOOTCOMMAND "bootm $kernel_addr_r " \ > + "$initrd_addr_r:$initrd_size $fdt_addr_r" > #define CONFIG_BOOTDELAY -1 > +#endif > > /* Do not preserve environment */ > #define CONFIG_ENV_IS_NOWHERE 1 > @@ -180,7 +226,6 @@ > #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ > sizeof(CONFIG_SYS_PROMPT) + 16) > #define CONFIG_SYS_HUSH_PARSER > -#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " > #define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE > #define CONFIG_SYS_LONGHELP > #define CONFIG_CMDLINE_EDITING 1 > -- > 1.7.9.5 > >
Hi Bhupesh, I believe that this patch is now stale, because other changes to boards.cfg and vexpress_aemv8a.h were done after this patch was submitted. So it doesn't apply cleanly anymore and needs to be regenerated. In the meantime can you remove this patch from your world since I believe that it doesn't provide any functionality you need at this time? I will send in a v4 patch that applies cleanly to the latest u-boot. Am I suggesting the right process here? Thanks, Darwin On 14-05-23 05:05 AM, bhupesh.sharma@freescale.com wrote: > Hi Darwin, > >> -----Original Message----- >> From: Darwin Rambo [mailto:drambo@broadcom.com] >> Sent: Tuesday, March 25, 2014 12:46 AM >> To: u-boot@lists.denx.de >> Cc: Darwin Rambo; Albert Aribaud; Tom Rini; fenghua@phytium.com.cn; >> Sharma Bhupesh-B45370 >> Subject: [PATCH v3] arm: Add support for semihosting for armv8 fastmodel >> targets. >> >> The reason for this change is to be able to use the ARM Trusted Firmware >> (ATF) to load the various ATF images, plus u-boot, which can then load >> the kernel/ramdisk/dtb with calls to an external host from a standard >> fastmodel armv8 board file using semihosting, and then launch the kernel >> without a bootwrapper. This gives us a more realistic boot sequence. >> >> There are two main ARM virtual Fixed Virtual Platform (FVP) models, >> Versatile Express (VE) FVP and BASE FVP (See >> http://www.arm.com/products/tools/models/fast-models/foundation- >> model.php) >> The initial vexpress64 u-boot board created here runs on the VE virtual >> platform using the license-free Foundation_v8 simulator. Fortunately, the >> Foundation_v8 simulator also supports the BASE_FVP model which companies >> can purchase licenses for and contain much more functionality. >> So we can, in u-boot, run either model by either using the VE FVP >> (default), or turning on CONFIG_BASE_FVP for the more full featured >> model. >> >> Rather than create a new armv8 board similar to armltd/vexpress64, add >> semihosting calls to the existing one, enabled with CONFIG_SEMIHOSTING >> and CONFIG_BASE_FVP both set. Also reuse the existing board config file >> 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. >> >> Support for armv7 in fastmodel is less useful due to the wide range of >> available silicon and the lack of a free armv7 fastmodel, so this change >> contains an untested armv7 placeholder for the service trap opcode. >> >> 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. > > Sorry for the late reply. We are using ARMv8 foundation model (the free version) > to launch u-boot via the ARM Trusted Firmware (ATF). We are using a older > u-boot version and cannot see the ATF launching the u-boot.bin. > > Please find the details of the ARMv8 foundation model command line and ATF, u-boot commit > logs below (Host machine is a ubuntu-64 bit). > > ARMv8 foundation model Command Line used > ----------------------------------------- > > $ ./Foundation_v8 --cores=1 --no-secure-memory --visualization --gicv3 --data="bl1.bin"@0x00000000 --data="fip.bin"@0x80000000 > > Trying 127.0.0.1... > Connected to localhost. > Escape character is '^]'. > Booting trusted firmware boot loader stage 1 > Built : 12:58:21, May 22 2014 > ERROR: Firmware Image Package header check failed. > Booting trusted firmware boot loader stage 2 > BL2 Built : 12:58:22, May 22 2014 > ERROR: Firmware Image Package header check failed. > ERROR: Firmware Image Package header check failed. > Booting trusted firmware boot loader stage 3 > BL31 Built : 12:58:23, May 22 2014 > > ATF latest commit > ----------------- > > commit ca823d2c881d9d8c7db364de7e362d2e75ad55df > Author: Achin Gupta <achin.gupta@arm.com> > Date: Sun Feb 2 13:04:00 2014 +0000 > > Increase coherent stack sizes > > This patch increases coherent stack size for both debug and release > builds in order to accommodate stack-heavy printf() and extended EL3 > functionality > > Change-Id: I30ef30530a01517a97e63d703873374828c09f20 > > u-boot commit > ------------- > > commit 22a240c32c1340183fce12867ae5f8736b92a638 > Author: Alexey Brodkin <Alexey.Brodkin@synopsys.com> > Date: Fri Dec 13 10:35:11 2013 +0400 > > serial/serial_arc - add driver for ARC UART > > Driver for non-standard on-chip UART, instantiated in the ARC (Synopsys) > FPGA Boards such as ARCAngel4/ML50x > > Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com > > Regards, > Bhupesh > >> Signed-off-by: Darwin Rambo <drambo@broadcom.com> >> --- >> >> Changes in v3: >> - minor format fixup in board file >> >> Changes in v2: >> - use kernel_addr_r, fdt_addr_r, initrd_addr_r convention. >> - Use env variables for kernel/fdt/initrd file names. >> - Add CONFIG_BASE_FVP to differentiate VE and BASE FVP models. >> - CONFIG_SEMIHOSTING only refers to bringing in semihosting code now. >> - Remove unnecessary CONFIG_SYS_BAUDRATE_TABLE, >> CONFIG_SYS_PROMPT_HUSH_PS2 >> - Remove vexpress_aemv8a_semi.h and replace with CONFIG_BASE_FVP >> - Update boards.cfg with option SEMIHOSTING and BASE_FVP >> - Add doc/README.semihosting >> >> Changes in v1: >> - Initial code >> - Remove empty timer_init() function. >> >> arch/arm/include/asm/semihosting.h | 21 +++ >> arch/arm/lib/Makefile | 1 + >> arch/arm/lib/semihosting.c | 235 >> ++++++++++++++++++++++++++++++++++ >> board/armltd/vexpress64/vexpress64.c | 101 ++++++++++++++- >> boards.cfg | 1 + >> doc/README.semihosting | 35 +++++ >> include/configs/vexpress_aemv8a.h | 59 ++++++++- >> 7 files changed, 441 insertions(+), 12 deletions(-) create mode 100644 >> arch/arm/include/asm/semihosting.h >> create mode 100644 arch/arm/lib/semihosting.c create mode 100644 >> doc/README.semihosting >> >> diff --git a/arch/arm/include/asm/semihosting.h >> b/arch/arm/include/asm/semihosting.h >> new file mode 100644 >> index 0000000..74111dc >> --- /dev/null >> +++ b/arch/arm/include/asm/semihosting.h >> @@ -0,0 +1,21 @@ >> +/* >> + * Copyright 2014 Broadcom Corporation >> + * >> + * SPDX-License-Identifier: GPL-2.0+ >> + */ >> + >> +#ifndef __SEMIHOSTING_H__ >> +#define __SEMIHOSTING_H__ >> + >> +/* >> + * ARM semihosting functions for loading images to memory. See the >> +source >> + * code for more information. >> + */ >> +int smh_load(const char *fname, void *memp, int avail, int verbose); >> +int smh_read(int fd, void *memp, int len); int smh_open(const char >> +*fname, char *modestr); int smh_close(int fd); int smh_len_fd(int fd); >> +int smh_len(const char *fname); >> + >> +#endif /* __SEMIHOSTING_H__ */ >> diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index >> 9fc81cd..0ba929d 100644 >> --- a/arch/arm/lib/Makefile >> +++ b/arch/arm/lib/Makefile >> @@ -32,6 +32,7 @@ obj-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o else >> obj-$(CONFIG_SPL_FRAMEWORK) += spl.o >> endif >> +obj-$(CONFIG_SEMIHOSTING) += semihosting.o >> >> obj-y += sections.o >> ifdef CONFIG_ARM64 >> diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c new >> file mode 100644 index 0000000..d603789 >> --- /dev/null >> +++ b/arch/arm/lib/semihosting.c >> @@ -0,0 +1,235 @@ >> +/* >> + * Copyright 2014 Broadcom Corporation >> + * >> + * SPDX-License-Identifier: GPL-2.0+ >> + */ >> + >> +/* >> + * Minimal semihosting implementation for reading files into memory. If >> +more >> + * features like writing files or console output are required they can >> +be >> + * added later. This code has been tested on arm64/aarch64 fastmodel >> only. >> + * An untested placeholder exists for armv7 architectures, but since >> +they >> + * are commonly available in silicon now, fastmodel usage makes less >> +sense >> + * for them. >> + */ >> +#include <common.h> >> +#include <asm/semihosting.h> >> + >> +#define SYSOPEN 0x01 >> +#define SYSCLOSE 0x02 >> +#define SYSREAD 0x06 >> +#define SYSFLEN 0x0C >> + >> +#define MODE_READ 0x0 >> +#define MODE_READBIN 0x1 >> + >> +/* >> + * Call the handler >> + */ >> +static int smh_trap(unsigned int sysnum, void *addr) { >> + register int result asm("r0"); >> +#if defined(CONFIG_ARM64) >> + asm volatile ("hlt #0xf000" : "=r" (result) : "0"(sysnum), >> "r"(addr)); >> +#else >> + /* Note - untested placeholder */ >> + asm volatile ("svc #0x123456" : "=r" (result) : "0"(sysnum), >> +"r"(addr)); #endif >> + return result; >> +} >> + >> +/* >> + * Open, load a file into memory, and close it. Check that the >> +available space >> + * is sufficient to store the entire file. Return the bytes actually >> +read from >> + * the file as seen by the read function. The verbose flag enables some >> +extra >> + * printing of successful read status. >> + */ >> +int smh_load(const char *fname, void *memp, int avail, int verbose) { >> + int ret, fd, len; >> + >> + ret = -1; >> + >> + debug("%s: fname \'%s\', avail %u, memp %p\n", __func__, fname, >> + avail, memp); >> + >> + /* Open the file */ >> + fd = smh_open(fname, "rb"); >> + if (fd == -1) >> + return ret; >> + >> + /* Get the file length */ >> + ret = smh_len_fd(fd); >> + if (ret == -1) { >> + smh_close(fd); >> + return ret; >> + } >> + >> + /* Check that the file will fit in the supplied buffer */ >> + if (ret > avail) { >> + printf("%s: ERROR ret %d, avail %u\n", __func__, ret, >> + avail); >> + smh_close(fd); >> + return ret; >> + } >> + >> + len = ret; >> + >> + /* Read the file into the buffer */ >> + ret = smh_read(fd, memp, len); >> + if (ret == 0) { >> + /* Print successful load information if requested */ >> + if (verbose) { >> + printf("\n%s\n", fname); >> + printf(" 0x%8p dest\n", memp); >> + printf(" 0x%08x size\n", len); >> + printf(" 0x%08x avail\n", avail); >> + } >> + } >> + >> + /* Close the file */ >> + smh_close(fd); >> + >> + return ret; >> +} >> + >> +/* >> + * Read 'len' bytes of file into 'memp'. Returns 0 on success, else >> +failure */ int smh_read(int fd, void *memp, int len) { >> + int ret; >> + struct smh_read_s { >> + int fd; >> + void *memp; >> + int len; >> + } read; >> + >> + debug("%s: fd %d, memp %p, len %d\n", __func__, fd, memp, len); >> + >> + read.fd = fd; >> + read.memp = memp; >> + read.len = len; >> + >> + ret = smh_trap(SYSREAD, &read); >> + if (ret == 0) { >> + return 0; >> + } else { >> + /* >> + * The ARM handler allows for returning partial lengths, >> + * but if this ever happens, it is a bug in the fastmodel >> + * implementation. The Linux fastmodel doesn't show this >> + * issue, and any Windows fastmodel bugs need to be fixed. >> + * So rather than create ugly unmaintainable partial read >> + * loops and such, just fail with an error message. >> + */ >> + printf("%s: ERROR ret %d, fd %d, len %u memp %p\n", >> + __func__, ret, fd, len, memp); >> + } >> + return ret; >> +} >> + >> +/* >> + * Open a file on the host. Mode is "r" or "rb" currently. Returns a >> +file >> + * descriptor or -1 on error. >> + */ >> +int smh_open(const char *fname, char *modestr) { >> + int ret, fd, mode; >> + struct smh_open_s { >> + const char *fname; >> + unsigned int mode; >> + unsigned int len; >> + } open; >> + >> + debug("%s: file \'%s\', mode \'%s\'\n", __func__, fname, modestr); >> + >> + ret = -1; >> + >> + /* Check the file mode */ >> + if (!(strcmp(modestr, "r"))) { >> + mode = MODE_READ; >> + } else if (!(strcmp(modestr, "rb"))) { >> + mode = MODE_READBIN; >> + } else { >> + printf("%s: ERROR mode \'%s\' not supported\n", __func__, >> + modestr); >> + return ret; >> + } >> + >> + open.fname = fname; >> + open.len = strlen(fname); >> + open.mode = mode; >> + >> + /* Open the file on the host */ >> + fd = smh_trap(SYSOPEN, &open); >> + if (fd == -1) >> + printf("%s: ERROR fd %d for file \'%s\'\n", __func__, fd, >> + fname); >> + >> + return fd; >> +} >> + >> +/* >> + * Close the file using the file descriptor */ int smh_close(int fd) { >> + int ret; >> + long fdlong; >> + >> + debug("%s: fd %d\n", __func__, fd); >> + >> + fdlong = (long)fd; >> + ret = smh_trap(SYSCLOSE, &fdlong); >> + if (ret == -1) >> + printf("%s: ERROR fd %d\n", __func__, fd); >> + >> + return ret; >> +} >> + >> +/* >> + * Get the file length from the file descriptor */ int smh_len_fd(int >> +fd) { >> + int ret; >> + long fdlong; >> + >> + debug("%s: fd %d\n", __func__, fd); >> + >> + fdlong = (long)fd; >> + ret = smh_trap(SYSFLEN, &fdlong); >> + if (ret == -1) >> + printf("%s: ERROR ret %d\n", __func__, ret); >> + >> + return ret; >> +} >> + >> +/* >> + * Get the file length from the filename */ int smh_len(const char >> +*fname) { >> + int ret, fd, len; >> + >> + debug("%s: file \'%s\'\n", __func__, fname); >> + >> + /* Open the file */ >> + fd = smh_open(fname, "rb"); >> + if (fd == -1) >> + return fd; >> + >> + /* Get the file length */ >> + len = smh_len_fd(fd); >> + >> + /* Close the file */ >> + ret = smh_close(fd); >> + if (ret == -1) >> + return ret; >> + >> + debug("%s: returning len %d\n", __func__, len); >> + >> + /* Return the file length (or -1 error indication) */ >> + return len; >> +} >> diff --git a/board/armltd/vexpress64/vexpress64.c >> b/board/armltd/vexpress64/vexpress64.c >> index 2ec3bc9..5897318 100644 >> --- a/board/armltd/vexpress64/vexpress64.c >> +++ b/board/armltd/vexpress64/vexpress64.c >> @@ -11,6 +11,7 @@ >> #include <netdev.h> >> #include <asm/io.h> >> #include <linux/compiler.h> >> +#include <asm/semihosting.h> >> >> DECLARE_GLOBAL_DATA_PTR; >> >> @@ -31,11 +32,6 @@ int dram_init(void) >> return 0; >> } >> >> -int timer_init(void) >> -{ >> - return 0; >> -} >> - >> /* >> * Board specific reset that is system reset. >> */ >> @@ -43,6 +39,101 @@ void reset_cpu(ulong addr) { } >> >> +#ifdef CONFIG_BOARD_LATE_INIT >> +int board_late_init(void) >> +{ >> +#ifdef CONFIG_SEMIHOSTING >> + /* >> + * Please refer to doc/README.semihosting for a more complete >> + * description. >> + * >> + * We require that the board include file defines these env >> variables: >> + * - kernel_name >> + * - kernel_addr_r >> + * - initrd_name >> + * - initrd_addr_r >> + * - fdt_name >> + * - fdt_addr_r >> + * >> + * For the "fdt chosen" startup macro, this code will then define: >> + * - initrd_end (based on 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. >> + */ >> + >> + /* Env variable strings */ >> + char *kernel_name = getenv("kernel_name"); >> + char *kernel_addr_str = getenv("kernel_addr_r"); >> + char *initrd_name = getenv("initrd_name"); >> + char *initrd_addr_str = getenv("initrd_addr_r"); >> + char *fdt_name = getenv("fdt_name"); >> + char *fdt_addr_str = getenv("fdt_addr_r"); >> + char initrd_end_str[64]; >> + >> + /* Actual addresses converted from env variables */ >> + void *kernel_addr_r; >> + void *initrd_addr_r; >> + void *fdt_addr_r; >> + >> + /* Actual initrd base and size */ >> + unsigned long initrd_base; >> + unsigned long initrd_size; >> + >> + /* Space available */ >> + int avail; >> + >> + /* Make sure the environment variables needed are set */ >> + if (!(kernel_addr_str && initrd_addr_str && fdt_addr_str)) { >> + printf("%s: Define {kernel/initrd/fdt}_addr_r\n", __func__); >> + return -1; >> + } >> + if (!(kernel_name && initrd_name && fdt_name)) { >> + printf("%s: Define {kernel/initrd/fdt}_name\n", __func__); >> + return -1; >> + } >> + >> + /* Get exact initrd_size */ >> + initrd_size = smh_len(initrd_name); >> + if (initrd_size == -1) { >> + printf("%s: Can't get file size for \'%s\'\n", __func__, >> + initrd_name); >> + return -1; >> + } >> + >> + /* Set initrd_end */ >> + initrd_base = simple_strtoul(initrd_addr_str, NULL, 16); >> + initrd_addr_r = (void *)initrd_base; >> + sprintf(initrd_end_str, "0x%lx", initrd_base + initrd_size - 1); >> + setenv("initrd_end", initrd_end_str); >> + >> + /* Load kernel to memory */ >> + fdt_addr_r = (void *)simple_strtoul(fdt_addr_str, NULL, 16); >> + kernel_addr_r = (void *)simple_strtoul(kernel_addr_str, NULL, 16); >> + >> + /* >> + * The kernel must be lower in memory than fdt and loading the >> + * kernel must not trample the fdt or vice versa. >> + */ >> + avail = fdt_addr_r - kernel_addr_r; >> + if (avail < 0) { >> + printf("%s: fdt must be after kernel\n", __func__); >> + return -1; >> + } >> + smh_load(kernel_name, kernel_addr_r, avail, 1); >> + >> + /* Load fdt to memory */ >> + smh_load(fdt_name, fdt_addr_r, 0x20000, 1); >> + >> + /* Load initrd to memory */ >> + smh_load(initrd_name, initrd_addr_r, initrd_size, 1); >> + >> +#endif /* CONFIG_SEMIHOSTING */ >> + return 0; >> +} >> +#endif /* CONFIG_BOARD_LATE_INIT */ >> + >> /* >> * Board specific ethernet initialization routine. >> */ >> diff --git a/boards.cfg b/boards.cfg >> index 69c8936..d142b10 100644 >> --- a/boards.cfg >> +++ b/boards.cfg >> @@ -44,6 +44,7 @@ >> >> ######################################################################### >> ################################## >> >> Active aarch64 armv8 - armltd >> vexpress64 vexpress_aemv8a >> vexpress_aemv8a:ARM64 >> David Feng <fenghua@phytium.com.cn> >> +Active aarch64 armv8 - armltd >> vexpress64 vexpress_aemv8a_semi >> vexpress_aemv8a:ARM64,SEMIHOSTING,BASE_FVP >> Darwin Rambo <drambo@broadcom.com> >> Active arc arc700 - synopsys - >> axs101 - >> Alexey Brodkin <abrodkin@synopsys.com> >> Active arc arc700 - synopsys <none> >> arcangel4 - >> Alexey Brodkin <abrodkin@synopsys.com> >> Active arc arc700 - synopsys <none> >> arcangel4-be - >> Alexey Brodkin <abrodkin@synopsys.com> >> diff --git a/doc/README.semihosting b/doc/README.semihosting new file >> mode 100644 index 0000000..c999a27 >> --- /dev/null >> +++ b/doc/README.semihosting >> @@ -0,0 +1,35 @@ >> +/* >> + * Copyright 2014 Broadcom Corporation. >> + * >> + * SPDX-License-Identifier: GPL-2.0+ >> + */ >> + >> +Semihosting is ARM's way of having a real or virtual target communicate >> +with a host or host debugger for basic operations such as file I/O, >> +console I/O, etc. Please see >> +http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0471c/Bgb >> jjgij.html for more information. >> + >> +For developing on armv8 virtual fastmodel platforms, semihosting is a >> +valuable tool since it allows access to image/configuration files >> +before eMMC or other NV media are available. >> + >> +For reference, the current example is enabled by setting >> +CONFIG_SEMIHOSTING for the "vexpress_aemv8a" board. >> + >> +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" >> + >> +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. >> diff --git a/include/configs/vexpress_aemv8a.h >> b/include/configs/vexpress_aemv8a.h >> index e851702..96978f5 100644 >> --- a/include/configs/vexpress_aemv8a.h >> +++ b/include/configs/vexpress_aemv8a.h >> @@ -10,6 +10,14 @@ >> >> #define DEBUG >> >> +#ifdef CONFIG_BASE_FVP >> +#ifndef CONFIG_SEMIHOSTING >> +#error CONFIG_BASE_FVP requires CONFIG_SEMIHOSTING #endif #define >> +CONFIG_BOARD_LATE_INIT #define CONFIG_ARMV8_SWITCH_TO_EL1 #endif >> + >> #define CONFIG_REMAKE_ELF >> >> /*#define CONFIG_ARMV8_SWITCH_TO_EL1*/ >> @@ -28,8 +36,14 @@ >> #define CONFIG_BOOTP_VCI_STRING "U-boot.armv8.vexpress_aemv8a" >> >> /* Link Definitions */ >> +#ifdef CONFIG_BASE_FVP >> +/* ATF loads u-boot here for BASE_FVP model */ >> +#define CONFIG_SYS_TEXT_BASE 0x88000000 >> +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + >> 0x03f00000) >> +#else >> #define CONFIG_SYS_TEXT_BASE 0x80000000 >> #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + >> 0x7fff0) >> +#endif >> >> /* Flat Device Tree Definitions */ >> #define CONFIG_OF_LIBFDT >> @@ -37,7 +51,11 @@ >> #define CONFIG_DEFAULT_DEVICE_TREE vexpress64 >> >> /* SMP Spin Table Definitions */ >> +#ifdef CONFIG_BASE_FVP >> +#define CPU_RELEASE_ADDR (CONFIG_SYS_SDRAM_BASE + 0x03f00000) >> +#else >> #define CPU_RELEASE_ADDR (CONFIG_SYS_SDRAM_BASE + 0x7fff0) >> +#endif >> >> /* CS register bases for the original memory map. */ >> #define V2M_PA_CS0 0x00000000 >> @@ -93,8 +111,13 @@ >> #define COUNTER_FREQUENCY (0x1800000) /* 24MHz */ >> >> /* Generic Interrupt Controller Definitions */ >> +#ifdef CONFIG_BASE_FVP >> +#define GICD_BASE (0x2f000000) >> +#define GICC_BASE (0x2c000000) >> +#else >> #define GICD_BASE (0x2C001000) >> #define GICC_BASE (0x2C002000) >> +#endif >> >> #define CONFIG_SYS_MEMTEST_START V2M_BASE >> #define CONFIG_SYS_MEMTEST_END (V2M_BASE + 0x80000000) >> @@ -114,7 +137,6 @@ >> #define CONFIG_CONS_INDEX 0 >> >> #define CONFIG_BAUDRATE 115200 >> -#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } >> #define CONFIG_SYS_SERIAL0 V2M_UART0 >> #define CONFIG_SYS_SERIAL1 V2M_UART1 >> >> @@ -158,17 +180,41 @@ >> #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 >> >> /* Initial environment variables */ >> +#ifdef CONFIG_BASE_FVP >> +#define CONFIG_EXTRA_ENV_SETTINGS \ >> + "kernel_name=uImage\0" \ >> + "kernel_addr_r=0x80000000\0" \ >> + "initrd_name=ramdisk.img\0" \ >> + "initrd_addr_r=0x88000000\0" \ >> + "fdt_name=devtree.dtb\0" \ >> + "fdt_addr_r=0x83000000\0" \ >> + "fdt_high=0xffffffffffffffff\0" \ >> + "initrd_high=0xffffffffffffffff\0" >> + >> +#define CONFIG_BOOTARGS "console=ttyAMA0 earlyprintk=pl011,"\ >> + "0x1c090000 debug user_debug=31 "\ >> + "loglevel=9" >> + >> +#define CONFIG_BOOTCOMMAND "fdt addr $fdt_addr_r; fdt resize; " \ >> + "fdt chosen $initrd_addr_r $initrd_end; " \ >> + "bootm $kernel_addr_r - $fdt_addr_r" >> + >> +#define CONFIG_BOOTDELAY 1 >> + >> +#else >> + >> #define CONFIG_EXTRA_ENV_SETTINGS \ >> - "kernel_addr=0x200000\0" \ >> - "initrd_addr=0xa00000\0" \ >> + "kernel_addr_r=0x200000\0" \ >> + "initrd_addr_r=0xa00000\0" \ >> "initrd_size=0x2000000\0" \ >> - "fdt_addr=0x100000\0" \ >> + "fdt_addr_r=0x100000\0" \ >> "fdt_high=0xa0000000\0" >> >> #define CONFIG_BOOTARGS "console=ttyAMA0 >> root=/dev/ram0" >> -#define CONFIG_BOOTCOMMAND "bootm $kernel_addr " \ >> - "$initrd_addr:$initrd_size $fdt_addr" >> +#define CONFIG_BOOTCOMMAND "bootm $kernel_addr_r " \ >> + "$initrd_addr_r:$initrd_size $fdt_addr_r" >> #define CONFIG_BOOTDELAY -1 >> +#endif >> >> /* Do not preserve environment */ >> #define CONFIG_ENV_IS_NOWHERE 1 >> @@ -180,7 +226,6 @@ >> #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ >> sizeof(CONFIG_SYS_PROMPT) + 16) >> #define CONFIG_SYS_HUSH_PARSER >> -#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " >> #define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE >> #define CONFIG_SYS_LONGHELP >> #define CONFIG_CMDLINE_EDITING 1 >> -- >> 1.7.9.5 >> >> >
diff --git a/arch/arm/include/asm/semihosting.h b/arch/arm/include/asm/semihosting.h new file mode 100644 index 0000000..74111dc --- /dev/null +++ b/arch/arm/include/asm/semihosting.h @@ -0,0 +1,21 @@ +/* + * Copyright 2014 Broadcom Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __SEMIHOSTING_H__ +#define __SEMIHOSTING_H__ + +/* + * ARM semihosting functions for loading images to memory. See the source + * code for more information. + */ +int smh_load(const char *fname, void *memp, int avail, int verbose); +int smh_read(int fd, void *memp, int len); +int smh_open(const char *fname, char *modestr); +int smh_close(int fd); +int smh_len_fd(int fd); +int smh_len(const char *fname); + +#endif /* __SEMIHOSTING_H__ */ diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 9fc81cd..0ba929d 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o else obj-$(CONFIG_SPL_FRAMEWORK) += spl.o endif +obj-$(CONFIG_SEMIHOSTING) += semihosting.o obj-y += sections.o ifdef CONFIG_ARM64 diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c new file mode 100644 index 0000000..d603789 --- /dev/null +++ b/arch/arm/lib/semihosting.c @@ -0,0 +1,235 @@ +/* + * Copyright 2014 Broadcom Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * Minimal semihosting implementation for reading files into memory. If more + * features like writing files or console output are required they can be + * added later. This code has been tested on arm64/aarch64 fastmodel only. + * An untested placeholder exists for armv7 architectures, but since they + * are commonly available in silicon now, fastmodel usage makes less sense + * for them. + */ +#include <common.h> +#include <asm/semihosting.h> + +#define SYSOPEN 0x01 +#define SYSCLOSE 0x02 +#define SYSREAD 0x06 +#define SYSFLEN 0x0C + +#define MODE_READ 0x0 +#define MODE_READBIN 0x1 + +/* + * Call the handler + */ +static int smh_trap(unsigned int sysnum, void *addr) +{ + register int result asm("r0"); +#if defined(CONFIG_ARM64) + asm volatile ("hlt #0xf000" : "=r" (result) : "0"(sysnum), "r"(addr)); +#else + /* Note - untested placeholder */ + asm volatile ("svc #0x123456" : "=r" (result) : "0"(sysnum), "r"(addr)); +#endif + return result; +} + +/* + * Open, load a file into memory, and close it. Check that the available space + * is sufficient to store the entire file. Return the bytes actually read from + * the file as seen by the read function. The verbose flag enables some extra + * printing of successful read status. + */ +int smh_load(const char *fname, void *memp, int avail, int verbose) +{ + int ret, fd, len; + + ret = -1; + + debug("%s: fname \'%s\', avail %u, memp %p\n", __func__, fname, + avail, memp); + + /* Open the file */ + fd = smh_open(fname, "rb"); + if (fd == -1) + return ret; + + /* Get the file length */ + ret = smh_len_fd(fd); + if (ret == -1) { + smh_close(fd); + return ret; + } + + /* Check that the file will fit in the supplied buffer */ + if (ret > avail) { + printf("%s: ERROR ret %d, avail %u\n", __func__, ret, + avail); + smh_close(fd); + return ret; + } + + len = ret; + + /* Read the file into the buffer */ + ret = smh_read(fd, memp, len); + if (ret == 0) { + /* Print successful load information if requested */ + if (verbose) { + printf("\n%s\n", fname); + printf(" 0x%8p dest\n", memp); + printf(" 0x%08x size\n", len); + printf(" 0x%08x avail\n", avail); + } + } + + /* Close the file */ + smh_close(fd); + + return ret; +} + +/* + * Read 'len' bytes of file into 'memp'. Returns 0 on success, else failure + */ +int smh_read(int fd, void *memp, int len) +{ + int ret; + struct smh_read_s { + int fd; + void *memp; + int len; + } read; + + debug("%s: fd %d, memp %p, len %d\n", __func__, fd, memp, len); + + read.fd = fd; + read.memp = memp; + read.len = len; + + ret = smh_trap(SYSREAD, &read); + if (ret == 0) { + return 0; + } else { + /* + * The ARM handler allows for returning partial lengths, + * but if this ever happens, it is a bug in the fastmodel + * implementation. The Linux fastmodel doesn't show this + * issue, and any Windows fastmodel bugs need to be fixed. + * So rather than create ugly unmaintainable partial read + * loops and such, just fail with an error message. + */ + printf("%s: ERROR ret %d, fd %d, len %u memp %p\n", + __func__, ret, fd, len, memp); + } + return ret; +} + +/* + * Open a file on the host. Mode is "r" or "rb" currently. Returns a file + * descriptor or -1 on error. + */ +int smh_open(const char *fname, char *modestr) +{ + int ret, fd, mode; + struct smh_open_s { + const char *fname; + unsigned int mode; + unsigned int len; + } open; + + debug("%s: file \'%s\', mode \'%s\'\n", __func__, fname, modestr); + + ret = -1; + + /* Check the file mode */ + if (!(strcmp(modestr, "r"))) { + mode = MODE_READ; + } else if (!(strcmp(modestr, "rb"))) { + mode = MODE_READBIN; + } else { + printf("%s: ERROR mode \'%s\' not supported\n", __func__, + modestr); + return ret; + } + + open.fname = fname; + open.len = strlen(fname); + open.mode = mode; + + /* Open the file on the host */ + fd = smh_trap(SYSOPEN, &open); + if (fd == -1) + printf("%s: ERROR fd %d for file \'%s\'\n", __func__, fd, + fname); + + return fd; +} + +/* + * Close the file using the file descriptor + */ +int smh_close(int fd) +{ + int ret; + long fdlong; + + debug("%s: fd %d\n", __func__, fd); + + fdlong = (long)fd; + ret = smh_trap(SYSCLOSE, &fdlong); + if (ret == -1) + printf("%s: ERROR fd %d\n", __func__, fd); + + return ret; +} + +/* + * Get the file length from the file descriptor + */ +int smh_len_fd(int fd) +{ + int ret; + long fdlong; + + debug("%s: fd %d\n", __func__, fd); + + fdlong = (long)fd; + ret = smh_trap(SYSFLEN, &fdlong); + if (ret == -1) + printf("%s: ERROR ret %d\n", __func__, ret); + + return ret; +} + +/* + * Get the file length from the filename + */ +int smh_len(const char *fname) +{ + int ret, fd, len; + + debug("%s: file \'%s\'\n", __func__, fname); + + /* Open the file */ + fd = smh_open(fname, "rb"); + if (fd == -1) + return fd; + + /* Get the file length */ + len = smh_len_fd(fd); + + /* Close the file */ + ret = smh_close(fd); + if (ret == -1) + return ret; + + debug("%s: returning len %d\n", __func__, len); + + /* Return the file length (or -1 error indication) */ + return len; +} diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c index 2ec3bc9..5897318 100644 --- a/board/armltd/vexpress64/vexpress64.c +++ b/board/armltd/vexpress64/vexpress64.c @@ -11,6 +11,7 @@ #include <netdev.h> #include <asm/io.h> #include <linux/compiler.h> +#include <asm/semihosting.h> DECLARE_GLOBAL_DATA_PTR; @@ -31,11 +32,6 @@ int dram_init(void) return 0; } -int timer_init(void) -{ - return 0; -} - /* * Board specific reset that is system reset. */ @@ -43,6 +39,101 @@ void reset_cpu(ulong addr) { } +#ifdef CONFIG_BOARD_LATE_INIT +int board_late_init(void) +{ +#ifdef CONFIG_SEMIHOSTING + /* + * Please refer to doc/README.semihosting for a more complete + * description. + * + * We require that the board include file defines these env variables: + * - kernel_name + * - kernel_addr_r + * - initrd_name + * - initrd_addr_r + * - fdt_name + * - fdt_addr_r + * + * For the "fdt chosen" startup macro, this code will then define: + * - initrd_end (based on 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. + */ + + /* Env variable strings */ + char *kernel_name = getenv("kernel_name"); + char *kernel_addr_str = getenv("kernel_addr_r"); + char *initrd_name = getenv("initrd_name"); + char *initrd_addr_str = getenv("initrd_addr_r"); + char *fdt_name = getenv("fdt_name"); + char *fdt_addr_str = getenv("fdt_addr_r"); + char initrd_end_str[64]; + + /* Actual addresses converted from env variables */ + void *kernel_addr_r; + void *initrd_addr_r; + void *fdt_addr_r; + + /* Actual initrd base and size */ + unsigned long initrd_base; + unsigned long initrd_size; + + /* Space available */ + int avail; + + /* Make sure the environment variables needed are set */ + if (!(kernel_addr_str && initrd_addr_str && fdt_addr_str)) { + printf("%s: Define {kernel/initrd/fdt}_addr_r\n", __func__); + return -1; + } + if (!(kernel_name && initrd_name && fdt_name)) { + printf("%s: Define {kernel/initrd/fdt}_name\n", __func__); + return -1; + } + + /* Get exact initrd_size */ + initrd_size = smh_len(initrd_name); + if (initrd_size == -1) { + printf("%s: Can't get file size for \'%s\'\n", __func__, + initrd_name); + return -1; + } + + /* Set initrd_end */ + initrd_base = simple_strtoul(initrd_addr_str, NULL, 16); + initrd_addr_r = (void *)initrd_base; + sprintf(initrd_end_str, "0x%lx", initrd_base + initrd_size - 1); + setenv("initrd_end", initrd_end_str); + + /* Load kernel to memory */ + fdt_addr_r = (void *)simple_strtoul(fdt_addr_str, NULL, 16); + kernel_addr_r = (void *)simple_strtoul(kernel_addr_str, NULL, 16); + + /* + * The kernel must be lower in memory than fdt and loading the + * kernel must not trample the fdt or vice versa. + */ + avail = fdt_addr_r - kernel_addr_r; + if (avail < 0) { + printf("%s: fdt must be after kernel\n", __func__); + return -1; + } + smh_load(kernel_name, kernel_addr_r, avail, 1); + + /* Load fdt to memory */ + smh_load(fdt_name, fdt_addr_r, 0x20000, 1); + + /* Load initrd to memory */ + smh_load(initrd_name, initrd_addr_r, initrd_size, 1); + +#endif /* CONFIG_SEMIHOSTING */ + return 0; +} +#endif /* CONFIG_BOARD_LATE_INIT */ + /* * Board specific ethernet initialization routine. */ diff --git a/boards.cfg b/boards.cfg index 69c8936..d142b10 100644 --- a/boards.cfg +++ b/boards.cfg @@ -44,6 +44,7 @@ ########################################################################################################### Active aarch64 armv8 - armltd vexpress64 vexpress_aemv8a vexpress_aemv8a:ARM64 David Feng <fenghua@phytium.com.cn> +Active aarch64 armv8 - armltd vexpress64 vexpress_aemv8a_semi vexpress_aemv8a:ARM64,SEMIHOSTING,BASE_FVP Darwin Rambo <drambo@broadcom.com> Active arc arc700 - synopsys - axs101 - Alexey Brodkin <abrodkin@synopsys.com> Active arc arc700 - synopsys <none> arcangel4 - Alexey Brodkin <abrodkin@synopsys.com> Active arc arc700 - synopsys <none> arcangel4-be - Alexey Brodkin <abrodkin@synopsys.com> diff --git a/doc/README.semihosting b/doc/README.semihosting new file mode 100644 index 0000000..c999a27 --- /dev/null +++ b/doc/README.semihosting @@ -0,0 +1,35 @@ +/* + * Copyright 2014 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +Semihosting is ARM's way of having a real or virtual target communicate +with a host or host debugger for basic operations such as file I/O, +console I/O, etc. Please see +http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0471c/Bgbjjgij.html for more information. + +For developing on armv8 virtual fastmodel platforms, semihosting is a +valuable tool since it allows access to image/configuration files before +eMMC or other NV media are available. + +For reference, the current example is enabled by setting CONFIG_SEMIHOSTING +for the "vexpress_aemv8a" board. + +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" + +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. diff --git a/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8a.h index e851702..96978f5 100644 --- a/include/configs/vexpress_aemv8a.h +++ b/include/configs/vexpress_aemv8a.h @@ -10,6 +10,14 @@ #define DEBUG +#ifdef CONFIG_BASE_FVP +#ifndef CONFIG_SEMIHOSTING +#error CONFIG_BASE_FVP requires CONFIG_SEMIHOSTING +#endif +#define CONFIG_BOARD_LATE_INIT +#define CONFIG_ARMV8_SWITCH_TO_EL1 +#endif + #define CONFIG_REMAKE_ELF /*#define CONFIG_ARMV8_SWITCH_TO_EL1*/ @@ -28,8 +36,14 @@ #define CONFIG_BOOTP_VCI_STRING "U-boot.armv8.vexpress_aemv8a" /* Link Definitions */ +#ifdef CONFIG_BASE_FVP +/* ATF loads u-boot here for BASE_FVP model */ +#define CONFIG_SYS_TEXT_BASE 0x88000000 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x03f00000) +#else #define CONFIG_SYS_TEXT_BASE 0x80000000 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x7fff0) +#endif /* Flat Device Tree Definitions */ #define CONFIG_OF_LIBFDT @@ -37,7 +51,11 @@ #define CONFIG_DEFAULT_DEVICE_TREE vexpress64 /* SMP Spin Table Definitions */ +#ifdef CONFIG_BASE_FVP +#define CPU_RELEASE_ADDR (CONFIG_SYS_SDRAM_BASE + 0x03f00000) +#else #define CPU_RELEASE_ADDR (CONFIG_SYS_SDRAM_BASE + 0x7fff0) +#endif /* CS register bases for the original memory map. */ #define V2M_PA_CS0 0x00000000 @@ -93,8 +111,13 @@ #define COUNTER_FREQUENCY (0x1800000) /* 24MHz */ /* Generic Interrupt Controller Definitions */ +#ifdef CONFIG_BASE_FVP +#define GICD_BASE (0x2f000000) +#define GICC_BASE (0x2c000000) +#else #define GICD_BASE (0x2C001000) #define GICC_BASE (0x2C002000) +#endif #define CONFIG_SYS_MEMTEST_START V2M_BASE #define CONFIG_SYS_MEMTEST_END (V2M_BASE + 0x80000000) @@ -114,7 +137,6 @@ #define CONFIG_CONS_INDEX 0 #define CONFIG_BAUDRATE 115200 -#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } #define CONFIG_SYS_SERIAL0 V2M_UART0 #define CONFIG_SYS_SERIAL1 V2M_UART1 @@ -158,17 +180,41 @@ #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 /* Initial environment variables */ +#ifdef CONFIG_BASE_FVP +#define CONFIG_EXTRA_ENV_SETTINGS \ + "kernel_name=uImage\0" \ + "kernel_addr_r=0x80000000\0" \ + "initrd_name=ramdisk.img\0" \ + "initrd_addr_r=0x88000000\0" \ + "fdt_name=devtree.dtb\0" \ + "fdt_addr_r=0x83000000\0" \ + "fdt_high=0xffffffffffffffff\0" \ + "initrd_high=0xffffffffffffffff\0" + +#define CONFIG_BOOTARGS "console=ttyAMA0 earlyprintk=pl011,"\ + "0x1c090000 debug user_debug=31 "\ + "loglevel=9" + +#define CONFIG_BOOTCOMMAND "fdt addr $fdt_addr_r; fdt resize; " \ + "fdt chosen $initrd_addr_r $initrd_end; " \ + "bootm $kernel_addr_r - $fdt_addr_r" + +#define CONFIG_BOOTDELAY 1 + +#else + #define CONFIG_EXTRA_ENV_SETTINGS \ - "kernel_addr=0x200000\0" \ - "initrd_addr=0xa00000\0" \ + "kernel_addr_r=0x200000\0" \ + "initrd_addr_r=0xa00000\0" \ "initrd_size=0x2000000\0" \ - "fdt_addr=0x100000\0" \ + "fdt_addr_r=0x100000\0" \ "fdt_high=0xa0000000\0" #define CONFIG_BOOTARGS "console=ttyAMA0 root=/dev/ram0" -#define CONFIG_BOOTCOMMAND "bootm $kernel_addr " \ - "$initrd_addr:$initrd_size $fdt_addr" +#define CONFIG_BOOTCOMMAND "bootm $kernel_addr_r " \ + "$initrd_addr_r:$initrd_size $fdt_addr_r" #define CONFIG_BOOTDELAY -1 +#endif /* Do not preserve environment */ #define CONFIG_ENV_IS_NOWHERE 1 @@ -180,7 +226,6 @@ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ sizeof(CONFIG_SYS_PROMPT) + 16) #define CONFIG_SYS_HUSH_PARSER -#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " #define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE #define CONFIG_SYS_LONGHELP #define CONFIG_CMDLINE_EDITING 1
The reason for this change is to be able to use the ARM Trusted Firmware (ATF) to load the various ATF images, plus u-boot, which can then load the kernel/ramdisk/dtb with calls to an external host from a standard fastmodel armv8 board file using semihosting, and then launch the kernel without a bootwrapper. This gives us a more realistic boot sequence. There are two main ARM virtual Fixed Virtual Platform (FVP) models, Versatile Express (VE) FVP and BASE FVP (See http://www.arm.com/products/tools/models/fast-models/foundation-model.php) The initial vexpress64 u-boot board created here runs on the VE virtual platform using the license-free Foundation_v8 simulator. Fortunately, the Foundation_v8 simulator also supports the BASE_FVP model which companies can purchase licenses for and contain much more functionality. So we can, in u-boot, run either model by either using the VE FVP (default), or turning on CONFIG_BASE_FVP for the more full featured model. Rather than create a new armv8 board similar to armltd/vexpress64, add semihosting calls to the existing one, enabled with CONFIG_SEMIHOSTING and CONFIG_BASE_FVP both set. Also reuse the existing board config file 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. Support for armv7 in fastmodel is less useful due to the wide range of available silicon and the lack of a free armv7 fastmodel, so this change contains an untested armv7 placeholder for the service trap opcode. 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. Signed-off-by: Darwin Rambo <drambo@broadcom.com> --- Changes in v3: - minor format fixup in board file Changes in v2: - use kernel_addr_r, fdt_addr_r, initrd_addr_r convention. - Use env variables for kernel/fdt/initrd file names. - Add CONFIG_BASE_FVP to differentiate VE and BASE FVP models. - CONFIG_SEMIHOSTING only refers to bringing in semihosting code now. - Remove unnecessary CONFIG_SYS_BAUDRATE_TABLE, CONFIG_SYS_PROMPT_HUSH_PS2 - Remove vexpress_aemv8a_semi.h and replace with CONFIG_BASE_FVP - Update boards.cfg with option SEMIHOSTING and BASE_FVP - Add doc/README.semihosting Changes in v1: - Initial code - Remove empty timer_init() function. arch/arm/include/asm/semihosting.h | 21 +++ arch/arm/lib/Makefile | 1 + arch/arm/lib/semihosting.c | 235 ++++++++++++++++++++++++++++++++++ board/armltd/vexpress64/vexpress64.c | 101 ++++++++++++++- boards.cfg | 1 + doc/README.semihosting | 35 +++++ include/configs/vexpress_aemv8a.h | 59 ++++++++- 7 files changed, 441 insertions(+), 12 deletions(-) create mode 100644 arch/arm/include/asm/semihosting.h create mode 100644 arch/arm/lib/semihosting.c create mode 100644 doc/README.semihosting