commit 341764495180a712b9aaccfa0479b2ff7e44e35b Author: Deepak Saxena <deepak_sax...@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_sax...@mentor.com> Signed-off-by: Hollis Blanchard <hollis_blanch...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot