[U-Boot] [PATCH v2 0/6] Add ARM flat device tree support

This is the third submission of this patch series. The first was an RFC and I received lots of comments that I addressed in the second for which I got no feedback.
This version fixes some issues I found in testing on a hacked Beagle kernel with enough device tree functionality to verify that u-boot is able to pass a device tree.
Patch summary: 1-4 are fixes/clean up to existing code 3 needs testing on nios and microblaze 5 actually adds the ARM FDT support 6 enables FDT support for omap3_beagle
John Rigby (6): fdt_relocate: fix fdt size and endian bugs FDT: Add fixup support for multiple banks of memory FDT: only call boot_get_fdt from generic code boot: change some arch ifdefs to feature ifdefs ARM: add flat device tree support ARM: enable device tree for beagle
arch/arm/include/asm/config.h | 2 + arch/arm/lib/bootm.c | 137 ++++++++++++++++++++++++++++++++---- arch/m68k/include/asm/config.h | 3 + arch/microblaze/lib/bootm.c | 12 +--- arch/nios2/lib/bootm.c | 8 +-- arch/powerpc/include/asm/config.h | 3 + arch/sparc/include/asm/config.h | 1 + common/cmd_bootm.c | 4 +- common/fdt_support.c | 86 ++++++++++++----------- common/image.c | 18 +++-- include/configs/omap3_beagle.h | 9 +++ include/fdt_support.h | 1 + include/image.h | 9 ++- 13 files changed, 210 insertions(+), 83 deletions(-)

Fix two problems in fdt_relocate.
First, for the non relocation case current code calculates fdt blob size by subtracting the fdt address from the end of bootmap. This wrong because it assumes that the fdt_blob is located at the top (high) of the bootmap. Use the current size plus padding instead. For example if the blob is at the beginning of bootmap then the calculated size will be the size of the entire bootmapped area.
Second, fdt_relocate returns bad size info on little endian platforms because it calls be32_to_cpu on the value returned by fdt_totalsize. This is wrong because the value returned by fdt_totalsize is already cpu endian.
Signed-off-by: John Rigby john.rigby@linaro.org --- common/image.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/common/image.c b/common/image.c index 3a2f25e..4aec9d6 100644 --- a/common/image.c +++ b/common/image.c @@ -1252,7 +1252,7 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, *of_size = of_len; } else { *of_flat_tree = fdt_blob; - of_len = (CONFIG_SYS_BOOTMAPSZ + bootmap_base) - (ulong)fdt_blob; + of_len = *of_size + (unsigned)CONFIG_SYS_FDT_PAD; lmb_reserve(lmb, (ulong)fdt_blob, of_len); fdt_set_totalsize(*of_flat_tree, of_len);
@@ -1561,7 +1561,7 @@ int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *imag goto error; }
- if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) { + if (fdt_totalsize(fdt_blob) != fdt_len) { fdt_error ("fdt size != image size"); goto error; } @@ -1575,7 +1575,7 @@ int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *imag }
*of_flat_tree = fdt_blob; - *of_size = be32_to_cpu (fdt_totalsize (fdt_blob)); + *of_size = fdt_totalsize(fdt_blob); debug (" of_flat_tree at 0x%08lx size 0x%08lx\n", (ulong)*of_flat_tree, *of_size);

