From 590d3cacb98cb377b127869b58507d2afe9c904a Mon Sep 17 00:00:00 2001
From: Grant Likely <grant.likely@linaro.org>
Date: Mon, 28 Mar 2011 09:58:34 +0000
Subject: [PATCH 1/5] Stop passing around bootmem_base value.

For the calls to boot_relocate_fdt(), boot_get_cmdline(), and
boot_get_kbd(), the value of bootmem_base is always obtained by
calling getenv_bootm_low().  Since the value always comes from the
same source, the calling signature for those functions can be
simplified by making them call getenv_bootm_low() directly.

Signed-off-by: Grant Likely <grant.likely@linaro.org>
---
 arch/arm/lib/bootm.c     |  3 +--
 arch/m68k/lib/bootm.c    |  7 ++-----
 arch/powerpc/lib/bootm.c |  9 +++------
 common/cmd_bootm.c       |  3 +--
 common/image.c           | 25 +++++++++----------------
 include/image.h          |  8 +++-----
 6 files changed, 19 insertions(+), 36 deletions(-)

diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 77349530f0..aba13f4e86 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -178,7 +178,6 @@ static int bootm_linux_fdt(int machid, bootm_headers_t *images)
 {
 	ulong rd_len;
 	void (*kernel_entry)(int zero, int dt_machid, void *dtblob);
-	ulong bootmap_base = getenv_bootm_low();
 	ulong of_size = images->ft_len;
 	char **of_flat_tree = &images->ft_addr;
 	ulong *initrd_start = &images->initrd_start;
@@ -194,7 +193,7 @@ static int bootm_linux_fdt(int machid, bootm_headers_t *images)
 	if (ret)
 		return ret;
 
-	ret = boot_relocate_fdt(lmb, bootmap_base, of_flat_tree, &of_size);
+	ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
 	if (ret)
 		return ret;
 
diff --git a/arch/m68k/lib/bootm.c b/arch/m68k/lib/bootm.c
index 76a2fb27c1..1229ac7f25 100644
--- a/arch/m68k/lib/bootm.c
+++ b/arch/m68k/lib/bootm.c
@@ -71,7 +71,6 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima
 	int ret;
 
 	ulong cmd_start, cmd_end;
-	ulong bootmap_base;
 	bd_t  *kbd;
 	void  (*kernel) (bd_t *, ulong, ulong, ulong, ulong);
 	struct lmb *lmb = &images->lmb;
@@ -79,17 +78,15 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima
 	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
 		return 1;
 
-	bootmap_base = getenv_bootm_low();
-
 	/* allocate space and init command line */
-	ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base);
+	ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end);
 	if (ret) {
 		puts("ERROR with allocation of cmdline\n");
 		goto error;
 	}
 
 	/* allocate space for kernel copy of board info */
