pxe: Ensure all memory access is to mapped memory

Properly map memory through map_sysmem so that pxe can be used from the
sandbox.

Tested in sandbox as well as on jetson-tk1, odroid-xu3, snow as peach-pi
boards

Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
Acked-by: Simon Glass <sjg@chromium.org>
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c
index 5cde5b6..4cbb2b1 100644
--- a/common/cmd_pxe.c
+++ b/common/cmd_pxe.c
@@ -14,6 +14,7 @@
 #include <errno.h>
 #include <linux/list.h>
 #include <fs.h>
+#include <asm/io.h>
 
 #include "menu.h"
 #include "cli.h"
@@ -189,11 +190,12 @@
  *
  * Returns 1 for success, or < 0 on error.
  */
-static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
+static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path,
+	unsigned long file_addr)
 {
 	size_t path_len;
 	char relfile[MAX_TFTP_PATH_LEN+1];
-	char addr_buf[10];
+	char addr_buf[18];
 	int err;
 
 	err = get_bootfile_path(file_path, relfile, sizeof(relfile));
@@ -216,7 +218,7 @@
 
 	printf("Retrieving file: %s\n", relfile);
 
-	sprintf(addr_buf, "%p", file_addr);
+	sprintf(addr_buf, "%lx", file_addr);
 
 	return do_getfile(cmdtp, relfile, addr_buf);
 }
@@ -228,11 +230,13 @@
  *
  * Returns 1 on success, or < 0 for error.
  */
-static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
+static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path,
+	unsigned long file_addr)
 {
 	unsigned long config_file_size;
 	char *tftp_filesize;
 	int err;
+	char *buf;
 
 	err = get_relfile(cmdtp, file_path, file_addr);
 
@@ -251,7 +255,9 @@
 	if (strict_strtoul(tftp_filesize, 16, &config_file_size) < 0)
 		return -EINVAL;
 
-	*(char *)(file_addr + config_file_size) = '\0';
+	buf = map_sysmem(file_addr + config_file_size, 1);
+	*buf = '\0';
+	unmap_sysmem(buf);
 
 	return 1;
 }
@@ -267,7 +273,8 @@
  *
  * Returns 1 on success or < 0 on error.
  */
