sandbox: image: Add support for booting images in sandbox

Much of the image code uses addresses as ulongs and pointers interchangeably,
casting between the two forms as needed.

This doesn't work with sandbox, which has a U-Boot RAM buffer which is
separate from the host machine's memory.

Adjust the cost so that translating from a U-Boot address to a pointer uses
map_sysmem(). This allows bootm to work correctly on sandbox.

Note that there are no exhaustive tests for this code on sandbox, so it is
possible that some dark corners remain.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Marek Vasut <marex@denx.de> (v1)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index aa717bf..b9b2979 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -36,6 +36,7 @@
 #include <lmb.h>
 #include <linux/ctype.h>
 #include <asm/byteorder.h>
+#include <asm/io.h>
 #include <linux/compiler.h>
 
 #if defined(CONFIG_CMD_USB)
@@ -97,7 +98,7 @@
 static int fit_check_kernel(const void *fit, int os_noffset, int verify);
 #endif
 
-static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
+static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
 				char * const argv[], bootm_headers_t *images,
 				ulong *os_data, ulong *os_len);
 
@@ -203,8 +204,8 @@
 
 static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	void		*os_hdr;
-	int		ret;
+	const void *os_hdr;
+	int ret;
 
 	memset((void *)&images, 0, sizeof(images));
 	images.verify = getenv_yesno("verify");
@@ -855,14 +856,15 @@
  *     pointer to image header if valid image was found, plus kernel start
  *     address and length, otherwise NULL
  */