-	ret = boot_get_kbd (lmb, &kbd, bootmap_base);
+	ret = boot_get_kbd (lmb, &kbd);
 	if (ret) {
 		puts("ERROR with allocation of kernel bd\n");
 		goto error;
diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c
index c7f3d084a3..6e2a81b9aa 100644
--- a/arch/powerpc/lib/bootm.c
+++ b/arch/powerpc/lib/bootm.c
@@ -186,7 +186,6 @@ static void boot_prep_linux(void)
 
 static int boot_cmdline_linux(bootm_headers_t *images)
 {
-	ulong bootmap_base = getenv_bootm_low();
 	ulong of_size = images->ft_len;
 	struct lmb *lmb = &images->lmb;
 	ulong *cmd_start = &images->cmdline_start;
@@ -196,7 +195,7 @@ static int boot_cmdline_linux(bootm_headers_t *images)
 
 	if (!of_size) {
 		/* allocate space and init command line */
-		ret = boot_get_cmdline (lmb, cmd_start, cmd_end, bootmap_base);
+		ret = boot_get_cmdline (lmb, cmd_start, cmd_end);
 		if (ret) {
 			puts("ERROR with allocation of cmdline\n");
 			return ret;
@@ -208,7 +207,6 @@ static int boot_cmdline_linux(bootm_headers_t *images)
 
 static int boot_bd_t_linux(bootm_headers_t *images)
 {
-	ulong bootmap_base = getenv_bootm_low();
 	ulong of_size = images->ft_len;
 	struct lmb *lmb = &images->lmb;
 	bd_t **kbd = &images->kbd;
@@ -217,7 +215,7 @@ static int boot_bd_t_linux(bootm_headers_t *images)
 
 	if (!of_size) {
 		/* allocate space for kernel copy of board info */
-		ret = boot_get_kbd (lmb, kbd, bootmap_base);
+		ret = boot_get_kbd (lmb, kbd);
 		if (ret) {
 			puts("ERROR with allocation of kernel bd\n");
 			return ret;
@@ -235,7 +233,6 @@ static int boot_body_linux(bootm_headers_t *images)
 	ulong *initrd_start = &images->initrd_start;
 	ulong *initrd_end = &images->initrd_end;
 #if defined(CONFIG_OF_LIBFDT)
-	ulong bootmap_base = getenv_bootm_low();
 	ulong of_size = images->ft_len;
 	char **of_flat_tree = &images->ft_addr;
 #endif
@@ -258,7 +255,7 @@ static int boot_body_linux(bootm_headers_t *images)
 		return ret;
 
 #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_SYS_BOOTMAPSZ)
-	ret = boot_relocate_fdt(lmb, bootmap_base, of_flat_tree, &of_size);
+	ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
 	if (ret)
 		return ret;
 
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 778f6a4296..989bf737ff 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -547,8 +547,7 @@ int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
 #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_SYS_BOOTMAPSZ)
 		case BOOTM_STATE_FDT:
 		{
-			ulong bootmap_base = getenv_bootm_low();
-			ret = boot_relocate_fdt(&images.lmb, bootmap_base,
+			ret = boot_relocate_fdt(&images.lmb,
 				&images.ft_addr, &images.ft_len);
 			break;
 		}
diff --git a/common/image.c b/common/image.c
index f63a2ff1a0..c86b86fbe7 100644
--- a/common/image.c
+++ b/common/image.c
@@ -1172,7 +1172,6 @@ static int fit_check_fdt (const void *fit, int fdt_noffset, int verify)
 /**
  * boot_relocate_fdt - relocate flat device tree
  * @lmb: pointer to lmb handle, will be used for memory mgmt
- * @bootmap_base: base address of the bootmap region
  * @of_flat_tree: pointer to a char* variable, will hold fdt start address
  * @of_size: pointer to a ulong variable, will hold fdt length
  *
@@ -1188,8 +1187,7 @@ static int fit_check_fdt (const void *fit, int fdt_noffset, int verify)
  *      1 - failure
  */
 #if defined(CONFIG_SYS_BOOTMAPSZ)
-int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
-		char **of_flat_tree, ulong *of_size)
+int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size)
 {
 	void	*fdt_blob = *of_flat_tree;
 	void	*of_start = 0;
@@ -1209,7 +1207,7 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
 	/* Pad the FDT by a specified amount */
 	of_len = *of_size + CONFIG_SYS_FDT_PAD;
 	of_start = (void *)(unsigned long)lmb_alloc_base(lmb, of_len, 0x1000,
-			(CONFIG_SYS_BOOTMAPSZ + bootmap_base));
+			CONFIG_SYS_BOOTMAPSZ + getenv_bootm_low());
 
 	if (of_start == 0) {
 		puts("device tree - allocation error\n");
@@ -1567,11 +1565,9 @@ error:
  * @lmb: pointer to lmb handle, will be used for memory mgmt
  * @cmd_start: pointer to a ulong variable, will hold cmdline start
  * @cmd_end: pointer to a ulong variable, will hold cmdline end
- * @bootmap_base: ulong variable, holds offset in physical memory to
- * base of bootmap
  *
  * boot_get_cmdline() allocates space for kernel command line below
- * BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt
+ * BOOTMAPSZ + getenv_bootm_low() address. If "bootargs" U-boot environemnt
  * variable is present its contents is copied to allocated kernel
  * command line.
  *
@@ -1579,14 +1575,13 @@ error:
  *      0 - success
  *     -1 - failure
  */
-int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
-			ulong bootmap_base)
+int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end)
 {
 	char *cmdline;
 	char *s;
 
 	cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf,
-					 CONFIG_SYS_BOOTMAPSZ + bootmap_base);
+				     CONFIG_SYS_BOOTMAPSZ + getenv_bootm_low());
 
 	if (cmdline == NULL)
 		return -1;
@@ -1610,21 +1605,19 @@ int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
  * boot_get_kbd - allocate and initialize kernel copy of board info
  * @lmb: pointer to lmb handle, will be used for memory mgmt
  * @kbd: double pointer to board info data
- * @bootmap_base: ulong variable, holds offset in physical memory to
- * base of bootmap
  *
  * boot_get_kbd() allocates space for kernel copy of board info data below
- * BOOTMAPSZ + bootmap_base address and kernel board info is initialized with
- * the current u-boot board info data.
+ * BOOTMAPSZ + getenv_bootm_low() address and kernel board info is initialized
+ * with the current u-boot board info data.
  *
  * returns:
  *      0 - success
  *     -1 - failure
  */
-int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base)
+int boot_get_kbd (struct lmb *lmb, bd_t **kbd)
 {
 	*kbd = (bd_t *)(ulong)lmb_alloc_base(lmb, sizeof(bd_t), 0xf,
-				      CONFIG_SYS_BOOTMAPSZ + bootmap_base);
+				     CONFIG_SYS_BOOTMAPSZ + getenv_bootm_low());
 	if (*kbd == NULL)
 		return -1;
 
diff --git a/include/image.h b/include/image.h
index 005e0d24e4..792de25104 100644
--- a/include/image.h
+++ b/include/image.h
@@ -336,8 +336,7 @@ int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images,
 #ifdef CONFIG_OF_LIBFDT
 int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *images,
 		char **of_flat_tree, ulong *of_size);
-int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
-		char **of_flat_tree, ulong *of_size);
+int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size);
 #endif
 
 #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
