[U-Boot] [PATCH] Honor /memory/reg node in DTB files

Deepak Saxena deepak_saxena at mentor.com
Tue Dec 7 01:56:26 CET 2010


commit 341764495180a712b9aaccfa0479b2ff7e44e35b
Author: Deepak Saxena <deepak_saxena at mentor.com>
Date:   Mon Dec 6 15:52:07 2010 -0800

     Honor /memory/reg node in DTB files

     This patch adds code to the bootm path to check if a valid
     /memory/reg node exists in the DTB file and if so, it
     does not override it with the values in bi_memstart and
     bi_memsize. This is particularly useful in multi-core
     environments where the memory may be partitioned across
     a large number of nodes.

     While the same can be accomplished on certain boards (p1022ds
     and p1_p2_rdb) by using the bootm_low and bootm_size
     environment variables, that solution is not universal and
     requires adding code ft_board_setup() for any new board
     that wants to support AMP operation. Also, given that the
     DTB is already  used to partition board devices (see commit
     dc2e673 in the Linux kernel tree), it makes sense to
     allow memory to be partitioned the same way from a user
     configuration perspective.

     This patch allows for the user to override the DTB file parameters
     on the p1022ds and p1_p2_rdb boards by setting the bootm_low and
     bootm_size to something other than bi_memstart and bi_memsize.
     In the long-term, those env variables should be depecrated and
     removed and system implementors should provide the memory
     partitioning information in the DTB.

     Signed-off-by: Deepak Saxena <deepak_saxena at mentor.com>
     Signed-off-by: Hollis Blanchard <hollis_blanchard at mentor.com>

---

See http://lists.denx.de/pipermail/u-boot/2010-December/083057.html
for initial proposal on this.

diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c
index 4540364..6d384e3 100644
--- a/arch/powerpc/cpu/mpc85xx/fdt.c
+++ b/arch/powerpc/cpu/mpc85xx/fdt.c
@@ -377,6 +377,55 @@ static void ft_fixup_qe_snum(void *blob)
  }
  #endif

+/*
+ * Check to see if an valid memory/reg property exists
+ * in the fdt. If so, we do not overwrite it with what's
+ * been scanned.
+ *
+ * Valid mean all the following:
+ *
+ * - Memory node has a device-type of "memory"
+ * - A reg property exists which:
+ *   + has exactly as many cells as #address-cells + #size-cells
+ *   + provides a range that is within [bi_memstart, bi_memstart + 
bi_memsize]
+ */
+static int ft_validate_memory(void *blob, bd_t *bd)
+{
+	int nodeoffset;
+	u32 *addrcell = (u32*)fdt_getprop(blob, 0, "#address-cells", NULL);
+	u32 *sizecell = (u32*)fdt_getprop(blob, 0, "#size-cells", NULL);
+	u64 reg_base, reg_size;
+	void *reg, *dtype;
+	int len;
+
+	if ((nodeoffset = fdt_path_offset(blob, "/memory")) >= 0)
+	{
+		dtype = fdt_getprop(blob, nodeoffset, "device_type", &len);
+		if (!dtype || (strcmp(dtype, "memory") != 0))
+			return 0;
+
+		reg = fdt_getprop(blob, nodeoffset, "reg", &len);
+		if (reg && len == ((*addrcell + *sizecell) * 4)) {
+			if (*addrcell == 2) {
+				reg_base = ((u64*)reg)[0];
+				reg_size = ((u64*)reg)[1];
+			} else {
+				reg_base = ((u32*)reg)[0];
+				reg_size = ((u32*)reg)[1];
+			}
+
+			if ((reg_size) &&
+			    (reg_base >= (u64)bd->bi_memstart) &&
+			    ((reg_size + reg_base)
+			     <= ((u64)bd->bi_memstart + (u64)bd->bi_memsize)))
+				return 1;				
+		}
+	}
+
+	return 0;
+
+}
+
  void ft_cpu_setup(void *blob, bd_t *bd)
  {
  	int off;
@@ -434,7 +483,8 @@ void ft_cpu_setup(void *blob, bd_t *bd)
  		"clock-frequency", CONFIG_SYS_CLK_FREQ, 1);
  #endif

-	fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
+	if (!ft_validate_memory(blob, bd))
+		fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);

  #ifdef CONFIG_MP
  	ft_fixup_cpu(blob, (u64)bd->bi_memstart + (u64)bd->bi_memsize);
diff --git a/board/freescale/p1022ds/p1022ds.c 
b/board/freescale/p1022ds/p1022ds.c
index 5cdee9f..7378d88 100644
--- a/board/freescale/p1022ds/p1022ds.c
+++ b/board/freescale/p1022ds/p1022ds.c
@@ -320,7 +320,8 @@ void ft_board_setup(void *blob, bd_t *bd)
  	base = getenv_bootm_low();
  	size = getenv_bootm_size();

-	fdt_fixup_memory(blob, (u64)base, (u64)size);
+	if (base != (phys_addr_t)bd->bi_memstart && size != 
(phys_addr_t)bd->bi_memsize)
+		fdt_fixup_memory(blob, (u64)base, (u64)size);

  	FT_FSL_PCI_SETUP;

diff --git a/board/freescale/p1_p2_rdb/p1_p2_rdb.c 
b/board/freescale/p1_p2_rdb/p1_p2_rdb.c
index fae31f2..5e4adc6 100644
--- a/board/freescale/p1_p2_rdb/p1_p2_rdb.c
+++ b/board/freescale/p1_p2_rdb/p1_p2_rdb.c
@@ -220,9 +220,10 @@ void ft_board_setup(void *blob, bd_t *bd)
  	base = getenv_bootm_low();
  	size = getenv_bootm_size();

-	ft_pci_board_setup(blob);
+	if (base != (phys_addr_t)bd->bi_memstart && size != 
(phys_addr_t)bd->bi_memsize)
+		fdt_fixup_memory(blob, (u64)base, (u64)size);

-	fdt_fixup_memory(blob, (u64)base, (u64)size);
+	ft_pci_board_setup(blob);
  }
  #endif



More information about the U-Boot mailing list