-static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, void *pxefile_addr_r)
+static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file,
+	unsigned long pxefile_addr_r)
 {
 	size_t base_len = strlen(PXELINUX_DIR);
 	char path[MAX_TFTP_PATH_LEN+1];
@@ -288,7 +295,7 @@
  *
  * Returns 1 on success or < 0 on error.
  */
-static int pxe_uuid_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
+static int pxe_uuid_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r)
 {
 	char *uuid_str;
 
@@ -306,7 +313,7 @@
  *
  * Returns 1 on success or < 0 on error.
  */
-static int pxe_mac_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
+static int pxe_mac_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r)
 {
 	char mac_str[21];
 	int err;
@@ -326,7 +333,7 @@
  *
  * Returns 1 on success or < 0 on error.
  */
-static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
+static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r)
 {
 	char ip_addr[9];
 	int mask_pos, err;
@@ -385,9 +392,9 @@
 	 * Keep trying paths until we successfully get a file we're looking
 	 * for.
 	 */
-	if (pxe_uuid_path(cmdtp, (void *)pxefile_addr_r) > 0 ||
-	    pxe_mac_path(cmdtp, (void *)pxefile_addr_r) > 0 ||
-	    pxe_ipaddr_paths(cmdtp, (void *)pxefile_addr_r) > 0) {
+	if (pxe_uuid_path(cmdtp, pxefile_addr_r) > 0 ||
+	    pxe_mac_path(cmdtp, pxefile_addr_r) > 0 ||
+	    pxe_ipaddr_paths(cmdtp, pxefile_addr_r) > 0) {
 		printf("Config file found\n");
 
 		return 0;
@@ -395,7 +402,7 @@
 
 	while (pxe_default_paths[i]) {
 		if (get_pxelinux_path(cmdtp, pxe_default_paths[i],
-				      (void *)pxefile_addr_r) > 0) {
+				      pxefile_addr_r) > 0) {
 			printf("Config file found\n");
 			return 0;
 		}
@@ -428,7 +435,7 @@
 	if (strict_strtoul(envaddr, 16, &file_addr) < 0)
 		return -EINVAL;
 
-	return get_relfile(cmdtp, file_path, (void *)file_addr);
+	return get_relfile(cmdtp, file_path, file_addr);
 }
 
 /*
@@ -791,6 +798,7 @@
 	else
 		do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
 #endif
+	unmap_sysmem(buf);
 	return 1;
 }
 
@@ -1055,7 +1063,8 @@
 	return 1;
 }
 
-static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, int nest_level);
+static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base,
+	struct pxe_menu *cfg, int nest_level);
 
 /*
  * Parse an include statement, and retrieve and parse the file it mentions.
@@ -1065,12 +1074,14 @@
  * include, nest_level has already been incremented and doesn't need to be
  * incremented here.
  */
-static int handle_include(cmd_tbl_t *cmdtp, char **c, char *base,
+static int handle_include(cmd_tbl_t *cmdtp, char **c, unsigned long base,
 				struct pxe_menu *cfg, int nest_level)
 {
 	char *include_path;
 	char *s = *c;
 	int err;
+	char *buf;
+	int ret;
 
 	err = parse_sliteral(c, &include_path);
 
@@ -1087,20 +1098,25 @@
 		return err;
 	}
 
-	return parse_pxefile_top(cmdtp, base, cfg, nest_level);
+	buf = map_sysmem(base, 0);
+	ret = parse_pxefile_top(cmdtp, buf, base, cfg, nest_level);
+	unmap_sysmem(buf);
+
+	return ret;
 }
 
 /*
  * Parse lines that begin with 'menu'.
  *
- * b and nest are provided to handle the 'menu include' case.
+ * base and nest are provided to handle the 'menu include' case.
  *
- * b should be the address where the file currently being parsed is stored.
+ * base should point to a location where it's safe to store the included file.
  *
  * nest_level should be 1 when parsing the top level pxe file, 2 when parsing
  * a file it includes, 3 when parsing a file included by that file, and so on.
  */
-static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, char *b, int nest_level)
+static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg,
+				unsigned long base, int nest_level)
 {
 	struct token t;
 	char *s = *c;
@@ -1115,7 +1131,7 @@
 		break;
 
 	case T_INCLUDE:
-		err = handle_include(cmdtp, c, b + strlen(b) + 1, cfg,
+		err = handle_include(cmdtp, c, base, cfg,
 						nest_level + 1);
 		break;
 
@@ -1282,7 +1298,8 @@
  *
  * Returns 1 on success, < 0 on error.
  */
-static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, int nest_level)
+static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base,
+				struct pxe_menu *cfg, int nest_level)
 {
 	struct token t;
 	char *s, *b, *label_name;
@@ -1304,7 +1321,9 @@
 		switch (t.type) {
 		case T_MENU:
 			cfg->prompt = 1;
-			err = parse_menu(cmdtp, &p, cfg, b, nest_level);
+			err = parse_menu(cmdtp, &p, cfg,
+				base + ALIGN(strlen(b) + 1, 4),
+				nest_level);
 			break;
 
 		case T_TIMEOUT:
@@ -1329,8 +1348,9 @@
 			break;
 
 		case T_INCLUDE:
-			err = handle_include(cmdtp, &p, b + ALIGN(strlen(b), 4), cfg,
-							nest_level + 1);
+			err = handle_include(cmdtp, &p,
+				base + ALIGN(strlen(b), 4), cfg,
+				nest_level + 1);
 			break;
 
 		case T_PROMPT:
@@ -1386,9 +1406,11 @@
  * files it includes). The resulting pxe_menu struct can be free()'d by using
  * the destroy_pxe_menu() function.
  */
-static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, char *menucfg)
+static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, unsigned long menucfg)
 {
 	struct pxe_menu *cfg;
+	char *buf;
+	int r;
 
 	cfg = malloc(sizeof(struct pxe_menu));
 
@@ -1399,7 +1421,11 @@
 
 	INIT_LIST_HEAD(&cfg->labels);
 
-	if (parse_pxefile_top(cmdtp, menucfg, cfg, 1) < 0) {
+	buf = map_sysmem(menucfg, 0);
+	r = parse_pxefile_top(cmdtp, buf, menucfg, cfg, 1);
+	unmap_sysmem(buf);
+
+	if (r < 0) {
 		destroy_pxe_menu(cfg);
 		return NULL;
 	}
@@ -1557,7 +1583,7 @@
 		return 1;
 	}
 
-	cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r));
+	cfg = parse_pxefile(cmdtp, pxefile_addr_r);
 
 	if (cfg == NULL) {
 		printf("Error parsing config file\n");
@@ -1664,12 +1690,12 @@
 		return 1;
 	}
 
-	if (get_pxe_file(cmdtp, filename, (void *)pxefile_addr_r) < 0) {
+	if (get_pxe_file(cmdtp, filename, pxefile_addr_r) < 0) {
 		printf("Error reading config file\n");
 		return 1;
 	}
 
-	cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r));
+	cfg = parse_pxefile(cmdtp, pxefile_addr_r);
 
 	if (cfg == NULL) {
 		printf("Error parsing config file\n");