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

Deepak Saxena
2010-12-07T00:56:26Z

commit 341764495180a712b9aaccfa0479b2ff7e44e35b
Author: Deepak Saxena <deepak_saxena@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@mentor.com>
Signed-off-by: Hollis Blanchard <hollis_blanchard@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