@@ -345,11 +344,10 @@ int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
 		  ulong *initrd_start, ulong *initrd_end);
 #endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */
 #ifdef CONFIG_SYS_BOOT_GET_CMDLINE
-int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
-			ulong bootmap_base);
+int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end);
 #endif /* CONFIG_SYS_BOOT_GET_CMDLINE */
 #ifdef CONFIG_SYS_BOOT_GET_KBD
-int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base);
+int boot_get_kbd (struct lmb *lmb, bd_t **kbd);
 #endif /* CONFIG_SYS_BOOT_GET_KBD */
 #endif /* !USE_HOSTCC */
 

From c3624e6ed0a36f54aa0b3e7f32d30a6fde434f51 Mon Sep 17 00:00:00 2001
From: Grant Likely <grant.likely@linaro.org>
Date: Mon, 28 Mar 2011 09:58:43 +0000
Subject: [PATCH 2/5] Default to bootm_size() when CONFIG_SYS_BOOTMAPSZ is not
 defined

This patch adds a function getenv_bootm_mapsize() for obtaining the
size of the early mapped region accessible by the kernel during early
boot.  It defaults to CONFIG_SYS_BOOTMAPSZ, or if not defined,
defaults to getenv_bootm_size(), which in turn defaults to the size of
RAM.

getenv_bootm_mapsize() can also be overridden with a "bootm_mapsize"
environmental variable.

Signed-off-by: Grant Likely <grant.likely@linaro.org>
---
 README                   | 16 ++++++++++++++--
 arch/powerpc/lib/bootm.c |  2 +-
 common/image.c           | 22 +++++++++++++++++++---
 include/image.h          |  1 +
 4 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/README b/README
index cdbb9de02c..b647ecac34 100644
--- a/README
+++ b/README
@@ -2348,7 +2348,10 @@ Configuration Settings:
 		used) must be put below this limit, unless "bootm_low"
 		enviroment variable is defined and non-zero. In such case
 		all data for the Linux kernel must be between "bootm_low"
-		and "bootm_low" + CONFIG_SYS_BOOTMAPSZ.
+		and "bootm_low" + CONFIG_SYS_BOOTMAPSZ.  The environment
+		variable "bootm_mapsize" will override the value of
+		CONFIG_SYS_BOOTMAPSZ.  If CONFIG_SYS_BOOTMAPSZ is undefined,
+		then the value in "bootm_size" will be used instead.
 
 - CONFIG_SYS_BOOT_RAMDISK_HIGH:
 		Enable initrd_high functionality.  If defined then the
@@ -3184,7 +3187,16 @@ List of environment variables (most likely not complete):
 		  for use by the bootm command. See also "bootm_size"
 		  environment variable. Address defined by "bootm_low" is
 		  also the base of the initial memory mapping for the Linux