Dear John Rigby,
In message 1285775292-15060-2-git-send-email-john.rigby@linaro.org you wrote:
Fix two problems in fdt_relocate.
First, for the non relocation case current code calculates fdt blob size by subtracting the fdt address from the end
Please consider the non relocation case obsoleted. This is nothing that needs to or should have FDT support added.
of bootmap. This wrong because it assumes that the fdt_blob is located at the top (high) of the bootmap. Use the current size plus padding instead. For example if the blob is at the beginning of bootmap then the calculated size will be the size of the entire bootmapped area.
Second, fdt_relocate returns bad size info on little endian platforms because it calls be32_to_cpu on the value returned by fdt_totalsize. This is wrong because the value returned by fdt_totalsize is already cpu endian.
Signed-off-by: John Rigby john.rigby@linaro.org
common/image.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
Sorry, but the commit message and the code changes don't match at all.
You say you were fixing fdt_relocate(), but you change only common/image.c which is unrelated,
Please fix the commit message.
diff --git a/common/image.c b/common/image.c index 3a2f25e..4aec9d6 100644 --- a/common/image.c +++ b/common/image.c @@ -1252,7 +1252,7 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, *of_size = of_len; } else { *of_flat_tree = fdt_blob;
of_len = (CONFIG_SYS_BOOTMAPSZ + bootmap_base) - (ulong)fdt_blob;
of_len = *of_size + (unsigned)CONFIG_SYS_FDT_PAD;
Um... what are the implications of this on other architectures?
For example, on which PowerPC systems has this been tested?
Best regards,
Wolfgang Denk

On Tue, Oct 12, 2010 at 3:20 PM, Wolfgang Denk wd@denx.de wrote:
Dear John Rigby,
In message 1285775292-15060-2-git-send-email-john.rigby@linaro.org you wrote:
Fix two problems in fdt_relocate.
Sorry this should be boot_relocate_fdt
First, for the non relocation case current code calculates fdt blob size by subtracting the fdt address from the end
Please consider the non relocation case obsoleted. This is nothing that needs to or should have FDT support added.
of bootmap. This wrong because it assumes that the fdt_blob is located at the top (high) of the bootmap. Use the current size plus padding instead. For example if the blob is at the beginning of bootmap then the calculated size will be the size of the entire bootmapped area.
Second, fdt_relocate returns bad size info on little endian platforms because it calls be32_to_cpu on the value returned by fdt_totalsize. This is wrong because the value returned by fdt_totalsize is already cpu endian.
After changing fdt_relocate to boot_relocate_fdt the commit message is correct.
index 3a2f25e..4aec9d6 100644 --- a/common/image.c +++ b/common/image.c @@ -1252,7 +1252,7 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, *of_size = of_len; } else { *of_flat_tree = fdt_blob;
- of_len = (CONFIG_SYS_BOOTMAPSZ + bootmap_base) - (ulong)fdt_blob;
- of_len = *of_size + (unsigned)CONFIG_SYS_FDT_PAD;
Um... what are the implications of this on other architectures?
I believe this bug has never caused anyone problems because the else has never been reached.

Dear John Rigby,
In message AANLkTimuGeO9wq8FWDmwcyo2Rrfe1h9fyy05TYzJ4LRR@mail.gmail.com you wrote:
On Tue, Oct 12, 2010 at 3:20 PM, Wolfgang Denk wd@denx.de wrote:
Dear John Rigby,
In message 1285775292-15060-2-git-send-email-john.rigby@linaro.org you wrote:
Fix two problems in fdt_relocate.
Sorry this should be boot_relocate_fdt
In the Subject: it's more helpful to refer to the component / file name, i. e. here: "common/image.c: ..."
Second, fdt_relocate returns bad size info on little endian platforms because it calls be32_to_cpu on the value returned by fdt_totalsize. This is wrong because the value returned by fdt_totalsize is already cpu endian.
After changing fdt_relocate to boot_relocate_fdt the commit message is correct.
I disagree. My understanding is that fdt_relocate() does not return a bad size, the additional use of be32_to_cpu() in image.c corrupts the correct value. Otherwise the fix would need to be done in fdt_relocate().
Um... what are the implications of this on other architectures?
I believe this bug has never caused anyone problems because the else has never been reached.
So what are the implications, and how has it been tested?
Best regards,
Wolfgang Denk

Add fdt_fixup_memory_banks and reimplement fdt_fixup_memory using it.
Signed-off-by: John Rigby john.rigby@linaro.org --- common/fdt_support.c | 86 ++++++++++++++++++++++++++----------------------- include/fdt_support.h | 1 + 2 files changed, 47 insertions(+), 40 deletions(-)
diff --git a/common/fdt_support.c b/common/fdt_support.c index 6f32e3f..c8a45f9 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -362,10 +362,40 @@ void do_fixup_by_compat_u32(void *fdt, const char *compat, do_fixup_by_compat(fdt, compat, prop, &val, 4, create); }
-int fdt_fixup_memory(void *blob, u64 start, u64 size) +/* + * Get cells len in bytes + * if #NNNN-cells property is 2 then len is 8 + * otherwise len is 4 + */ +static int get_cells_len(void *blob, char *nr_cells_name) +{ + const u32 *cell; + + cell = fdt_getprop(blob, 0, nr_cells_name, NULL); + if (cell && *cell == 2) + return 8; + + return 4; +} + +/* + * Write a 4 or 8 byte big endian cell + */ +static void write_cell(u8 *addr, u64 val, int size) { - int err, nodeoffset, len = 0; - u8 tmp[16]; + int shift = (size - 1) * 8; + while (size-- > 0) { + *addr++ = (val >> shift) & 0xff; + shift -= 8; + } +} + +int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks) +{ + int err, nodeoffset; + int addr_cell_len, size_cell_len, len; + u8 tmp[banks * 8]; + int bank; const u32 *addrcell, *sizecell;
err = fdt_check_header(blob); @@ -391,44 +421,15 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) return err; }
- addrcell = fdt_getprop(blob, 0, "#address-cells", NULL); - /* use shifts and mask to ensure endianness */ - if ((addrcell) && (*addrcell == 2)) { - tmp[0] = (start >> 56) & 0xff; - tmp[1] = (start >> 48) & 0xff; - tmp[2] = (start >> 40) & 0xff; - tmp[3] = (start >> 32) & 0xff; - tmp[4] = (start >> 24) & 0xff; - tmp[5] = (start >> 16) & 0xff; - tmp[6] = (start >> 8) & 0xff; - tmp[7] = (start ) & 0xff; - len = 8; - } else { - tmp[0] = (start >> 24) & 0xff; - tmp[1] = (start >> 16) & 0xff; - tmp[2] = (start >> 8) & 0xff; - tmp[3] = (start ) & 0xff; - len = 4; - } + addr_cell_len = get_cells_len(blob, "#address-cells"); + size_cell_len = get_cells_len(blob, "#size-cells");
- sizecell = fdt_getprop(blob, 0, "#size-cells", NULL); - /* use shifts and mask to ensure endianness */ - if ((sizecell) && (*sizecell == 2)) { - tmp[0+len] = (size >> 56) & 0xff; - tmp[1+len] = (size >> 48) & 0xff; - tmp[2+len] = (size >> 40) & 0xff; - tmp[3+len] = (size >> 32) & 0xff; - tmp[4+len] = (size >> 24) & 0xff; - tmp[5+len] = (size >> 16) & 0xff; - tmp[6+len] = (size >> 8) & 0xff; - tmp[7+len] = (size ) & 0xff; - len += 8; - } else { - tmp[0+len] = (size >> 24) & 0xff; - tmp[1+len] = (size >> 16) & 0xff; - tmp[2+len] = (size >> 8) & 0xff; - tmp[3+len] = (size ) & 0xff; - len += 4; + for (bank = 0, len = 0; bank < banks; bank++) { + write_cell(tmp + len, start[bank], addr_cell_len); + len += addr_cell_len; + + write_cell(tmp + len, size[bank], size_cell_len); + len += size_cell_len; }
err = fdt_setprop(blob, nodeoffset, "reg", tmp, len); @@ -440,6 +441,11 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) return 0; }
+int fdt_fixup_memory(void *blob, u64 start, u64 size) +{ + return fdt_fixup_memory_banks(blob, &start, &size, 1); +} + void fdt_fixup_ethernet(void *fdt) { int node, i, j; diff --git a/include/fdt_support.h b/include/fdt_support.h index fd94929..7457121 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -48,6 +48,7 @@ void do_fixup_by_compat(void *fdt, const char *compat, void do_fixup_by_compat_u32(void *fdt, const char *compat, const char *prop, u32 val, int create); int fdt_fixup_memory(void *blob, u64 start, u64 size); +int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks); void fdt_fixup_ethernet(void *fdt); int fdt_find_and_setprop(void *fdt, const char *node, const char *prop, const void *val, int len, int create);

Dear John Rigby,
In message 1285775292-15060-3-git-send-email-john.rigby@linaro.org you wrote:
Add fdt_fixup_memory_banks and reimplement fdt_fixup_memory using it.
Signed-off-by: John Rigby john.rigby@linaro.org
This needs to go thorugh the FDT custodian or at least needs his ACK.
You probably want to put him on Cc: so he gets aware of the patch [done here].
Best regards,
Wolfgang Denk

All arches except nios2 and microblaze call boot_get_fdt from bootm_start in common/cmd_bootm.c.
Having nios2 and microblaze do so as well removes code from their respective do_bootm_linux routines and allows removal of a nasty ifdef from bootm_start.
Signed-off-by: John Rigby john.rigby@linaro.org CC: Scott McNutt smcnutt@psyent.com CC: Michal Simek monstr@monstr.eu --- arch/microblaze/lib/bootm.c | 12 +++--------- arch/nios2/lib/bootm.c | 8 +++----- common/cmd_bootm.c | 2 -- 3 files changed, 6 insertions(+), 16 deletions(-)
diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index 8e2c6d8..25f63d9 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -46,12 +46,9 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima
char *of_flat_tree = NULL; #if defined(CONFIG_OF_LIBFDT) - ulong of_size = 0; - - /* find flattened device tree */ - ret = boot_get_fdt (flag, argc, argv, images, &of_flat_tree, &of_size); - if (ret) - return 1; + /* did generic code already find a device tree? */ + if (images->ft_len) + of_flat_tree = images->ft_addr; #endif
theKernel = (void (*)(char *, ulong, ulong))images->ep; @@ -64,9 +61,6 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima
show_boot_progress (15);
- if (!(ulong) of_flat_tree) - of_flat_tree = (char *)simple_strtoul (argv[3], NULL, 16); - #ifdef DEBUG printf ("## Transferring control to Linux (at address 0x%08lx) " \ "ramdisk 0x%08lx, FDT 0x%08lx...\n", diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c index 40a4d15..f32be52 100644 --- a/arch/nios2/lib/bootm.c +++ b/arch/nios2/lib/bootm.c @@ -36,11 +36,9 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima ulong initrd_end = images->rd_end; char *of_flat_tree = NULL; #if defined(CONFIG_OF_LIBFDT) - ulong of_size = 0; - - /* find flattened device tree */ - if (boot_get_fdt(flag, argc, argv, images, &of_flat_tree, &of_size)) - return 1; + /* did generic code already find a device tree? */ + if (images->ft_len) + of_flat_tree = images->ft_addr; #endif if (!of_flat_tree && argc > 3) of_flat_tree = (char *)simple_strtoul(argv[3], NULL, 16); diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index db59e6f..25bc39c 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -308,7 +308,6 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] }
#if defined(CONFIG_OF_LIBFDT) -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) /* find flattened device tree */ ret = boot_get_fdt (flag, argc, argv, &images, &images.ft_addr, &images.ft_len); @@ -319,7 +318,6 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
set_working_fdt_addr(images.ft_addr); #endif -#endif }
images.os.start = (ulong)os_hdr;

Dear John Rigby,
In message 1285775292-15060-4-git-send-email-john.rigby@linaro.org you wrote:
All arches except nios2 and microblaze call boot_get_fdt from bootm_start in common/cmd_bootm.c.
Having nios2 and microblaze do so as well removes code from their respective do_bootm_linux routines and allows removal of a nasty ifdef from bootm_start.
Signed-off-by: John Rigby john.rigby@linaro.org CC: Scott McNutt smcnutt@psyent.com CC: Michal Simek monstr@monstr.eu
arch/microblaze/lib/bootm.c | 12 +++--------- arch/nios2/lib/bootm.c | 8 +++----- common/cmd_bootm.c | 2 -- 3 files changed, 6 insertions(+), 16 deletions(-)
diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index 8e2c6d8..25f63d9 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -46,12 +46,9 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima
char *of_flat_tree = NULL; #if defined(CONFIG_OF_LIBFDT)
- ulong of_size = 0;
- /* find flattened device tree */
- ret = boot_get_fdt (flag, argc, argv, images, &of_flat_tree, &of_size);
- if (ret)
return 1;
- /* did generic code already find a device tree? */
- if (images->ft_len)
of_flat_tree = images->ft_addr;
#endif
So what if the generic code did NOT find a device tree?
Before, there was an error return. And now?
diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c index 40a4d15..f32be52 100644 --- a/arch/nios2/lib/bootm.c +++ b/arch/nios2/lib/bootm.c @@ -36,11 +36,9 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima ulong initrd_end = images->rd_end; char *of_flat_tree = NULL; #if defined(CONFIG_OF_LIBFDT)
- ulong of_size = 0;
- /* find flattened device tree */
- if (boot_get_fdt(flag, argc, argv, images, &of_flat_tree, &of_size))
return 1;
- /* did generic code already find a device tree? */
- if (images->ft_len)
of_flat_tree = images->ft_addr;
Ditto.
On which nios2 and microblaze has this been tested?
You may want to put the NIOS and MB custodians on Cc:
Best regards,
Wolfgang Denk

On Tue, Oct 12, 2010 at 3:24 PM, Wolfgang Denk wd@denx.de wrote:
Dear John Rigby,
In message 1285775292-15060-4-git-send-email-john.rigby@linaro.org you wrote:
All arches except nios2 and microblaze call boot_get_fdt from bootm_start in common/cmd_bootm.c.
....
- /* find flattened device tree */
- ret = boot_get_fdt (flag, argc, argv, images, &of_flat_tree, &of_size);
- if (ret)
- return 1;
- /* did generic code already find a device tree? */
- if (images->ft_len)
- of_flat_tree = images->ft_addr;
#endif
So what if the generic code did NOT find a device tree?
Before, there was an error return. And now?
I'll fix this.
- /* find flattened device tree */
- if (boot_get_fdt(flag, argc, argv, images, &of_flat_tree, &of_size))
- return 1;
- /* did generic code already find a device tree? */
- if (images->ft_len)
- of_flat_tree = images->ft_addr;
Ditto.
And this.
On which nios2 and microblaze has this been tested?
It hasn't that is why the custodians were CC'd.
You may want to put the NIOS and MB custodians on Cc:
I just checked my original message. They were CC'd unless I am very confused.
Thanks, John

Dear John Rigby,
In message AANLkTi=Qzxn91cp3XwN=OaDNK0VRV0yLnRAeh5W9J2G+@mail.gmail.com you wrote:
You may want to put the NIOS and MB custodians on Cc:
I just checked my original message. They were CC'd unless I am very confused.
We really have to find out when and why the list server is playing such tricks on us :-(
Sorry for the noise, then.
Best regards,
Wolfgang Denk

The routines boot_ramdisk_high, boot_get_cmdline and boot_get_kbd are currently enabled by various combinations of CONFIG_M68K, CONFIG_POWERPC and CONFIG_SPARC.
Use CONFIG_<FEATURE> defines instead.
CONFIG_BOOT_RAMDISK_HIGH CONFIG_BOOT_GET_CMDLINE CONFIG_BOOT_GET_KBD
Define these as appropriate in arch/include/asm/config.h files.
Signed-off-by: John Rigby john.rigby@linaro.org --- arch/m68k/include/asm/config.h | 3 +++ arch/powerpc/include/asm/config.h | 3 +++ arch/sparc/include/asm/config.h | 1 + common/cmd_bootm.c | 2 +- common/image.c | 10 ++++++---- include/image.h | 9 ++++++--- 6 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/arch/m68k/include/asm/config.h b/arch/m68k/include/asm/config.h index 36438be..1fbdf0a 100644 --- a/arch/m68k/include/asm/config.h +++ b/arch/m68k/include/asm/config.h @@ -22,5 +22,8 @@ #define _ASM_CONFIG_H_
#define CONFIG_LMB +#define CONFIG_BOOT_RAMDISK_HIGH +#define CONFIG_BOOT_GET_CMDLINE +#define CONFIG_BOOT_GET_KBD
#endif diff --git a/arch/powerpc/include/asm/config.h b/arch/powerpc/include/asm/config.h index d098657..788f27d 100644 --- a/arch/powerpc/include/asm/config.h +++ b/arch/powerpc/include/asm/config.h @@ -22,6 +22,9 @@ #define _ASM_CONFIG_H_
#define CONFIG_LMB +#define CONFIG_BOOT_RAMDISK_HIGH +#define CONFIG_BOOT_GET_CMDLINE +#define CONFIG_BOOT_GET_KBD
#ifndef CONFIG_MAX_MEM_MAPPED #if defined(CONFIG_4xx) || defined(CONFIG_E500) || defined(CONFIG_MPC86xx) diff --git a/arch/sparc/include/asm/config.h b/arch/sparc/include/asm/config.h index 36438be..b072771 100644 --- a/arch/sparc/include/asm/config.h +++ b/arch/sparc/include/asm/config.h @@ -22,5 +22,6 @@ #define _ASM_CONFIG_H_
#define CONFIG_LMB +#define CONFIG_BOOT_RAMDISK_HIGH
#endif diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 25bc39c..e78896f 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -528,7 +528,7 @@ int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); break; -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#ifdef CONFIG_BOOT_RAMDISK_HIGH case BOOTM_STATE_RAMDISK: { ulong rd_len = images.rd_end - images.rd_start; diff --git a/common/image.c b/common/image.c index 4aec9d6..0562e3b 100644 --- a/common/image.c +++ b/common/image.c @@ -992,7 +992,7 @@ int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images, return 0; }
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#ifdef CONFIG_BOOT_RAMDISK_HIGH /** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1081,7 +1081,7 @@ int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, error: return -1; } -#endif /* defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) */ +#endif /* CONFIG_BOOT_RAMDISK_HIGH */
#ifdef CONFIG_OF_LIBFDT static void fdt_error (const char *msg) @@ -1588,7 +1588,7 @@ error: } #endif /* CONFIG_OF_LIBFDT */
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +#ifdef CONFIG_BOOT_GET_CMDLINE /** * boot_get_cmdline - allocate and initialize kernel cmdline * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1630,7 +1630,9 @@ int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
return 0; } +#endif /* CONFIG_BOOT_GET_CMDLINE */
+#ifdef CONFIG_BOOT_GET_KBD /** * boot_get_kbd - allocate and initialize kernel copy of board info * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1663,7 +1665,7 @@ int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base)
return 0; } -#endif /* CONFIG_PPC || CONFIG_M68K */ +#endif /* CONFIG_BOOT_GET_KBD */ #endif /* !USE_HOSTCC */
#if defined(CONFIG_FIT) diff --git a/include/image.h b/include/image.h index 18a9f0e..5983a98 100644 --- a/include/image.h +++ b/include/image.h @@ -340,14 +340,17 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, char **of_flat_tree, ulong *of_size); #endif
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +#ifdef CONFIG_BOOT_RAMDISK_HIGH int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, ulong *initrd_start, ulong *initrd_end); - +#endif /* CONFIG_BOOT_RAMDISK_HIGH */ +#ifdef CONFIG_BOOT_GET_CMDLINE int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, ulong bootmap_base); +#endif /* CONFIG_BOOT_GET_CMDLINE */ +#ifdef CONFIG_BOOT_GET_KBD int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base); -#endif /* CONFIG_PPC || CONFIG_M68K */ +#endif /* CONFIG_BOOT_GET_KBD */ #endif /* !USE_HOSTCC */
/*******************************************************************/

Dear John Rigby,
In message 1285775292-15060-5-git-send-email-john.rigby@linaro.org you wrote:
The routines boot_ramdisk_high, boot_get_cmdline and boot_get_kbd are currently enabled by various combinations of CONFIG_M68K, CONFIG_POWERPC and CONFIG_SPARC.
Use CONFIG_<FEATURE> defines instead.
CONFIG_BOOT_RAMDISK_HIGH CONFIG_BOOT_GET_CMDLINE CONFIG_BOOT_GET_KBD
Define these as appropriate in arch/include/asm/config.h files.
No. CONFIG_ means user coinfigurable options; these are not actually configurable on a per-board base by the end user, so CONFIG_SYS_ should be used.
Signed-off-by: John Rigby john.rigby@linaro.org
arch/m68k/include/asm/config.h | 3 +++ arch/powerpc/include/asm/config.h | 3 +++ arch/sparc/include/asm/config.h | 1 + common/cmd_bootm.c | 2 +- common/image.c | 10 ++++++---- include/image.h | 9 ++++++--- 6 files changed, 20 insertions(+), 8 deletions(-)
Also, the new variables need to be documented in the README.
Best regards,
Wolfgang Denk

On Tue, Oct 12, 2010 at 3:27 PM, Wolfgang Denk wd@denx.de wrote:
Dear John Rigby,
In message 1285775292-15060-5-git-send-email-john.rigby@linaro.org you wrote:
The routines boot_ramdisk_high, boot_get_cmdline and boot_get_kbd are currently enabled by various combinations of CONFIG_M68K, CONFIG_POWERPC and CONFIG_SPARC.
Use CONFIG_<FEATURE> defines instead.
CONFIG_BOOT_RAMDISK_HIGH CONFIG_BOOT_GET_CMDLINE CONFIG_BOOT_GET_KBD
Define these as appropriate in arch/include/asm/config.h files.
No. CONFIG_ means user coinfigurable options; these are not actually configurable on a per-board base by the end user, so CONFIG_SYS_ should be used.
I will change these to CONFIG_SYS_ and document them in README.

Based on other architectures already supported.
Signed-off-by: John Rigby john.rigby@linaro.org --- arch/arm/include/asm/config.h | 2 + arch/arm/lib/bootm.c | 137 ++++++++++++++++++++++++++++++++++++----- common/image.c | 2 + 3 files changed, 125 insertions(+), 16 deletions(-)
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index 4e8dfd7..d85a396 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -25,4 +25,6 @@ /* Relocation to SDRAM works on all ARM boards */ #define CONFIG_RELOC_FIXUP_WORKS #endif +#define CONFIG_LMB +#define CONFIG_BOOT_RAMDISK_HIGH #endif diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 3101321..2e7b2e1 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -26,6 +26,9 @@ #include <image.h> #include <u-boot/zlib.h> #include <asm/byteorder.h> +#include <fdt.h> +#include <libfdt.h> +#include <fdt_support.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -50,12 +53,52 @@ static void setup_end_tag (bd_t *bd); static struct tag *params; #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
-int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) +static ulong get_sp(void); +#if defined(CONFIG_OF_LIBFDT) +static int bootm_linux_fdt(int machid, bootm_headers_t *images); +#endif + +void arch_lmb_reserve(struct lmb *lmb) +{ + ulong sp; + + /* + * Booting a (Linux) kernel image + * + * Allocate space for command line and board info - the + * address should be as high as possible within the reach of + * the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused + * memory, which means far enough below the current stack + * pointer. + */ + sp = get_sp(); + debug("## Current stack ends at 0x%08lx ", sp); + + /* adjust sp by 1K to be safe */ + sp -= 1024; + lmb_reserve(lmb, sp, + gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp); +} + +static void announce_and_cleanup(void) +{ + printf("\nStarting kernel ...\n\n"); + +#ifdef CONFIG_USB_DEVICE + { + extern void udc_disconnect(void); + udc_disconnect(); + } +#endif + cleanup_before_linux(); +} + +int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { bd_t *bd = gd->bd; char *s; int machid = bd->bi_arch_number; - void (*theKernel)(int zero, int arch, uint params); + void (*kernel_entry)(int zero, int arch, uint params);
#ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); @@ -64,8 +107,6 @@ 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;
- theKernel = (void (*)(int, int, uint))images->ep; - s = getenv ("machid"); if (s) { machid = simple_strtoul (s, NULL, 16); @@ -74,8 +115,15 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima
show_boot_progress (15);
+#ifdef CONFIG_OF_LIBFDT + if (images->ft_len) + return bootm_linux_fdt(machid, images); +#endif + + kernel_entry = (void (*)(int, int, uint))images->ep; + debug ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) theKernel); + (ulong) kernel_entry);
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ @@ -99,27 +147,76 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima if (images->rd_start && images->rd_end) setup_initrd_tag (bd, images->rd_start, images->rd_end); #endif - setup_end_tag (bd); + setup_end_tag(bd); #endif
- /* we assume that the kernel is in place */ - printf ("\nStarting kernel ...\n\n"); + announce_and_cleanup();
-#ifdef CONFIG_USB_DEVICE - { - extern void udc_disconnect (void); - udc_disconnect (); + kernel_entry(0, machid, bd->bi_boot_params); + /* does not return */ + + return 1; +} + +#if defined(CONFIG_OF_LIBFDT) +static int fixup_memory_node(void *blob) +{ + bd_t *bd = gd->bd; + int bank; + u64 start[CONFIG_NR_DRAM_BANKS]; + u64 size[CONFIG_NR_DRAM_BANKS]; + + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + start[bank] = bd->bi_dram[bank].start; + size[bank] = bd->bi_dram[bank].size; } -#endif
- cleanup_before_linux (); + return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); +} + +static int bootm_linux_fdt(int machid, bootm_headers_t *images) +{ + ulong rd_len; + bd_t *bd = gd->bd; + char *s; + 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; + ulong *initrd_end = &images->initrd_end; + struct lmb *lmb = &images->lmb; + int ret; + + kernel_entry = (void (*)(int, int, void *))images->ep; + + rd_len = images->rd_end - images->rd_start; + ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, + initrd_start, initrd_end); + if (ret) + return ret; + + ret = boot_relocate_fdt(lmb, bootmap_base, of_flat_tree, &of_size); + if (ret) + return ret;
- theKernel (0, machid, bd->bi_boot_params); + debug("## Transferring control to Linux (at address %08lx) ...\n", + (ulong) kernel_entry); + + fdt_chosen(*of_flat_tree, 1); + + fixup_memory_node(*of_flat_tree); + + fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1); + + announce_and_cleanup(); + + kernel_entry(0, machid, *of_flat_tree); /* does not return */
return 1; } - +#endif
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ @@ -239,4 +336,12 @@ static void setup_end_tag (bd_t *bd) params->hdr.size = 0; }
+static ulong get_sp(void) +{ + ulong ret; + + asm("mov %0, sp" : "=r"(ret) : ); + return ret; +} + #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ diff --git a/common/image.c b/common/image.c index 0562e3b..7b181cc 100644 --- a/common/image.c +++ b/common/image.c @@ -1214,9 +1214,11 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, if (fdt_blob < (char *)bootmap_base) relocate = 1;
+#ifdef CONFIG_SYS_BOOTMAPSZ if ((fdt_blob + *of_size + CONFIG_SYS_FDT_PAD) >= ((char *)CONFIG_SYS_BOOTMAPSZ + bootmap_base)) relocate = 1; +#endif
/* move flattend device tree if needed */ if (relocate) {

On Wed, Sep 29, 2010 at 9:48 AM, John Rigby john.rigby@linaro.org wrote:
Based on other architectures already supported.
Signed-off-by: John Rigby john.rigby@linaro.org
From an response to an earlier version of this patch:
Tested-by: Rob Herring rob.herring@smooth-stone.com

Dear John Rigby,
In message 1285775292-15060-6-git-send-email-john.rigby@linaro.org you wrote:
Based on other architectures already supported.
Signed-off-by: John Rigby john.rigby@linaro.org
arch/arm/include/asm/config.h | 2 + arch/arm/lib/bootm.c | 137 ++++++++++++++++++++++++++++++++++++----- common/image.c | 2 + 3 files changed, 125 insertions(+), 16 deletions(-)
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index 4e8dfd7..d85a396 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -25,4 +25,6 @@ /* Relocation to SDRAM works on all ARM boards */ #define CONFIG_RELOC_FIXUP_WORKS #endif +#define CONFIG_LMB +#define CONFIG_BOOT_RAMDISK_HIGH #endif
These should be CONFIG_SYS_ instead.
diff --git a/common/image.c b/common/image.c index 0562e3b..7b181cc 100644 --- a/common/image.c +++ b/common/image.c @@ -1214,9 +1214,11 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, if (fdt_blob < (char *)bootmap_base) relocate = 1;
+#ifdef CONFIG_SYS_BOOTMAPSZ if ((fdt_blob + *of_size + CONFIG_SYS_FDT_PAD) >= ((char *)CONFIG_SYS_BOOTMAPSZ + bootmap_base)) relocate = 1; +#endif
What is the impact of this on other architectures?
On which systems / architectures has this been tested?
Best regards,
Wolfgang Denk

On Tue, Oct 12, 2010 at 3:29 PM, Wolfgang Denk wd@denx.de wrote:
Dear John Rigby,
In message 1285775292-15060-6-git-send-email-john.rigby@linaro.org you wrote:
Based on other architectures already supported.
Signed-off-by: John Rigby john.rigby@linaro.org
arch/arm/include/asm/config.h | 2 + arch/arm/lib/bootm.c | 137 ++++++++++++++++++++++++++++++++++++----- common/image.c | 2 + 3 files changed, 125 insertions(+), 16 deletions(-)
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index 4e8dfd7..d85a396 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -25,4 +25,6 @@ /* Relocation to SDRAM works on all ARM boards */ #define CONFIG_RELOC_FIXUP_WORKS #endif +#define CONFIG_LMB +#define CONFIG_BOOT_RAMDISK_HIGH #endif
These should be CONFIG_SYS_ instead.
These are not new. Do you want me to submit a patch changing all existing instances to CONFIG_SYS_*?
diff --git a/common/image.c b/common/image.c index 0562e3b..7b181cc 100644 --- a/common/image.c +++ b/common/image.c @@ -1214,9 +1214,11 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, if (fdt_blob < (char *)bootmap_base) relocate = 1;
+#ifdef CONFIG_SYS_BOOTMAPSZ if ((fdt_blob + *of_size + CONFIG_SYS_FDT_PAD) >= ((char *)CONFIG_SYS_BOOTMAPSZ + bootmap_base)) relocate = 1; +#endif
What is the impact of this on other architectures?
This ifdef is not needed I will remove it. It is an artifact of trying to make the code work without CONFIG_SYS_BOOTMAPSZ which I subsequently abandoned.
On which systems / architectures has this been tested?
Best regards,
Wolfgang Denk
-- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de I wish I had a bronze torc for every user who didn't read the manual. - Terry Pratchett, _The Light Fantastic_

Dear John Rigby,
In message AANLkTikYU9LtSCHLUP-6-=vd5WPWpnyVkHkZnW23zqc5@mail.gmail.com you wrote:
index 4e8dfd7..d85a396 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -25,4 +25,6 @@ /* Relocation to SDRAM works on all ARM boards */ #define CONFIG_RELOC_FIXUP_WORKS #endif +#define CONFIG_LMB +#define CONFIG_BOOT_RAMDISK_HIGH #endif
These should be CONFIG_SYS_ instead.
These are not new. Do you want me to submit a patch changing all existing instances to CONFIG_SYS_*?
Not new? I must be missing something then. I cannot find any reference to CONFIG_BOOT_RAMDISK_HIGH anywhere in the current code.
CONFIG_LMB is indeed not new, but a misnomer that should by fixed. Also, an explanation should be added to the README. [I am aware that this is not a fault of your patch.]
CONFIG_RELOC_FIXUP_WORKS is also a misnomer now, and undocumented :-(
On which systems / architectures has this been tested?
Please make sure to proovide such information, it _is_ important.
Best regards,
Wolfgang Denk

For testing ARM device tree support
Signed-off-by: John Rigby john.rigby@linaro.org --- include/configs/omap3_beagle.h | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h index 2463be4..daf84c7 100644 --- a/include/configs/omap3_beagle.h +++ b/include/configs/omap3_beagle.h @@ -55,6 +55,15 @@ #undef CONFIG_USE_IRQ /* no support for IRQs */ #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 #define CONFIG_INITRD_TAG 1

There have been no NACK's to this and one Tested-by, so can this series go into 2010.12?
Thanks, John
On Wed, Sep 29, 2010 at 9:48 AM, John Rigby john.rigby@linaro.org wrote:
This is the third submission of this patch series. The first was an RFC and I received lots of comments that I addressed in the second for which I got no feedback.
This version fixes some issues I found in testing on a hacked Beagle kernel with enough device tree functionality to verify that u-boot is able to pass a device tree.
Patch summary: 1-4 are fixes/clean up to existing code 3 needs testing on nios and microblaze 5 actually adds the ARM FDT support 6 enables FDT support for omap3_beagle
John Rigby (6): fdt_relocate: fix fdt size and endian bugs FDT: Add fixup support for multiple banks of memory FDT: only call boot_get_fdt from generic code boot: change some arch ifdefs to feature ifdefs ARM: add flat device tree support ARM: enable device tree for beagle
arch/arm/include/asm/config.h | 2 + arch/arm/lib/bootm.c | 137 ++++++++++++++++++++++++++++++++---- arch/m68k/include/asm/config.h | 3 + arch/microblaze/lib/bootm.c | 12 +--- arch/nios2/lib/bootm.c | 8 +-- arch/powerpc/include/asm/config.h | 3 + arch/sparc/include/asm/config.h | 1 + common/cmd_bootm.c | 4 +- common/fdt_support.c | 86 ++++++++++++----------- common/image.c | 18 +++-- include/configs/omap3_beagle.h | 9 +++ include/fdt_support.h | 1 + include/image.h | 9 ++- 13 files changed, 210 insertions(+), 83 deletions(-)

On Thu, Oct 7, 2010 at 10:11 AM, John Rigby john.rigby@linaro.org wrote:
There have been no NACK's to this and one Tested-by, so can this series go into 2010.12?
Thanks, John
Apologies in advance for the top post.

Dear John Rigby,
In message AANLkTi=pWR=UnByG0gGiqA4dK++5HA5XQCQo8Cfn9XUK@mail.gmail.com you wrote:
There have been no NACK's to this and one Tested-by, so can this series go into 2010.12?
Sure. Sorry, I'm late with ARM related stuff, but your patches are on my list.
Best regards,
Wolfgang Denk

This new v3 series attempts to address all feedback received regarding v2.
Patch 1/7 and 2/7 (old 1/6) split in two with better commit message to explain what exactly the fixes do. Patch 3/7 (old 2/6) added CC to libfdt maintainer. Patch 4/7 (old 3/6) fixed patch and better commit message and added another CC. Patch 5/7 (old 4/6) changed the new CONFIG_*'s to CONFIG_SYS_*'s and documented them in README. Patch 6/7 (old 5/6) Removed redundant ifdef, better commit message. Patch 7/7 (old 6/6) Unchanged.
John Rigby (7): common/image.c fix length calculation in boot_relocate_fdt common/image.c remove extra calls to be32_to_cpu in boot_get_fdt FDT: Add fixup support for multiple banks of memory FDT: only call boot_get_fdt from generic code boot: change some arch ifdefs to feature ifdefs ARM: add flat device tree support ARM: enable device tree for beagle
README | 13 ++++ arch/arm/include/asm/config.h | 2 + arch/arm/lib/bootm.c | 137 ++++++++++++++++++++++++++++++++---- arch/m68k/include/asm/config.h | 3 + arch/microblaze/lib/bootm.c | 14 ++--- arch/nios2/lib/bootm.c | 8 +-- arch/powerpc/include/asm/config.h | 3 + arch/sparc/include/asm/config.h | 1 + common/cmd_bootm.c | 6 +- common/fdt_support.c | 86 ++++++++++++----------- common/image.c | 16 +++-- include/configs/omap3_beagle.h | 9 +++ include/fdt_support.h | 1 + include/image.h | 9 ++- 14 files changed, 224 insertions(+), 84 deletions(-)

Dear John Rigby,
In message 1286999857-13790-1-git-send-email-john.rigby@linaro.org you wrote:
This new v3 series attempts to address all feedback received regarding v2.
Patch 1/7 and 2/7 (old 1/6) split in two with better commit message to explain what exactly the fixes do. Patch 3/7 (old 2/6) added CC to libfdt maintainer. Patch 4/7 (old 3/6) fixed patch and better commit message and added another CC. Patch 5/7 (old 4/6) changed the new CONFIG_*'s to CONFIG_SYS_*'s and documented them in README. Patch 6/7 (old 5/6) Removed redundant ifdef, better commit message. Patch 7/7 (old 6/6) Unchanged.
Plase check and confirm if my understanding of this series is correct:
Patch 1/7 and 2/7 affect generic code and go through me.
Patch 3/7 affects FDT code and goes through Gerry (or Gerry AKC's and tells me to pull it directly as part of the series).
Patch 4/7 affects generic code, plus NIOS2 and MicroBlace specific parts; it goes through me but needs ACKs from Scott McNutt and Michal Simek
Patch 5/7 affects generic code and goes through me.
Patch 6/7 and 7/7 affect ARM code and go through the ARM custodian (which happens to be me ATM).
Is this understanding correct? So you need the ACKs from Scott, Michal, and Gerry...
Best regards,
Wolfgang Denk

On Wed, Oct 13, 2010 at 2:41 PM, Wolfgang Denk wd@denx.de wrote:
Dear John Rigby,
In message 1286999857-13790-1-git-send-email-john.rigby@linaro.org you wrote:
This new v3 series attempts to address all feedback received regarding v2.
Patch 1/7 and 2/7 (old 1/6) split in two with better commit message to explain what exactly the fixes do. Patch 3/7 (old 2/6) added CC to libfdt maintainer. Patch 4/7 (old 3/6) fixed patch and better commit message and added another CC. Patch 5/7 (old 4/6) changed the new CONFIG_*'s to CONFIG_SYS_*'s and documented them in README. Patch 6/7 (old 5/6) Removed redundant ifdef, better commit message. Patch 7/7 (old 6/6) Unchanged.
Plase check and confirm if my understanding of this series is correct:
Patch 1/7 and 2/7 affect generic code and go through me.
Patch 3/7 affects FDT code and goes through Gerry (or Gerry AKC's and tells me to pull it directly as part of the series).
Patch 4/7 affects generic code, plus NIOS2 and MicroBlace specific parts; it goes through me but needs ACKs from Scott McNutt and Michal Simek
Patch 5/7 affects generic code and goes through me.
Patch 6/7 and 7/7 affect ARM code and go through the ARM custodian (which happens to be me ATM).
Is this understanding correct? So you need the ACKs from Scott, Michal, and Gerry...
Yes I believe this is correct.
Thanks, John

Dear John, Wolfgang,
The patch 4/7 looks good to me and runs on my MPC8360EMDS board (acked below). Wolfgang, if you would pull this directly, I would appreciate it.
On 10/13/2010 04:41 PM, Wolfgang Denk wrote:
Dear John Rigby,
In message1286999857-13790-1-git-send-email-john.rigby@linaro.org you wrote:
This new v3 series attempts to address all feedback received regarding v2.
Patch 1/7 and 2/7 (old 1/6) split in two with better commit message to explain what exactly the fixes do. Patch 3/7 (old 2/6) added CC to libfdt maintainer. Patch 4/7 (old 3/6) fixed patch and better commit message and added another CC. Patch 5/7 (old 4/6) changed the new CONFIG_*'s to CONFIG_SYS_*'s and documented them in README. Patch 6/7 (old 5/6) Removed redundant ifdef, better commit message. Patch 7/7 (old 6/6) Unchanged.
Plase check and confirm if my understanding of this series is correct:
Patch 1/7 and 2/7 affect generic code and go through me.
Patch 3/7 affects FDT code and goes through Gerry (or Gerry AKC's and tells me to pull it directly as part of the series).
Acked-by: Gerald Van Baren vanbaren@cideas.com
[snip]
Is this understanding correct? So you need the ACKs from Scott, Michal, and Gerry...
Best regards,
Wolfgang Denk
Best regards, gvb

boot_relocate_fdt is called on platforms with CONFIG_SYS_BOOTMAPSZ defined to relocate the device tree blob to be inside the boot map area between bootmap_base and bootmap_base+CONFIG_SYS_BOOTMAPSZ.
For the case where the blob needs to be relocated, space is allocated inside the bootmap by calling lmb_alloc_base with size passed in plus some padding:
of_len = *of_size + CONFIG_SYS_FDT_PAD;
For the case where the blob is already inside the bounds of the boot map area, lmb_reserve is called to reserve the the space where the blob is already residing. The calculation for this case is currently:
of_len = (CONFIG_SYS_BOOTMAPSZ + bootmap_base) - (ulong)fdt_blob;
This is wrong because it reserves all the space in the boot map area from the blob to the end ignoring completely the actual size. The worst case is where the blob is at the beginning and the entire boot map area get reserved. Fix this by changing the length calculation to this:
of_len = *of_size + CONFIG_SYS_FDT_PAD;
This bug has likely never manifested itself because bootm has never been called with the fdt blob already in the bootmap area. In my testing on an OMAP3 beagle board I initially worked around the bug by simply moving the initial location of the fdt blob. I have tested with the new calculation with the fdt blob both inside and outside the boot map area.
Signed-off-by: John Rigby john.rigby@linaro.org --- common/image.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/common/image.c b/common/image.c index 3a2f25e..f59904d 100644 --- a/common/image.c +++ b/common/image.c @@ -1252,7 +1252,7 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, *of_size = of_len; } else { *of_flat_tree = fdt_blob; - of_len = (CONFIG_SYS_BOOTMAPSZ + bootmap_base) - (ulong)fdt_blob; + of_len = *of_size + CONFIG_SYS_FDT_PAD; lmb_reserve(lmb, (ulong)fdt_blob, of_len); fdt_set_totalsize(*of_flat_tree, of_len);

Dear John Rigby,
In message 1286999857-13790-2-git-send-email-john.rigby@linaro.org you wrote:
boot_relocate_fdt is called on platforms with CONFIG_SYS_BOOTMAPSZ defined to relocate the device tree blob to be inside the boot map area between bootmap_base and bootmap_base+CONFIG_SYS_BOOTMAPSZ.
For the case where the blob needs to be relocated, space is allocated inside the bootmap by calling lmb_alloc_base with size passed in plus some padding:
of_len = *of_size + CONFIG_SYS_FDT_PAD;
For the case where the blob is already inside the bounds of the boot map area, lmb_reserve is called to reserve the the space where the blob is already residing. The calculation for this case is currently:
of_len = (CONFIG_SYS_BOOTMAPSZ + bootmap_base) - (ulong)fdt_blob;
This is wrong because it reserves all the space in the boot map area from the blob to the end ignoring completely the actual size. The worst case is where the blob is at the beginning and the entire boot map area get reserved. Fix this by changing the length calculation to this:
of_len = *of_size + CONFIG_SYS_FDT_PAD;
This bug has likely never manifested itself because bootm has never been called with the fdt blob already in the bootmap area. In my testing on an OMAP3 beagle board I initially worked around the bug by simply moving the initial location of the fdt blob. I have tested with the new calculation with the fdt blob both inside and outside the boot map area.
Signed-off-by: John Rigby john.rigby@linaro.org
common/image.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
Applied to u-boot-arm, thanks.
Best regards,
Wolfgang Denk

fdt_totalsize returns size in cpu endian so don't call be32_to_cpu on the result. This was harmless on big endian platforms but not on little endian ARMs.
Signed-off-by: John Rigby john.rigby@linaro.org --- common/image.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/common/image.c b/common/image.c index f59904d..dda3025 100644 --- a/common/image.c +++ b/common/image.c @@ -1561,7 +1561,7 @@ int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *imag goto error; }
- if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) { + if (fdt_totalsize(fdt_blob) != fdt_len) { fdt_error ("fdt size != image size"); goto error; } @@ -1575,7 +1575,7 @@ int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *imag }
*of_flat_tree = fdt_blob; - *of_size = be32_to_cpu (fdt_totalsize (fdt_blob)); + *of_size = fdt_totalsize(fdt_blob); debug (" of_flat_tree at 0x%08lx size 0x%08lx\n", (ulong)*of_flat_tree, *of_size);

Dear John Rigby,
In message 1286999857-13790-3-git-send-email-john.rigby@linaro.org you wrote:
fdt_totalsize returns size in cpu endian so don't call be32_to_cpu on the result. This was harmless on big endian platforms but not on little endian ARMs.
Signed-off-by: John Rigby john.rigby@linaro.org
common/image.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
Applied to u-boot-arm, thanks.
Best regards,
Wolfgang Denk

Add fdt_fixup_memory_banks and reimplement fdt_fixup_memory using it. Tested on OMAP3 beagle board with two banks of memory.
Signed-off-by: John Rigby john.rigby@linaro.org CC: Jerry Van Baren vanbaren@cideas.com --- common/fdt_support.c | 86 ++++++++++++++++++++++++++----------------------- include/fdt_support.h | 1 + 2 files changed, 47 insertions(+), 40 deletions(-)
diff --git a/common/fdt_support.c b/common/fdt_support.c index 9b65a8a..fe53779 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -362,10 +362,40 @@ void do_fixup_by_compat_u32(void *fdt, const char *compat, do_fixup_by_compat(fdt, compat, prop, &val, 4, create); }
-int fdt_fixup_memory(void *blob, u64 start, u64 size) +/* + * Get cells len in bytes + * if #NNNN-cells property is 2 then len is 8 + * otherwise len is 4 + */ +static int get_cells_len(void *blob, char *nr_cells_name) +{ + const u32 *cell; + + cell = fdt_getprop(blob, 0, nr_cells_name, NULL); + if (cell && *cell == 2) + return 8; + + return 4; +} + +/* + * Write a 4 or 8 byte big endian cell + */ +static void write_cell(u8 *addr, u64 val, int size) { - int err, nodeoffset, len = 0; - u8 tmp[16]; + int shift = (size - 1) * 8; + while (size-- > 0) { + *addr++ = (val >> shift) & 0xff; + shift -= 8; + } +} + +int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks) +{ + int err, nodeoffset; + int addr_cell_len, size_cell_len, len; + u8 tmp[banks * 8]; + int bank; const u32 *addrcell, *sizecell;
err = fdt_check_header(blob); @@ -391,44 +421,15 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) return err; }
- addrcell = fdt_getprop(blob, 0, "#address-cells", NULL); - /* use shifts and mask to ensure endianness */ - if ((addrcell) && (*addrcell == 2)) { - tmp[0] = (start >> 56) & 0xff; - tmp[1] = (start >> 48) & 0xff; - tmp[2] = (start >> 40) & 0xff; - tmp[3] = (start >> 32) & 0xff; - tmp[4] = (start >> 24) & 0xff; - tmp[5] = (start >> 16) & 0xff; - tmp[6] = (start >> 8) & 0xff; - tmp[7] = (start ) & 0xff; - len = 8; - } else { - tmp[0] = (start >> 24) & 0xff; - tmp[1] = (start >> 16) & 0xff; - tmp[2] = (start >> 8) & 0xff; - tmp[3] = (start ) & 0xff; - len = 4; - } + addr_cell_len = get_cells_len(blob, "#address-cells"); + size_cell_len = get_cells_len(blob, "#size-cells");
- sizecell = fdt_getprop(blob, 0, "#size-cells", NULL); - /* use shifts and mask to ensure endianness */ - if ((sizecell) && (*sizecell == 2)) { - tmp[0+len] = (size >> 56) & 0xff; - tmp[1+len] = (size >> 48) & 0xff; - tmp[2+len] = (size >> 40) & 0xff; - tmp[3+len] = (size >> 32) & 0xff; - tmp[4+len] = (size >> 24) & 0xff; - tmp[5+len] = (size >> 16) & 0xff; - tmp[6+len] = (size >> 8) & 0xff; - tmp[7+len] = (size ) & 0xff; - len += 8; - } else { - tmp[0+len] = (size >> 24) & 0xff; - tmp[1+len] = (size >> 16) & 0xff; - tmp[2+len] = (size >> 8) & 0xff; - tmp[3+len] = (size ) & 0xff; - len += 4; + for (bank = 0, len = 0; bank < banks; bank++) { + write_cell(tmp + len, start[bank], addr_cell_len); + len += addr_cell_len; + + write_cell(tmp + len, size[bank], size_cell_len); + len += size_cell_len; }
err = fdt_setprop(blob, nodeoffset, "reg", tmp, len); @@ -440,6 +441,11 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) return 0; }
+int fdt_fixup_memory(void *blob, u64 start, u64 size) +{ + return fdt_fixup_memory_banks(blob, &start, &size, 1); +} + void fdt_fixup_ethernet(void *fdt) { int node, i, j; diff --git a/include/fdt_support.h b/include/fdt_support.h index deb5dda..ce6817b 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -48,6 +48,7 @@ void do_fixup_by_compat(void *fdt, const char *compat, void do_fixup_by_compat_u32(void *fdt, const char *compat, const char *prop, u32 val, int create); int fdt_fixup_memory(void *blob, u64 start, u64 size); +int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks); void fdt_fixup_ethernet(void *fdt); int fdt_find_and_setprop(void *fdt, const char *node, const char *prop, const void *val, int len, int create);

Dear John Rigby,
In message 1286999857-13790-4-git-send-email-john.rigby@linaro.org you wrote:
Add fdt_fixup_memory_banks and reimplement fdt_fixup_memory using it. Tested on OMAP3 beagle board with two banks of memory.
Signed-off-by: John Rigby john.rigby@linaro.org CC: Jerry Van Baren vanbaren@cideas.com
common/fdt_support.c | 86 ++++++++++++++++++++++++++----------------------- include/fdt_support.h | 1 + 2 files changed, 47 insertions(+), 40 deletions(-)
Applied to u-boot-arm, thanks.
Best regards,
Wolfgang Denk

Commit a6bd9e8 "FDT: Add fixup support for multiple banks of memory" removed code but forgot to remove the variables used by it, resulting in warnings:
fdt_support.c: In function 'fdt_fixup_memory_banks': fdt_support.c:399: warning: unused variable 'sizecell' fdt_support.c:399: warning: unused variable 'addrcell'
Remove the declarations, too.
Signed-off-by: Wolfgang Denk wd@denx.de --- common/fdt_support.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/common/fdt_support.c b/common/fdt_support.c index 90e9097..5829afd 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -396,7 +396,6 @@ int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks) int addr_cell_len, size_cell_len, len; u8 tmp[banks * 8]; int bank; - const u32 *addrcell, *sizecell;
err = fdt_check_header(blob); if (err < 0) {

All arches except nios2 and microblaze call boot_get_fdt from bootm_start in common/cmd_bootm.c.
Having nios2 and microblaze do so as well removes code from their respective do_bootm_linux routines and allows removal of a nasty ifdef from bootm_start.
In the case where boot_get_fdt returns an error bootm_start returns and the platform specific do_bootm_linux routines will never get called.
Also only check argv[3] for an fdt addr if argc > 3 first. This is already the case for nios2.
Signed-off-by: John Rigby john.rigby@linaro.org CC: Scott McNutt smcnutt@psyent.com CC: Michal Simek monstr@monstr.eu CC: Thomas Chou thomas@wytron.com.tw --- arch/microblaze/lib/bootm.c | 14 +++++--------- arch/nios2/lib/bootm.c | 8 +++----- common/cmd_bootm.c | 2 -- 3 files changed, 8 insertions(+), 16 deletions(-)
diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index 8e2c6d8..9f6d6d6 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -46,12 +46,9 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima
char *of_flat_tree = NULL; #if defined(CONFIG_OF_LIBFDT) - ulong of_size = 0; - - /* find flattened device tree */ - ret = boot_get_fdt (flag, argc, argv, images, &of_flat_tree, &of_size); - if (ret) - return 1; + /* did generic code already find a device tree? */ + if (images->ft_len) + of_flat_tree = images->ft_addr; #endif
theKernel = (void (*)(char *, ulong, ulong))images->ep; @@ -64,9 +61,8 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima
show_boot_progress (15);
- if (!(ulong) of_flat_tree) - of_flat_tree = (char *)simple_strtoul (argv[3], NULL, 16); - + if (!of_flat_tree && argc > 3) + of_flat_tree = (char *)simple_strtoul(argv[3], NULL, 16); #ifdef DEBUG printf ("## Transferring control to Linux (at address 0x%08lx) " \ "ramdisk 0x%08lx, FDT 0x%08lx...\n", diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c index 40a4d15..f32be52 100644 --- a/arch/nios2/lib/bootm.c +++ b/arch/nios2/lib/bootm.c @@ -36,11 +36,9 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima ulong initrd_end = images->rd_end; char *of_flat_tree = NULL; #if defined(CONFIG_OF_LIBFDT) - ulong of_size = 0; - - /* find flattened device tree */ - if (boot_get_fdt(flag, argc, argv, images, &of_flat_tree, &of_size)) - return 1; + /* did generic code already find a device tree? */ + if (images->ft_len) + of_flat_tree = images->ft_addr; #endif if (!of_flat_tree && argc > 3) of_flat_tree = (char *)simple_strtoul(argv[3], NULL, 16); diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index db59e6f..25bc39c 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -308,7 +308,6 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] }
#if defined(CONFIG_OF_LIBFDT) -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) /* find flattened device tree */ ret = boot_get_fdt (flag, argc, argv, &images, &images.ft_addr, &images.ft_len); @@ -319,7 +318,6 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
set_working_fdt_addr(images.ft_addr); #endif -#endif }
images.os.start = (ulong)os_hdr;

John Rigby wrote:
All arches except nios2 and microblaze call boot_get_fdt from bootm_start in common/cmd_bootm.c.
Having nios2 and microblaze do so as well removes code from their respective do_bootm_linux routines and allows removal of a nasty ifdef from bootm_start.
In the case where boot_get_fdt returns an error bootm_start returns and the platform specific do_bootm_linux routines will never get called.
Also only check argv[3] for an fdt addr if argc > 3 first. This is already the case for nios2.
Signed-off-by: John Rigby john.rigby@linaro.org CC: Scott McNutt smcnutt@psyent.com CC: Michal Simek monstr@monstr.eu CC: Thomas Chou thomas@wytron.com.tw
arch/microblaze/lib/bootm.c | 14 +++++---------
Acked-by: Michal Simek monstr@monstr.eu

John Rigby wrote:
All arches except nios2 and microblaze call boot_get_fdt from bootm_start in common/cmd_bootm.c.
Having nios2 and microblaze do so as well removes code from their respective do_bootm_linux routines and allows removal of a nasty ifdef from bootm_start.
In the case where boot_get_fdt returns an error bootm_start returns and the platform specific do_bootm_linux routines will never get called.
Also only check argv[3] for an fdt addr if argc > 3 first. This is already the case for nios2.
Signed-off-by: John Rigby john.rigby@linaro.org CC: Scott McNutt smcnutt@psyent.com CC: Michal Simek monstr@monstr.eu CC: Thomas Chou thomas@wytron.com.tw
arch/nios2/lib/bootm.c | 8 +++-----
Tested with/without libfdt support on nios2 board. Tested-by: Thomas Chou thomas@wytron.com.tw

Dear John Rigby,
In message 1286999857-13790-5-git-send-email-john.rigby@linaro.org you wrote:
All arches except nios2 and microblaze call boot_get_fdt from bootm_start in common/cmd_bootm.c.
Having nios2 and microblaze do so as well removes code from their respective do_bootm_linux routines and allows removal of a nasty ifdef from bootm_start.
In the case where boot_get_fdt returns an error bootm_start returns and the platform specific do_bootm_linux routines will never get called.
Also only check argv[3] for an fdt addr if argc > 3 first. This is already the case for nios2.
Signed-off-by: John Rigby john.rigby@linaro.org CC: Scott McNutt smcnutt@psyent.com CC: Michal Simek monstr@monstr.eu CC: Thomas Chou thomas@wytron.com.tw
arch/microblaze/lib/bootm.c | 14 +++++--------- arch/nios2/lib/bootm.c | 8 +++----- common/cmd_bootm.c | 2 -- 3 files changed, 8 insertions(+), 16 deletions(-)
Applied to u-boot-arm, thanks.
Best regards,
Wolfgang Denk

The routines boot_ramdisk_high, boot_get_cmdline and boot_get_kbd are currently enabled by various combinations of CONFIG_M68K, CONFIG_POWERPC and CONFIG_SPARC.
Use CONFIG_SYS_BOOT_<FEATURE> defines instead.
CONFIG_SYS_BOOT_RAMDISK_HIGH CONFIG_SYS_BOOT_GET_CMDLINE CONFIG_SYS_BOOT_GET_KBD
Define these as appropriate in arch/include/asm/config.h files.
Signed-off-by: John Rigby john.rigby@linaro.org --- README | 13 +++++++++++++ arch/m68k/include/asm/config.h | 3 +++ arch/powerpc/include/asm/config.h | 3 +++ arch/sparc/include/asm/config.h | 1 + common/cmd_bootm.c | 4 ++-- common/image.c | 10 ++++++---- include/image.h | 9 ++++++--- 7 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/README b/README index 197804e..686c6b7 100644 --- a/README +++ b/README @@ -2275,6 +2275,19 @@ Configuration Settings: all data for the Linux kernel must be between "bootm_low" and "bootm_low" + CONFIG_SYS_BOOTMAPSZ.
+- CONFIG_SYS_BOOT_RAMDISK_HIGH: + Enable initrd_high functionality. If defined then the + initrd_high feature is enabled and the bootm ramdisk subcommand + is enabled. + +- CONFIG_SYS_BOOT_GET_CMDLINE: + Enables allocating and saving kernel cmdline in space between + "bootm_low" and "bootm_low" + BOOTMAPSZ. + +- CONFIG_SYS_BOOT_GET_KBD: + Enables allocating and saving a kernel copy of the bd_info in + space between "bootm_low" and "bootm_low" + BOOTMAPSZ. + - CONFIG_SYS_MAX_FLASH_BANKS: Max number of Flash memory banks
diff --git a/arch/m68k/include/asm/config.h b/arch/m68k/include/asm/config.h index 36438be..ec2cc16 100644 --- a/arch/m68k/include/asm/config.h +++ b/arch/m68k/include/asm/config.h @@ -22,5 +22,8 @@ #define _ASM_CONFIG_H_
#define CONFIG_LMB +#define CONFIG_SYS_BOOT_RAMDISK_HIGH +#define CONFIG_SYS_BOOT_GET_CMDLINE +#define CONFIG_SYS_BOOT_GET_KBD
#endif diff --git a/arch/powerpc/include/asm/config.h b/arch/powerpc/include/asm/config.h index d098657..a1942ca 100644 --- a/arch/powerpc/include/asm/config.h +++ b/arch/powerpc/include/asm/config.h @@ -22,6 +22,9 @@ #define _ASM_CONFIG_H_
#define CONFIG_LMB +#define CONFIG_SYS_BOOT_RAMDISK_HIGH +#define CONFIG_SYS_BOOT_GET_CMDLINE +#define CONFIG_SYS_BOOT_GET_KBD
#ifndef CONFIG_MAX_MEM_MAPPED #if defined(CONFIG_4xx) || defined(CONFIG_E500) || defined(CONFIG_MPC86xx) diff --git a/arch/sparc/include/asm/config.h b/arch/sparc/include/asm/config.h index 36438be..6ddc349 100644 --- a/arch/sparc/include/asm/config.h +++ b/arch/sparc/include/asm/config.h @@ -22,5 +22,6 @@ #define _ASM_CONFIG_H_
#define CONFIG_LMB +#define CONFIG_SYS_BOOT_RAMDISK_HIGH
#endif diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 25bc39c..ce3c77c 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -472,7 +472,7 @@ static int bootm_start_standalone(ulong iflag, int argc, char * const argv[]) static cmd_tbl_t cmd_bootm_sub[] = { U_BOOT_CMD_MKENT(start, 0, 1, (void *)BOOTM_STATE_START, "", ""), U_BOOT_CMD_MKENT(loados, 0, 1, (void *)BOOTM_STATE_LOADOS, "", ""), -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH U_BOOT_CMD_MKENT(ramdisk, 0, 1, (void *)BOOTM_STATE_RAMDISK, "", ""), #endif #ifdef CONFIG_OF_LIBFDT @@ -528,7 +528,7 @@ int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); break; -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH case BOOTM_STATE_RAMDISK: { ulong rd_len = images.rd_end - images.rd_start; diff --git a/common/image.c b/common/image.c index dda3025..385464d 100644 --- a/common/image.c +++ b/common/image.c @@ -992,7 +992,7 @@ int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images, return 0; }
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH /** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1081,7 +1081,7 @@ int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, error: return -1; } -#endif /* defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) */ +#endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */
#ifdef CONFIG_OF_LIBFDT static void fdt_error (const char *msg) @@ -1588,7 +1588,7 @@ error: } #endif /* CONFIG_OF_LIBFDT */
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +#ifdef CONFIG_SYS_BOOT_GET_CMDLINE /** * boot_get_cmdline - allocate and initialize kernel cmdline * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1630,7 +1630,9 @@ int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
return 0; } +#endif /* CONFIG_SYS_BOOT_GET_CMDLINE */
+#ifdef CONFIG_SYS_BOOT_GET_KBD /** * boot_get_kbd - allocate and initialize kernel copy of board info * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1663,7 +1665,7 @@ int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base)
return 0; } -#endif /* CONFIG_PPC || CONFIG_M68K */ +#endif /* CONFIG_SYS_BOOT_GET_KBD */ #endif /* !USE_HOSTCC */
#if defined(CONFIG_FIT) diff --git a/include/image.h b/include/image.h index 18a9f0e..49d6280 100644 --- a/include/image.h +++ b/include/image.h @@ -340,14 +340,17 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, char **of_flat_tree, ulong *of_size); #endif
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH 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); +#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); -#endif /* CONFIG_PPC || CONFIG_M68K */ +#endif /* CONFIG_SYS_BOOT_GET_KBD */ #endif /* !USE_HOSTCC */
/*******************************************************************/

