[U-Boot] [PATCH 0/3] MIPS: rework and fix broken bootm code

I recently discovered that booting Linux with FIT images containg initramfs or DTB images do not work anymore. That is a regression by the move to 'generic board' which broke LMB on MIPS. Also the MIPS DTB support was not compatible anymore with some changes made in the generic bootm code.
Daniel Schwierzeck (3): common/board_f: enable setup_board_part1() for MIPS MIPS: bootm: rework and fix broken bootm code MIPS: bootm: use CONFIG_IS_ENABLED() everywhere
arch/mips/lib/bootm.c | 196 ++++++++++++++++++++++++-------------------------- common/board_f.c | 8 ++- 2 files changed, 98 insertions(+), 106 deletions(-)

The variables bd_t:bi_memstart and bd_t:bi_memsize have to be initialized also on MIPS. Otherwise LMB and cmd_bdinfo do not correctly work. This currently breaks the booting of FIT images on MIPS. Enable the board_init_f hook setup_board_part1() for MIPS to fix this.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
---
common/board_f.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/common/board_f.c b/common/board_f.c index 7632041..a12ac28 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -551,7 +551,7 @@ static int display_new_sp(void) return 0; }
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) static int setup_board_part1(void) { bd_t *bd = gd->bd; @@ -580,7 +580,9 @@ static int setup_board_part1(void)
return 0; } +#endif
+#if defined(CONFIG_PPC) || defined(CONFIG_M68K) static int setup_board_part2(void) { bd_t *bd = gd->bd; @@ -933,8 +935,10 @@ static init_fnc_t init_sequence_f[] = { reserve_stacks, setup_dram_config, show_dram_config, -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) setup_board_part1, +#endif +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) INIT_FUNC_WATCHDOG_RESET setup_board_part2, #endif

On Sun, Nov 01, 2015 at 05:36:13PM +0100, Daniel Schwierzeck wrote:
The variables bd_t:bi_memstart and bd_t:bi_memsize have to be initialized also on MIPS. Otherwise LMB and cmd_bdinfo do not correctly work. This currently breaks the booting of FIT images on MIPS. Enable the board_init_f hook setup_board_part1() for MIPS to fix this.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
Reviewed-by: Tom Rini trini@konsulko.com

On 2 November 2015 at 16:37, Tom Rini trini@konsulko.com wrote:
On Sun, Nov 01, 2015 at 05:36:13PM +0100, Daniel Schwierzeck wrote:
The variables bd_t:bi_memstart and bd_t:bi_memsize have to be initialized also on MIPS. Otherwise LMB and cmd_bdinfo do not correctly work. This currently breaks the booting of FIT images on MIPS. Enable the board_init_f hook setup_board_part1() for MIPS to fix this.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
Reviewed-by: Tom Rini trini@konsulko.com
Reviewed-by: Simon Glass sjg@chromium.org