-static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
+static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
 		char * const argv[], bootm_headers_t *images, ulong *os_data,
 		ulong *os_len)
 {
 	image_header_t	*hdr;
 	ulong		img_addr;
+	const void *buf;
 #if defined(CONFIG_FIT)
-	void		*fit_hdr;
+	const void	*fit_hdr;
 	const char	*fit_uname_config = NULL;
 	const char	*fit_uname_kernel = NULL;
 	const void	*data;
@@ -898,7 +900,8 @@
 
 	/* check image type, for FIT images get FIT kernel node */
 	*os_data = *os_len = 0;
-	switch (genimg_get_format((void *)img_addr)) {
+	buf = map_sysmem(img_addr, 0);
+	switch (genimg_get_format(buf)) {
 	case IMAGE_FORMAT_LEGACY:
 		printf("## Booting kernel from Legacy Image at %08lx ...\n",
 				img_addr);
@@ -943,7 +946,7 @@
 		break;
 #if defined(CONFIG_FIT)
 	case IMAGE_FORMAT_FIT:
-		fit_hdr = (void *)img_addr;
+		fit_hdr = buf;
 		printf("## Booting kernel from FIT Image at %08lx ...\n",
 				img_addr);
 
@@ -1020,7 +1023,7 @@
 
 		*os_len = len;
 		*os_data = (ulong)data;
-		images->fit_hdr_os = fit_hdr;
+		images->fit_hdr_os = (void *)fit_hdr;
 		images->fit_uname_os = fit_uname_kernel;
 		images->fit_noffset_os = os_noffset;
 		break;
@@ -1034,7 +1037,7 @@
 	debug("   kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
 			*os_data, *os_len, *os_len);
 
-	return (void *)img_addr;
+	return buf;
 }
 
 #ifdef CONFIG_SYS_LONGHELP
diff --git a/common/image.c b/common/image.c
index 7412a0e..564ed90 100644
--- a/common/image.c
+++ b/common/image.c
@@ -51,6 +51,7 @@
 
 #include <u-boot/md5.h>
 #include <sha1.h>
+#include <asm/io.h>
 
 #ifdef CONFIG_CMD_BDI
 extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
@@ -90,6 +91,7 @@
 	{	IH_ARCH_AVR32,		"avr32",	"AVR32",	},
 	{	IH_ARCH_NDS32,		"nds32",	"NDS32",	},
 	{	IH_ARCH_OPENRISC,	"or1k",		"OpenRISC 1000",},
+	{	IH_ARCH_SANDBOX,	"sandbox",	"Sandbox",	},
 	{	-1,			"",		"",		},
 };
 
@@ -661,7 +663,7 @@
  * returns:
  *     image format type or IMAGE_FORMAT_INVALID if no image is present
  */
-int genimg_get_format(void *img_addr)
+int genimg_get_format(const void *img_addr)
 {
 	ulong format = IMAGE_FORMAT_INVALID;
 	const image_header_t *hdr;
@@ -701,6 +703,8 @@
 	ulong h_size, d_size;
 
 	if (addr_dataflash(img_addr)) {
+		void *buf;
+
 		/* ger RAM address */
 		ram_addr = CONFIG_SYS_LOAD_ADDR;
 
@@ -715,20 +719,20 @@
 		debug("   Reading image header from dataflash address "
 			"%08lx to RAM address %08lx\n", img_addr, ram_addr);
 
-		read_dataflash(img_addr, h_size, (char *)ram_addr);
+		buf = map_sysmem(ram_addr, 0);
+		read_dataflash(img_addr, h_size, buf);
 
 		/* get data size */
-		switch (genimg_get_format((void *)ram_addr)) {
+		switch (genimg_get_format(buf)) {
 		case IMAGE_FORMAT_LEGACY:
-			d_size = image_get_data_size(
-					(const image_header_t *)ram_addr);
+			d_size = image_get_data_size(buf);
 			debug("   Legacy format image found at 0x%08lx, "
 					"size 0x%08lx\n",
 					ram_addr, d_size);
 			break;
 #if defined(CONFIG_FIT)
 		case IMAGE_FORMAT_FIT:
-			d_size = fit_get_size((const void *)ram_addr) - h_size;
+			d_size = fit_get_size(buf) - h_size;
 			debug("   FIT/FDT format image found at 0x%08lx, "
 					"size 0x%08lx\n",
 					ram_addr, d_size);
@@ -746,7 +750,7 @@
 			ram_addr + h_size);
 
 		read_dataflash(img_addr + h_size, d_size,
-				(char *)(ram_addr + h_size));
+				(char *)(buf + h_size));
 
 	}
 #endif /* CONFIG_HAS_DATAFLASH */
@@ -802,6 +806,7 @@
 	ulong rd_addr, rd_load;
 	ulong rd_data, rd_len;
 	const image_header_t *rd_hdr;
+	void *buf;
 #ifdef CONFIG_SUPPORT_RAW_INITRD
 	char *end;
 #endif
@@ -863,7 +868,7 @@
 			/* use FIT configuration provided in first bootm
 			 * command argument
 			 */
-			rd_addr = (ulong)images->fit_hdr_os;
+			rd_addr = map_to_sysmem(images->fit_hdr_os);
 			fit_uname_config = images->fit_uname_cfg;
 			debug("*  ramdisk: using config '%s' from image "
 					"at 0x%08lx\n",
@@ -873,7 +878,7 @@
 			 * Check whether configuration has ramdisk defined,
 			 * if not, don't try to use it, quit silently.
 			 */
-			fit_hdr = (void *)rd_addr;
+			fit_hdr = images->fit_hdr_os;
 			cfg_noffset = fit_conf_get_node(fit_hdr,
 							fit_uname_config);
 			if (cfg_noffset < 0) {
@@ -898,7 +903,8 @@
 		 * address provided in the second bootm argument
 		 * check image type, for FIT images get FIT node.
 		 */
-		switch (genimg_get_format((void *)rd_addr)) {
+		buf = map_sysmem(rd_addr, 0);
+		switch (genimg_get_format(buf)) {
 		case IMAGE_FORMAT_LEGACY:
 			printf("## Loading init Ramdisk from Legacy "
 					"Image at %08lx ...\n", rd_addr);
@@ -916,7 +922,7 @@
 			break;
 #if defined(CONFIG_FIT)
 		case IMAGE_FORMAT_FIT:
-			fit_hdr = (void *)rd_addr;
+			fit_hdr = buf;
 			printf("## Loading init Ramdisk from FIT "
 					"Image at %08lx ...\n", rd_addr);
 
@@ -1159,7 +1165,7 @@
 
 static const image_header_t *image_get_fdt(ulong fdt_addr)
 {
-	const image_header_t *fdt_hdr = (const image_header_t *)fdt_addr;
+	const image_header_t *fdt_hdr = map_sysmem(fdt_addr, 0);
 
 	image_print_contents(fdt_hdr);
 
@@ -1396,6 +1402,7 @@
 	char		*fdt_blob = NULL;
 	ulong		image_start, image_data, image_end;
 	ulong		load_start, load_end;
+	void		*buf;
 #if defined(CONFIG_FIT)
 	void		*fit_hdr;
 	const char	*fit_uname_config = NULL;
@@ -1449,7 +1456,7 @@
 			/* use FIT configuration provided in first bootm
 			 * command argument
 			 */
-			fdt_addr = (ulong)images->fit_hdr_os;
+			fdt_addr = map_to_sysmem(images->fit_hdr_os);
 			fit_uname_config = images->fit_uname_cfg;
 			debug("*  fdt: using config '%s' from image "
 					"at 0x%08lx\n",
@@ -1459,7 +1466,7 @@
 			 * Check whether configuration has FDT blob defined,
 			 * if not quit silently.
 			 */
-			fit_hdr = (void *)fdt_addr;
+			fit_hdr = images->fit_hdr_os;
 			cfg_noffset = fit_conf_get_node(fit_hdr,
 					fit_uname_config);
 			if (cfg_noffset < 0) {
@@ -1487,7 +1494,8 @@
 		 * address provided in the second bootm argument
 		 * check image type, for FIT images get a FIT node.
 		 */
-		switch (genimg_get_format((void *)fdt_addr)) {
+		buf = map_sysmem(fdt_addr, 0);
+		switch (genimg_get_format(buf)) {
 		case IMAGE_FORMAT_LEGACY:
 			/* verify fdt_addr points to a valid image header */
 			printf("## Flattened Device Tree from Legacy Image "
@@ -1536,11 +1544,11 @@
 			 */
 #if defined(CONFIG_FIT)
 			/* check FDT blob vs FIT blob */
-			if (fit_check_format((const void *)fdt_addr)) {
+			if (fit_check_format(buf)) {
 				/*
 				 * FIT image
 				 */
-				fit_hdr = (void *)fdt_addr;
+				fit_hdr = buf;
 				printf("## Flattened Device Tree from FIT "
 						"Image at %08lx\n",
 						fdt_addr);
@@ -1646,10 +1654,10 @@
 				/*
 				 * FDT blob
 				 */
-				fdt_blob = (char *)fdt_addr;
+				fdt_blob = buf;
 				debug("*  fdt: raw FDT blob\n");
-				printf("## Flattened Device Tree blob at "
-					"%08lx\n", (long)fdt_blob);
+				printf("## Flattened Device Tree blob at %08lx\n",
+				       (long)fdt_addr);
 			}
 			break;
 		default:
diff --git a/include/image.h b/include/image.h
index aa93d9e..df020ff 100644
--- a/include/image.h
+++ b/include/image.h
@@ -352,7 +352,7 @@
 #define IMAGE_FORMAT_LEGACY	0x01	/* legacy image_header based format */
 #define IMAGE_FORMAT_FIT	0x02	/* new, libfdt based format */
 
-int genimg_get_format(void *img_addr);
+int genimg_get_format(const void *img_addr);
 int genimg_has_config(bootm_headers_t *images);
 ulong genimg_get_image(ulong img_addr);