Dear John Rigby,
In message 1286999857-13790-6-git-send-email-john.rigby@linaro.org you wrote:
The routines boot_ramdisk_high, boot_get_cmdline and boot_get_kbd are currently enabled by various combinations of CONFIG_M68K, CONFIG_POWERPC and CONFIG_SPARC.
Use CONFIG_SYS_BOOT_<FEATURE> defines instead.
CONFIG_SYS_BOOT_RAMDISK_HIGH CONFIG_SYS_BOOT_GET_CMDLINE CONFIG_SYS_BOOT_GET_KBD
Define these as appropriate in arch/include/asm/config.h files.
Signed-off-by: John Rigby john.rigby@linaro.org
README | 13 +++++++++++++ arch/m68k/include/asm/config.h | 3 +++ arch/powerpc/include/asm/config.h | 3 +++ arch/sparc/include/asm/config.h | 1 + common/cmd_bootm.c | 4 ++-- common/image.c | 10 ++++++---- include/image.h | 9 ++++++--- 7 files changed, 34 insertions(+), 9 deletions(-)
Applied to u-boot-arm, thanks.
Best regards,
Wolfgang Denk

Based on other architectures already supported. Tested on OMAP3 Beagle board and another unnamed ARM platform.
Signed-off-by: John Rigby john.rigby@linaro.org Tested-by: Rob Herring rob.herring@smooth-stone.com --- arch/arm/include/asm/config.h | 2 + arch/arm/lib/bootm.c | 137 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 123 insertions(+), 16 deletions(-)
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index 4e8dfd7..d8e33fc 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -25,4 +25,6 @@ /* Relocation to SDRAM works on all ARM boards */ #define CONFIG_RELOC_FIXUP_WORKS #endif +#define CONFIG_LMB +#define CONFIG_SYS_BOOT_RAMDISK_HIGH #endif diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 3101321..2e7b2e1 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -26,6 +26,9 @@ #include <image.h> #include <u-boot/zlib.h> #include <asm/byteorder.h> +#include <fdt.h> +#include <libfdt.h> +#include <fdt_support.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -50,12 +53,52 @@ static void setup_end_tag (bd_t *bd); static struct tag *params; #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
-int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) +static ulong get_sp(void); +#if defined(CONFIG_OF_LIBFDT) +static int bootm_linux_fdt(int machid, bootm_headers_t *images); +#endif + +void arch_lmb_reserve(struct lmb *lmb) +{ + ulong sp; + + /* + * Booting a (Linux) kernel image + * + * Allocate space for command line and board info - the + * address should be as high as possible within the reach of + * the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused + * memory, which means far enough below the current stack + * pointer. + */ + sp = get_sp(); + debug("## Current stack ends at 0x%08lx ", sp); + + /* adjust sp by 1K to be safe */ + sp -= 1024; + lmb_reserve(lmb, sp, + gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp); +} + +static void announce_and_cleanup(void) +{ + printf("\nStarting kernel ...\n\n"); + +#ifdef CONFIG_USB_DEVICE + { + extern void udc_disconnect(void); + udc_disconnect(); + } +#endif + cleanup_before_linux(); +} + +int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { bd_t *bd = gd->bd; char *s; int machid = bd->bi_arch_number; - void (*theKernel)(int zero, int arch, uint params); + void (*kernel_entry)(int zero, int arch, uint params);
#ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); @@ -64,8 +107,6 @@ 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;
- theKernel = (void (*)(int, int, uint))images->ep; - s = getenv ("machid"); if (s) { machid = simple_strtoul (s, NULL, 16); @@ -74,8 +115,15 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima
show_boot_progress (15);
+#ifdef CONFIG_OF_LIBFDT + if (images->ft_len) + return bootm_linux_fdt(machid, images); +#endif + + kernel_entry = (void (*)(int, int, uint))images->ep; + debug ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) theKernel); + (ulong) kernel_entry);
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ @@ -99,27 +147,76 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima if (images->rd_start && images->rd_end) setup_initrd_tag (bd, images->rd_start, images->rd_end); #endif - setup_end_tag (bd); + setup_end_tag(bd); #endif
- /* we assume that the kernel is in place */ - printf ("\nStarting kernel ...\n\n"); + announce_and_cleanup();
-#ifdef CONFIG_USB_DEVICE - { - extern void udc_disconnect (void); - udc_disconnect (); + kernel_entry(0, machid, bd->bi_boot_params); + /* does not return */ + + return 1; +} + +#if defined(CONFIG_OF_LIBFDT) +static int fixup_memory_node(void *blob) +{ + bd_t *bd = gd->bd; + int bank; + u64 start[CONFIG_NR_DRAM_BANKS]; + u64 size[CONFIG_NR_DRAM_BANKS]; + + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + start[bank] = bd->bi_dram[bank].start; + size[bank] = bd->bi_dram[bank].size; } -#endif
- cleanup_before_linux (); + return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); +} + +static int bootm_linux_fdt(int machid, bootm_headers_t *images) +{ + ulong rd_len; + bd_t *bd = gd->bd; + char *s; + 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; + ulong *initrd_end = &images->initrd_end; + struct lmb *lmb = &images->lmb; + int ret; + + kernel_entry = (void (*)(int, int, void *))images->ep; + + rd_len = images->rd_end - images->rd_start; + ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, + initrd_start, initrd_end); + if (ret) + return ret; + + ret = boot_relocate_fdt(lmb, bootmap_base, of_flat_tree, &of_size); + if (ret) + return ret;
- theKernel (0, machid, bd->bi_boot_params); + debug("## Transferring control to Linux (at address %08lx) ...\n", + (ulong) kernel_entry); + + fdt_chosen(*of_flat_tree, 1); + + fixup_memory_node(*of_flat_tree); + + fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1); + + announce_and_cleanup(); + + kernel_entry(0, machid, *of_flat_tree); /* does not return */
return 1; } - +#endif
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ @@ -239,4 +336,12 @@ static void setup_end_tag (bd_t *bd) params->hdr.size = 0; }
+static ulong get_sp(void) +{ + ulong ret; + + asm("mov %0, sp" : "=r"(ret) : ); + return ret; +} + #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */

Dear John Rigby,
In message 1286999857-13790-7-git-send-email-john.rigby@linaro.org you wrote:
Based on other architectures already supported. Tested on OMAP3 Beagle board and another unnamed ARM platform.
Signed-off-by: John Rigby john.rigby@linaro.org Tested-by: Rob Herring rob.herring@smooth-stone.com
arch/arm/include/asm/config.h | 2 + arch/arm/lib/bootm.c | 137 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 123 insertions(+), 16 deletions(-)
Applied to u-boot-arm, thanks.
Best regards,
Wolfgang Denk

For testing ARM device tree support
Signed-off-by: John Rigby john.rigby@linaro.org --- include/configs/omap3_beagle.h | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h index 2463be4..daf84c7 100644 --- a/include/configs/omap3_beagle.h +++ b/include/configs/omap3_beagle.h @@ -55,6 +55,15 @@ #undef CONFIG_USE_IRQ /* no support for IRQs */ #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 #define CONFIG_INITRD_TAG 1

Dear John Rigby,
In message 1286999857-13790-8-git-send-email-john.rigby@linaro.org you wrote:
For testing ARM device tree support
Signed-off-by: John Rigby john.rigby@linaro.org
include/configs/omap3_beagle.h | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-)
Applied to u-boot-arm, thanks.
Best regards,
Wolfgang Denk
participants (5)
-
Gerald Van Baren
-
John Rigby
-
Michal Simek
-
Thomas Chou
-
Wolfgang Denk