-		  kernel -- see the description of CONFIG_SYS_BOOTMAPSZ.
+		  kernel -- see the description of CONFIG_SYS_BOOTMAPSZ and
+		  bootm_mapsize.
+
+  bootm_mapsize	- Size of the initial memory mapping for the Linux kernel.
+		  This variable is given as a hexadecimal number and it
+		  defines the size of the memory region starting at base
+		  address bootm_low that is accessible by the Linux kernel
+		  during early boot.  If unset, CONFIG_SYS_BOOTMAPSZ is used
+		  as the default value if it is defined, and bootm_size is
+		  used otherwise.
 
   bootm_size	- Memory range available for image processing in the bootm
 		  command can be restricted. This variable is given as
diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c
index 6e2a81b9aa..02e544fcdd 100644
--- a/arch/powerpc/lib/bootm.c
+++ b/arch/powerpc/lib/bootm.c
@@ -96,7 +96,7 @@ static void boot_jump_linux(bootm_headers_t *images)
 		debug ("   Booting using OF flat tree...\n");
 		WATCHDOG_RESET ();
 		(*kernel) ((bd_t *)of_flat_tree, 0, 0, EPAPR_MAGIC,
-			   CONFIG_SYS_BOOTMAPSZ, 0, 0);
+			   getenv_bootm_mapsize(), 0, 0);
 		/* does not return */
 	} else
 #endif
diff --git a/common/image.c b/common/image.c
index c86b86fbe7..d8ba2ab90a 100644
--- a/common/image.c
+++ b/common/image.c
@@ -454,6 +454,22 @@ phys_size_t getenv_bootm_size(void)
 #endif
 }
 
+phys_size_t getenv_bootm_mapsize(void)
+{
+	phys_size_t tmp;
+	char *s = getenv ("bootm_mapsize");
+	if (s) {
+		tmp = (phys_size_t)simple_strtoull (s, NULL, 16);
+		return tmp;
+	}
+
+#if defined(CONFIG_SYS_BOOTMAPSZ)
+	return CONFIG_SYS_BOOTMAPSZ;
+#else
+	return getenv_bootm_size();
+#endif
+}
+
 void memmove_wd (void *to, void *from, size_t len, ulong chunksz)
 {
 	if (to == from)
@@ -1207,7 +1223,7 @@ int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size)
 	/* Pad the FDT by a specified amount */
 	of_len = *of_size + CONFIG_SYS_FDT_PAD;
 	of_start = (void *)(unsigned long)lmb_alloc_base(lmb, of_len, 0x1000,
-			CONFIG_SYS_BOOTMAPSZ + getenv_bootm_low());
+			getenv_bootm_mapsize() + getenv_bootm_low());
 
 	if (of_start == 0) {
 		puts("device tree - allocation error\n");
@@ -1581,7 +1597,7 @@ int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end)
 	char *s;
 
 	cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf,
-				     CONFIG_SYS_BOOTMAPSZ + getenv_bootm_low());
+				getenv_bootm_mapsize() + getenv_bootm_low());
 
 	if (cmdline == NULL)
 		return -1;
@@ -1617,7 +1633,7 @@ int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end)
 int boot_get_kbd (struct lmb *lmb, bd_t **kbd)
 {
 	*kbd = (bd_t *)(ulong)lmb_alloc_base(lmb, sizeof(bd_t), 0xf,
-				     CONFIG_SYS_BOOTMAPSZ + getenv_bootm_low());
+				getenv_bootm_mapsize() + getenv_bootm_low());
 	if (*kbd == NULL)
 		return -1;
 
diff --git a/include/image.h b/include/image.h
index 792de25104..8c40557314 100644
--- a/include/image.h
+++ b/include/image.h
@@ -451,6 +451,7 @@ int image_check_dcrc (const image_header_t *hdr);
 int getenv_yesno (char *var);
 ulong getenv_bootm_low(void);
 phys_size_t getenv_bootm_size(void);
+phys_size_t getenv_bootm_mapsize(void);
 void memmove_wd (void *to, void *from, size_t len, ulong chunksz);
 #endif
 

From ed59e58786cae9f8afcb575649afc65985beed4d Mon Sep 17 00:00:00 2001
From: Grant Likely <grant.likely@linaro.org>
Date: Mon, 28 Mar 2011 09:58:49 +0000
Subject: [PATCH 3/5] Remove device tree booting dependency on
 CONFIG_SYS_BOOTMAPSZ

