diff mbox

[v4] arm: Add support for semihosting for armv8 fastmodel targets.

Message ID 1400888288-30570-1-git-send-email-drambo@broadcom.com
State New
Headers show

Commit Message

Darwin Rambo May 23, 2014, 11:38 p.m. UTC
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>
Cc: trini@ti.com
Cc: fenghua@phytium.com.cn
Cc: bhupesh.sharma@freescale.com

---

Changes in v4:
- refreshed patch and retested
- fix boards.cfg conflict
- fix GICV3 conflict
- minor documentation cleanup - semihosting.c, README.semihosting
- change maintainer of semihosting target
- tested with vexpress_aemv8a_semi target (BASE_FVP) against
  e75e73dd5f280b91f5bfc0a76a0fd09b6eba1c66 (May 16, 2014)

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           |  233 ++++++++++++++++++++++++++++++++++
 board/armltd/vexpress64/vexpress64.c |  101 ++++++++++++++-
 boards.cfg                           |    1 +
 doc/README.semihosting               |   35 +++++
 include/configs/vexpress_aemv8a.h    |   63 ++++++++-
 7 files changed, 443 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

Comments

Albert ARIBAUD June 9, 2014, 9 a.m. UTC | #1
Hi Darwin,

On Fri, 23 May 2014 16:38:08 -0700, Darwin Rambo <drambo@broadcom.com>
wrote:

> 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>
> Cc: trini@ti.com
> Cc: fenghua@phytium.com.cn
> Cc: bhupesh.sharma@freescale.com
> 
> ---

I am basically ok with this patch, except for the very long commit
message. I would prefer it to be shorter and more synthetic and just
state in a few paragraphs what is fixed or improved, and that the rest
of it be moved after the commit message boundary above, or if it should
be kept for future reference, added or put in a README.* file under
doc/.

Amicalement,
diff mbox

Patch

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 585f1f7..1ef2400 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..cb5dc26
--- /dev/null
+++ b/arch/arm/lib/semihosting.c
@@ -0,0 +1,233 @@ 
+/*
+ * 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 in practice this never happens so rather than create
+		 * hard to maintain 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 440c312..16b9e79 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                                                                                        Steve Rae <srae@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..a37feb1
--- /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 target vexpress_aemv8a_semi enables
+CONFIG_SEMIHOSTING and CONFIG_BASE_FVP 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 dff6adc..1905d13 100644
--- a/include/configs/vexpress_aemv8a.h
+++ b/include/configs/vexpress_aemv8a.h
@@ -10,9 +10,20 @@ 
 
 #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
 
+#ifndef CONFIG_BASE_FVP
+/* Base FVP not using GICv3 yet */
 #define CONFIG_GICV3
+#endif
 
 /*#define CONFIG_ARMV8_SWITCH_TO_EL1*/
 
@@ -30,8 +41,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
@@ -39,7 +56,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
@@ -99,9 +120,15 @@ 
 #define GICD_BASE			(0x2f000000)
 #define GICR_BASE			(0x2f100000)
 #else
+
+#ifdef CONFIG_BASE_FVP
+#define GICD_BASE			(0x2f000000)
+#define GICC_BASE			(0x2c000000)
+#else
 #define GICD_BASE			(0x2C001000)
 #define GICC_BASE			(0x2C002000)
 #endif
+#endif
 
 #define CONFIG_SYS_MEMTEST_START	V2M_BASE
 #define CONFIG_SYS_MEMTEST_END		(V2M_BASE + 0x80000000)
@@ -121,7 +148,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
 
@@ -165,17 +191,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
@@ -187,7 +237,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