The move to 'generic board' as well as changes in the generic bootm code broke the boot of FIT uImage's. Especially uImage's with additional initramfs images or FDT's do not work anymore.
Refactor the bootm code to work again with the generic bootm code.
Always relocate ramdisk and FDT in step 'bootm prep' because the generic bootm code does this only for legacy uImage's.
Move the step 'bootm cmdline' to 'bootm prep' because the Linux kernel parameters rd_start and rd_size have to be initialized after the relocation of the ramdisk.
Furthermore support the step 'bootm fake'.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
---
arch/mips/lib/bootm.c | 163 ++++++++++++++++++++++++-------------------------- 1 file changed, 78 insertions(+), 85 deletions(-)
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index 9c647aa..a7eddd3 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -21,18 +21,6 @@ DECLARE_GLOBAL_DATA_PTR; #define mips_boot_malta 0 #endif
-#if defined(CONFIG_MIPS_BOOT_CMDLINE_LEGACY) -#define mips_boot_cmdline_legacy 1 -#else -#define mips_boot_cmdline_legacy 0 -#endif - -#if defined(CONFIG_MIPS_BOOT_ENV_LEGACY) -#define mips_boot_env_legacy 1 -#else -#define mips_boot_env_legacy 0 -#endif - static int linux_argc; static char **linux_argv; static char *linux_argp; @@ -62,50 +50,6 @@ void arch_lmb_reserve(struct lmb *lmb) lmb_reserve(lmb, sp, CONFIG_SYS_SDRAM_BASE + gd->ram_size - sp); }
-static int boot_setup_linux(bootm_headers_t *images) -{ - int ret; - ulong rd_len; - - rd_len = images->rd_end - images->rd_start; - ret = boot_ramdisk_high(&images->lmb, images->rd_start, - rd_len, &images->initrd_start, &images->initrd_end); - if (ret) - return ret; - -#if defined(CONFIG_MIPS_BOOT_FDT) && defined(CONFIG_OF_LIBFDT) - if (images->ft_len) { - boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr); - - ret = boot_relocate_fdt(&images->lmb, &images->ft_addr, - &images->ft_len); - if (ret) - return ret; - } -#endif - - return 0; -} - -static void boot_setup_fdt(bootm_headers_t *images) -{ -#if defined(CONFIG_MIPS_BOOT_FDT) && defined(CONFIG_OF_LIBFDT) - u64 mem_start = 0; - u64 mem_size = gd->ram_size; - - debug("## setup FDT\n"); - - fdt_chosen(images->ft_addr); - fdt_fixup_memory_banks(images->ft_addr, &mem_start, &mem_size, 1); - fdt_fixup_ethernet(images->ft_addr); - fdt_initrd(images->ft_addr, images->initrd_start, images->initrd_end); - -#if defined(CONFIG_OF_BOARD_SETUP) - ft_board_setup(images->ft_addr, gd->bd); -#endif -#endif -} - static void linux_cmdline_init(void) { linux_argc = 1; @@ -197,18 +141,6 @@ static void linux_cmdline_append(bootm_headers_t *images) } }
-static void boot_cmdline_linux(bootm_headers_t *images) -{ - if (mips_boot_cmdline_legacy && !images->ft_len) { - linux_cmdline_legacy(images); - - if (!mips_boot_env_legacy) - linux_cmdline_append(images); - - linux_cmdline_dump(); - } -} - static void linux_env_init(void) { linux_env = (char **)(((ulong) linux_argp + 15) & ~15); @@ -288,13 +220,81 @@ static void linux_env_legacy(bootm_headers_t *images) } }
+static int boot_reloc_ramdisk(bootm_headers_t *images) +{ + ulong rd_len = images->rd_end - images->rd_start; + + /* + * In case of legacy uImage's, relocation of ramdisk is already done + * by do_bootm_states() and should not repeated in 'bootm prep'. + */ + if (images->state & BOOTM_STATE_RAMDISK) { + debug("## Ramdisk already relocated\n"); + return 0; + } + + return boot_ramdisk_high(&images->lmb, images->rd_start, + rd_len, &images->initrd_start, &images->initrd_end); +} + +static int boot_reloc_fdt(bootm_headers_t *images) +{ + /* + * In case of legacy uImage's, relocation of FDT is already done + * by do_bootm_states() and should not repeated in 'bootm prep'. + */ + if (images->state & BOOTM_STATE_FDT) { + debug("## FDT already relocated\n"); + return 0; + } + +#if CONFIG_IS_ENABLED(MIPS_BOOT_FDT) && CONFIG_IS_ENABLED(OF_LIBFDT) + boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr); + return boot_relocate_fdt(&images->lmb, &images->ft_addr, + &images->ft_len); +#else + return 0; +#endif +} + +int arch_fixup_memory_node(void *blob) +{ +#if CONFIG_IS_ENABLED(MIPS_BOOT_FDT) && CONFIG_IS_ENABLED(OF_LIBFDT) + u64 mem_start = 0; + u64 mem_size = gd->ram_size; + + return fdt_fixup_memory_banks(blob, &mem_start, &mem_size, 1); +#else + return 0; +#endif +} + +static int boot_setup_fdt(bootm_headers_t *images) +{ + return image_setup_libfdt(images, images->ft_addr, images->ft_len, + &images->lmb); +} + static void boot_prep_linux(bootm_headers_t *images) { - if (mips_boot_env_legacy && !images->ft_len) - linux_env_legacy(images); + boot_reloc_ramdisk(images);
- if (images->ft_len) + if (CONFIG_IS_ENABLED(MIPS_BOOT_FDT) && images->ft_len) { + boot_reloc_fdt(images); boot_setup_fdt(images); + } else { + if (CONFIG_IS_ENABLED(CONFIG_MIPS_BOOT_ENV_LEGACY)) + linux_env_legacy(images); + + if (CONFIG_IS_ENABLED(MIPS_BOOT_CMDLINE_LEGACY)) { + linux_cmdline_legacy(images); + + if (!CONFIG_IS_ENABLED(CONFIG_MIPS_BOOT_ENV_LEGACY)) + linux_cmdline_append(images); + + linux_cmdline_dump(); + } + } }
static void boot_jump_linux(bootm_headers_t *images) @@ -327,35 +327,28 @@ static void boot_jump_linux(bootm_headers_t *images) int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) { - int ret; - /* No need for those on MIPS */ if (flag & BOOTM_STATE_OS_BD_T) return -1;
- if (flag & BOOTM_STATE_OS_CMDLINE) { - boot_cmdline_linux(images); + /* + * Cmdline init has been moved to 'bootm prep' because it has to be + * done after relocation of ramdisk to always pass correct values + * for rd_start and rd_size to Linux kernel. + */ + if (flag & BOOTM_STATE_OS_CMDLINE) return 0; - }
if (flag & BOOTM_STATE_OS_PREP) { boot_prep_linux(images); return 0; }
- if (flag & BOOTM_STATE_OS_GO) { + if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { boot_jump_linux(images); return 0; }
- ret = boot_setup_linux(images); - if (ret) - return ret; - - boot_cmdline_linux(images); - boot_prep_linux(images); - boot_jump_linux(images); - /* does not return */ return 1; }

On Sun, Nov 01, 2015 at 05:36:14PM +0100, Daniel Schwierzeck wrote:
The move to 'generic board' as well as changes in the generic bootm code broke the boot of FIT uImage's. Especially uImage's with additional initramfs images or FDT's do not work anymore.
Refactor the bootm code to work again with the generic bootm code.
Always relocate ramdisk and FDT in step 'bootm prep' because the generic bootm code does this only for legacy uImage's.
Move the step 'bootm cmdline' to 'bootm prep' because the Linux kernel parameters rd_start and rd_size have to be initialized after the relocation of the ramdisk.
Furthermore support the step 'bootm fake'.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
Reviewed-by: Tom Rini trini@konsulko.com

On 2 November 2015 at 16:38, Tom Rini trini@konsulko.com wrote:
On Sun, Nov 01, 2015 at 05:36:14PM +0100, Daniel Schwierzeck wrote:
The move to 'generic board' as well as changes in the generic bootm code broke the boot of FIT uImage's. Especially uImage's with additional initramfs images or FDT's do not work anymore.
Refactor the bootm code to work again with the generic bootm code.
Always relocate ramdisk and FDT in step 'bootm prep' because the generic bootm code does this only for legacy uImage's.
Move the step 'bootm cmdline' to 'bootm prep' because the Linux kernel parameters rd_start and rd_size have to be initialized after the relocation of the ramdisk.
Furthermore support the step 'bootm fake'.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
Reviewed-by: Tom Rini trini@konsulko.com
Reviewed-by: Simon Glass sjg@chromium.org

Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
---
arch/mips/lib/bootm.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-)
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index a7eddd3..eed159c 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -15,12 +15,6 @@ DECLARE_GLOBAL_DATA_PTR; #define LINUX_MAX_ENVS 256 #define LINUX_MAX_ARGS 256
-#if defined(CONFIG_MALTA) -#define mips_boot_malta 1 -#else -#define mips_boot_malta 0 -#endif - static int linux_argc; static char **linux_argv; static char *linux_argp; @@ -157,7 +151,7 @@ static void linux_env_set(const char *env_name, const char *env_val) strcpy(linux_env_p, env_name); linux_env_p += strlen(env_name);
- if (mips_boot_malta) { + if (CONFIG_IS_ENABLED(MALTA)) { linux_env_p++; linux_env[++linux_env_idx] = linux_env_p; } else { @@ -178,14 +172,15 @@ static void linux_env_legacy(bootm_headers_t *images) const char *cp; ulong rd_start, rd_size;
-#ifdef CONFIG_MEMSIZE_IN_BYTES - sprintf(env_buf, "%lu", (ulong)gd->ram_size); - debug("## Giving linux memsize in bytes, %lu\n", (ulong)gd->ram_size); -#else - sprintf(env_buf, "%lu", (ulong)(gd->ram_size >> 20)); - debug("## Giving linux memsize in MB, %lu\n", - (ulong)(gd->ram_size >> 20)); -#endif /* CONFIG_MEMSIZE_IN_BYTES */ + if (CONFIG_IS_ENABLED(MEMSIZE_IN_BYTES)) { + sprintf(env_buf, "%lu", (ulong)gd->ram_size); + debug("## Giving linux memsize in bytes, %lu\n", + (ulong)gd->ram_size); + } else { + sprintf(env_buf, "%lu", (ulong)(gd->ram_size >> 20)); + debug("## Giving linux memsize in MB, %lu\n", + (ulong)(gd->ram_size >> 20)); + }
rd_start = UNCACHED_SDRAM(images->initrd_start); rd_size = images->initrd_end - images->initrd_start; @@ -214,7 +209,7 @@ static void linux_env_legacy(bootm_headers_t *images) if (cp) linux_env_set("eth1addr", cp);
- if (mips_boot_malta) { + if (CONFIG_IS_ENABLED(MALTA)) { sprintf(env_buf, "%un8r", gd->baudrate); linux_env_set("modetty0", env_buf); } @@ -307,13 +302,13 @@ static void boot_jump_linux(bootm_headers_t *images)
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
- if (mips_boot_malta) + if (CONFIG_IS_ENABLED(MALTA)) linux_extra = gd->ram_size;
-#ifdef CONFIG_BOOTSTAGE_FDT +#if CONFIG_IS_ENABLED(BOOTSTAGE_FDT) bootstage_fdt_add_report(); #endif -#ifdef CONFIG_BOOTSTAGE_REPORT +#if CONFIG_IS_ENABLED(BOOTSTAGE_REPORT) bootstage_report(); #endif

On Sun, Nov 01, 2015 at 05:36:15PM +0100, Daniel Schwierzeck wrote:
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
Reviewed-by: Tom Rini trini@konsulko.com
participants (3)
-
Daniel Schwierzeck
-
Simon Glass
-
Tom Rini