The previous patch makes u-boot use the full accessible size of ram as
the default boot mapped size if CONFIG_SYS_BOOTMAPSZ is not defined,
which means boot_relocate_fdt() can be changed to depend solely on
CONFIG_OF_LIBFDT.

Signed-off-by: Grant Likely <grant.likely@linaro.org>
---
 arch/powerpc/lib/bootm.c       | 4 ++--
 common/cmd_bootm.c             | 2 +-
 common/image.c                 | 4 ++--
 include/configs/omap3_beagle.h | 7 -------
 4 files changed, 5 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c
index 02e544fcdd..6be22c474a 100644
--- a/arch/powerpc/lib/bootm.c
+++ b/arch/powerpc/lib/bootm.c
@@ -254,7 +254,7 @@ static int boot_body_linux(bootm_headers_t *images)
 	if (ret)
 		return ret;
 
-#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_SYS_BOOTMAPSZ)
+#if defined(CONFIG_OF_LIBFDT)
 	ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
 	if (ret)
 		return ret;
@@ -293,7 +293,7 @@ static int boot_body_linux(bootm_headers_t *images)
 		if (*initrd_start && *initrd_end)
 			fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
 	}
-#endif	/* CONFIG_OF_LIBFDT && CONFIG_SYS_BOOTMAPSZ */
+#endif	/* CONFIG_OF_LIBFDT */
 	return 0;
 }
 
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 989bf737ff..a23e465696 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -544,7 +544,7 @@ int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
 		}
 			break;
 #endif
-#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_SYS_BOOTMAPSZ)
+#if defined(CONFIG_OF_LIBFDT)
 		case BOOTM_STATE_FDT:
 		{
 			ret = boot_relocate_fdt(&images.lmb,
diff --git a/common/image.c b/common/image.c
index d8ba2ab90a..5ce4b1bd24 100644
--- a/common/image.c
+++ b/common/image.c
@@ -1202,7 +1202,7 @@ static int fit_check_fdt (const void *fit, int fdt_noffset, int verify)
  *      0 - success
  *      1 - failure
  */
-#if defined(CONFIG_SYS_BOOTMAPSZ)
+#if defined(CONFIG_OF_LIBFDT)
 int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size)
 {
 	void	*fdt_blob = *of_flat_tree;
@@ -1252,7 +1252,7 @@ int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size)
 error:
 	return 1;
 }
-#endif /* CONFIG_SYS_BOOTMAPSZ */
+#endif /* CONFIG_OF_LIBFDT */
 
 /**
  * boot_get_fdt - main fdt handling routine
diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h
index 5cfa4cb69a..a0f6829625 100644
--- a/include/configs/omap3_beagle.h
+++ b/include/configs/omap3_beagle.h
@@ -56,13 +56,6 @@
 #define CONFIG_MISC_INIT_R
 
 #define CONFIG_OF_LIBFDT		1
-/*
- * The early kernel mapping on ARM currently only maps from the base of DRAM
- * to the end of the kernel image.  The kernel is loaded at DRAM base + 0x8000.
- * The early kernel pagetable uses DRAM base + 0x4000 to DRAM base + 0x8000,
- * so that leaves DRAM base to DRAM base + 0x4000 available.
- */
-#define CONFIG_SYS_BOOTMAPSZ	        0x4000
 
 #define CONFIG_CMDLINE_TAG		1	/* enable passing of ATAGs */
 #define CONFIG_SETUP_MEMORY_TAGS	1

From ce6b27a874fe30e7126ae93c060277770ee85ced Mon Sep 17 00:00:00 2001
From: Grant Likely <grant.likely@linaro.org>
Date: Mon, 28 Mar 2011 09:58:55 +0000
Subject: [PATCH 4/5] Fix off-by-one error in passing initrd end address via
 device tree

The initrd_end variable contains the address immediately *after* the
initrd blob, not the last address containing data.  This patch fixes
an inadvertent off-by-one when setting up the initrd reserved map.

Signed-off-by: Grant Likely <grant.likely@linaro.org>
---
 common/fdt_support.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common/fdt_support.c b/common/fdt_support.c
index edcf04a21b..496040b54c 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -183,7 +183,7 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
 		}
 	}
 
-	err = fdt_add_mem_rsv(fdt, initrd_start, initrd_end - initrd_start + 1);
+	err = fdt_add_mem_rsv(fdt, initrd_start, initrd_end - initrd_start);
 	if (err < 0) {
 		printf("fdt_initrd: %s\n", fdt_strerror(err));
 		return err;

From 55b0a39314562087143f439ecae57379b97db9aa Mon Sep 17 00:00:00 2001
From: Grant Likely <grant.likely@linaro.org>
Date: Mon, 28 Mar 2011 09:59:01 +0000
Subject: [PATCH 5/5] Respect memreserve regions specified in the device tree

If a regions is reserved in the fdt, then it should not be used.  Add
the memreserve regions to the lmb so that u-boot doesn't use them to
store the initrd.

Signed-off-by: Grant Likely <grant.likely@linaro.org>
---
 arch/arm/lib/bootm.c     |  2 ++
 arch/powerpc/lib/bootm.c |  4 ++++
 common/cmd_bootm.c       |  2 ++
 common/image.c           | 29 ++++++++++++++++++++++++++++-
 include/image.h          |  1 +
 5 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index aba13f4e86..802e833a2e 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -187,6 +187,8 @@ static int bootm_linux_fdt(int machid, bootm_headers_t *images)
 
 	kernel_entry = (void (*)(int, int, void *))images->ep;
 
+	boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
+
 	rd_len = images->rd_end - images->rd_start;
 	ret = boot_ramdisk_high(lmb, images->rd_start, rd_len,
 				initrd_start, initrd_end);
diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c
index 6be22c474a..e01787dcb7 100644
--- a/arch/powerpc/lib/bootm.c
+++ b/arch/powerpc/lib/bootm.c
@@ -239,6 +239,10 @@ static int boot_body_linux(bootm_headers_t *images)
 
 	int ret;
 
+#if defined(CONFIG_OF_LIBFDT)
+	boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
+#endif
+
 	/* allocate space and init command line */
 	ret = boot_cmdline_linux(images);
 	if (ret)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index a23e465696..1966da48ca 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -547,6 +547,8 @@ int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
 #if defined(CONFIG_OF_LIBFDT)
 		case BOOTM_STATE_FDT:
 		{
+			boot_fdt_add_mem_rsv_regions(&images.lmb,
+						     images.ft_addr);
 			ret = boot_relocate_fdt(&images.lmb,
 				&images.ft_addr, &images.ft_len);
 			break;
diff --git a/common/image.c b/common/image.c
index 5ce4b1bd24..e542a57367 100644
--- a/common/image.c
+++ b/common/image.c
@@ -1185,6 +1185,34 @@ static int fit_check_fdt (const void *fit, int fdt_noffset, int verify)
 #define CONFIG_SYS_FDT_PAD 0x3000
 #endif
 
+#if defined(CONFIG_OF_LIBFDT)
+/**
+ * boot_fdt_add_mem_rsv_regions - Mark the memreserve sections as unusable
+ * @lmb: pointer to lmb handle, will be used for memory mgmt
+ * @fdt_blob: pointer to fdt blob base address
+ *
+ * Adds the memreserve regions in the dtb to the lmb block.  Adding the
+ * memreserve regions prevents u-boot from using them to store the initrd
+ * or the fdt blob.
+ */
+void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
+{
+	uint64_t addr, size;
+	int i, total;
+
+	if (fdt_check_header (fdt_blob) != 0)
+		return;
+
+	total = fdt_num_mem_rsv(fdt_blob);
+	for (i = 0; i < total; i++) {
+		if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0)
+			continue;
+		printf("   reserving fdt memory region: addr=%llx size=%llx\n",
+			(unsigned long long)addr, (unsigned long long)size);
+		lmb_reserve(lmb, addr, size);
+	}
+}
+
 /**
  * boot_relocate_fdt - relocate flat device tree
  * @lmb: pointer to lmb handle, will be used for memory mgmt
@@ -1202,7 +1230,6 @@ static int fit_check_fdt (const void *fit, int fdt_noffset, int verify)
  *      0 - success
  *      1 - failure
  */
-#if defined(CONFIG_OF_LIBFDT)
 int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size)
 {
 	void	*fdt_blob = *of_flat_tree;
diff --git a/include/image.h b/include/image.h
index 8c40557314..c31e862d32 100644
--- a/include/image.h
+++ b/include/image.h
@@ -336,6 +336,7 @@ int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images,
 #ifdef CONFIG_OF_LIBFDT
 int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *images,
 		char **of_flat_tree, ulong *of_size);
+void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob);
 int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size);
 #endif