[U-Boot] [PATCH 00/10] microblaze: External initrd support

Hi,
Microblaze is not changing a lot but there was a real pain for not supporting external initrd. That's why several patches in the series are fixing this issue. The rest of patches are just cleanup which I found when I was trying to fix it.
Thanks, Michal
Michal Simek (10): microblaze: Remove unused variable ram_base microblaze: Move CONFIG_LMB from board file to config.h microblaze: Fix lmb memory initialization microblaze: Define arch_lmb_reserve microblaze: Switch to generic bootm implementation microblaze: Enable cache by default microblaze: Setup reasonable maximum bootm len microblaze: Setup initrd_high and fdt_high at run time microblaze: Remove additional headers microblaze: Enable random mac generation
arch/microblaze/Kconfig | 8 ++ arch/microblaze/include/asm/config.h | 4 + arch/microblaze/lib/bootm.c | 136 +++++++++++------- .../microblaze-generic/microblaze-generic.c | 28 ++-- common/image.c | 5 +- configs/microblaze-generic_defconfig | 2 + include/configs/microblaze-generic.h | 8 +- 7 files changed, 129 insertions(+), 62 deletions(-)

This variable is completely unused that's why remove it.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
board/xilinx/microblaze-generic/microblaze-generic.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index ba82292e35ac..4e038ddf0cc7 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -24,8 +24,6 @@
DECLARE_GLOBAL_DATA_PTR;
-ulong ram_base; - int dram_init_banksize(void) { return fdtdec_setup_memory_banksize();

It is common for the whole architecture that's why move it there.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/microblaze/include/asm/config.h | 2 ++ include/configs/microblaze-generic.h | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/microblaze/include/asm/config.h b/arch/microblaze/include/asm/config.h index 45966eef9127..d522669f6660 100644 --- a/arch/microblaze/include/asm/config.h +++ b/arch/microblaze/include/asm/config.h @@ -6,6 +6,8 @@ #ifndef _ASM_CONFIG_H_ #define _ASM_CONFIG_H_
+#define CONFIG_LMB + #ifndef CONFIG_SPL_BUILD #define CONFIG_NEEDS_MANUAL_RELOC #endif diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 814fec5b330f..f66f63e07491 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -152,9 +152,6 @@ "setenv stdin serial\0" #endif
-/* Enable flat device tree support */ -#define CONFIG_LMB 1 - #if defined(CONFIG_XILINX_AXIEMAC) # define CONFIG_SYS_FAULT_ECHO_LINK_DOWN 1 #endif

Microblaze as Arm is using multiple memory banks which are read from DT that's why there is a need to initialized LMB based on bd->bi_dram[]. Without this fix memory base/size is all the time 0 and image relocation is not possible.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
common/image.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/common/image.c b/common/image.c index 179eef0bd2dc..fc0ebe338bd8 100644 --- a/common/image.c +++ b/common/image.c @@ -582,7 +582,7 @@ ulong env_get_bootm_low(void)
#if defined(CONFIG_SYS_SDRAM_BASE) return CONFIG_SYS_SDRAM_BASE; -#elif defined(CONFIG_ARM) +#elif defined(CONFIG_ARM) || defined(CONFIG_MICROBLAZE) return gd->bd->bi_dram[0].start; #else return 0; @@ -599,7 +599,8 @@ phys_size_t env_get_bootm_size(void) return tmp; }
-#if defined(CONFIG_ARM) && defined(CONFIG_NR_DRAM_BANKS) +#if (defined(CONFIG_ARM) || defined(CONFIG_MICROBLAZE)) && \ + defined(CONFIG_NR_DRAM_BANKS) start = gd->bd->bi_dram[0].start; size = gd->bd->bi_dram[0].size; #else

arch_lmb_reserve() protects U-Boot relocated code with stack not to be used for image relocation.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/microblaze/lib/bootm.c | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)
diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index ec332944d8e8..a74f1d1e559c 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -15,6 +15,47 @@ #include <u-boot/zlib.h> #include <asm/byteorder.h>
+DECLARE_GLOBAL_DATA_PTR; + +static ulong get_sp(void) +{ + ulong ret; + + asm("addik %0, r1, 0" : "=r"(ret) : ); + return ret; +} + +void arch_lmb_reserve(struct lmb *lmb) +{ + ulong sp, bank_end; + int bank; + + /* + * 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 4K to be safe */ + sp -= 4096; + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + if (sp < gd->bd->bi_dram[bank].start) + continue; + bank_end = gd->bd->bi_dram[bank].start + + gd->bd->bi_dram[bank].size; + if (sp >= bank_end) + continue; + lmb_reserve(lmb, sp, bank_end - sp); + break; + } +} + int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) {

There is no reason to use private code for standard bootm command. Current implementation is also broken and don't support image relocation properly. Switching to generic bootm implementation is fixing these issues.
cmdline and bdt bootm subcommands are returning -1 because they are not implemented.
Similar change was done long time ago by for example commit 2bb5b638791d ("MIPS: bootm: rework and fix broken bootm code")
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/microblaze/include/asm/config.h | 2 + arch/microblaze/lib/bootm.c | 105 +++++++++++++-------------- 2 files changed, 54 insertions(+), 53 deletions(-)
diff --git a/arch/microblaze/include/asm/config.h b/arch/microblaze/include/asm/config.h index d522669f6660..112427291526 100644 --- a/arch/microblaze/include/asm/config.h +++ b/arch/microblaze/include/asm/config.h @@ -12,4 +12,6 @@ #define CONFIG_NEEDS_MANUAL_RELOC #endif
+#define CONFIG_SYS_BOOT_RAMDISK_HIGH + #endif diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index a74f1d1e559c..11e534715d15 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -56,71 +56,70 @@ void arch_lmb_reserve(struct lmb *lmb) } }
-int do_bootm_linux(int flag, int argc, char * const argv[], - bootm_headers_t *images) +static void boot_jump_linux(bootm_headers_t *images, int flag) { - /* First parameter is mapped to $r5 for kernel boot args */ - void (*thekernel) (char *, ulong, ulong); - char *commandline = env_get("bootargs"); - ulong rd_data_start, rd_data_end; - - /* - * allow the PREP bootm subcommand, it is required for bootm to work - */ - if (flag & BOOTM_STATE_OS_PREP) - return 0; - - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; - - int ret; - - char *of_flat_tree = NULL; -#if defined(CONFIG_OF_LIBFDT) - /* did generic code already find a device tree? */ - if (images->ft_len) - of_flat_tree = images->ft_addr; -#endif + void (*thekernel)(char *cmdline, ulong rd, ulong dt); + ulong dt = (ulong)images->ft_addr; + ulong rd_start = images->initrd_start; + ulong cmdline = images->cmdline_start; + int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
thekernel = (void (*)(char *, ulong, ulong))images->ep;
- /* find ramdisk */ - ret = boot_get_ramdisk(argc, argv, images, IH_ARCH_MICROBLAZE, - &rd_data_start, &rd_data_end); - if (ret) - return 1; - - bootstage_mark(BOOTSTAGE_ID_RUN_OS); - - if (!of_flat_tree && argc > 1) - of_flat_tree = (char *)simple_strtoul(argv[1], NULL, 16); - - /* fixup the initrd now that we know where it should be */ - if (images->rd_start && images->rd_end && of_flat_tree) { - ret = fdt_initrd(of_flat_tree, images->rd_start, - images->rd_end); - if (ret) - return 1; - } - #ifdef DEBUG printf("## Transferring control to Linux (at address 0x%08lx) ", (ulong)thekernel); - printf("ramdisk 0x%08lx, FDT 0x%08lx...\n", - rd_data_start, (ulong) of_flat_tree); + printf("cmdline 0x%08lx, ramdisk 0x%08lx, FDT 0x%08lx...\n", + cmdline, rd_start, dt); #endif
#ifdef XILINX_USE_DCACHE flush_cache(0, XILINX_DCACHE_BYTE_SIZE); #endif - /* - * Linux Kernel Parameters (passing device tree): - * r5: pointer to command line - * r6: pointer to ramdisk - * r7: pointer to the fdt, followed by the board info data - */ - thekernel(commandline, rd_data_start, (ulong)of_flat_tree); - /* does not return */
+ if (!fake) { + /* + * Linux Kernel Parameters (passing device tree): + * r5: pointer to command line + * r6: pointer to ramdisk + * r7: pointer to the fdt, followed by the board info data + */ + thekernel((char *)cmdline, rd_start, dt); + /* does not return */ + } +} + +static void boot_prep_linux(bootm_headers_t *images) +{ + if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) { + printf("using: FDT\n"); + if (image_setup_linux(images)) { + printf("FDT creation failed! hanging..."); + hang(); + } + } +} + +int do_bootm_linux(int flag, int argc, char * const argv[], + bootm_headers_t *images) +{ + images->cmdline_start = (ulong)env_get("bootargs"); + + /* cmdline init is the part of 'prep' and nothing to do for 'bdt' */ + if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) + return -1; + + if (flag & BOOTM_STATE_OS_PREP) { + boot_prep_linux(images); + return 0; + } + + if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { + boot_jump_linux(images, flag); + return 0; + } + + boot_prep_linux(images); + boot_jump_linux(images, flag); return 1; }

The whole cache code needs to be redesign to read information about cache from DT instead of macro selection. Enable caches by default because systems have caches on by default for Linux.
Also enable CMD_CACHE to be able to disable cache if there is any issue.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
configs/microblaze-generic_defconfig | 1 + include/configs/microblaze-generic.h | 3 +++ 2 files changed, 4 insertions(+)
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 819441006b88..5eaf18f5f951 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -34,6 +34,7 @@ CONFIG_CMD_DHCP=y CONFIG_CMD_TFTPPUT=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y CONFIG_CMD_JFFS2=y CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index f66f63e07491..ce18ee73c2bc 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -100,6 +100,9 @@ #endif /* !SPIFLASH */ #endif /* !FLASH */
+#define XILINX_USE_ICACHE 1 +#define XILINX_USE_DCACHE 1 + #if defined(XILINX_USE_ICACHE) # define CONFIG_ICACHE #else

We are far from 8MB default size. Setup 64MB for now.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
include/configs/microblaze-generic.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index ce18ee73c2bc..f1d0def3c163 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -13,6 +13,8 @@ /* MicroBlaze CPU */ #define MICROBLAZE_V5 1
+#define CONFIG_SYS_BOOTM_LEN (64 * 1024 * 1024) + /* linear and spi flash memory */ #ifdef XILINX_FLASH_START #define FLASH

Setup initrd_high and fdt_high to be placed in lowmem space for kernel to be able to reach it. Values are setup at run time to ensure that the same setting can be used on different memory setup. Do this setting only when variables are not
Similar run time detection was done for Zynqmp and Versal.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/microblaze/Kconfig | 8 ++++++++ .../microblaze-generic/microblaze-generic.c | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+)
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 5cc68d63c4f7..5ce8261451d3 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -20,6 +20,14 @@ config TARGET_MICROBLAZE_GENERIC
endchoice
+config STACK_SIZE + hex "Define max stack size that can be used by u-boot" + default 0x200000 + help + Defines Max stack size that can be used by u-boot so that the + initrd_high will be calculated as base stack pointer minus this + stack size. + source "board/xilinx/microblaze-generic/Kconfig"
config SPL_LDSCRIPT diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index 4e038ddf0cc7..30be0150f309 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -21,6 +21,7 @@ #include <asm/gpio.h> #include <dm/uclass.h> #include <wdt.h> +#include <linux/sizes.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -39,6 +40,8 @@ int dram_init(void)
int board_late_init(void) { + ulong max_size, lowmem_size; + #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SYSRESET_MICROBLAZE) int ret;
@@ -47,5 +50,21 @@ int board_late_init(void) if (ret) printf("Warning: No reset driver: ret=%d\n", ret); #endif + + if (!(gd->flags & GD_FLG_ENV_DEFAULT)) { + debug("Saved variables - Skipping\n"); + return 0; + } + + max_size = gd->start_addr_sp - CONFIG_STACK_SIZE; + max_size = round_down(max_size, SZ_16M); + + /* Linux default LOWMEM_SIZE is 0x30000000 = 768MB */ + lowmem_size = gd->ram_base + 768 * 1024 * 1024; + + env_set_addr("initrd_high", (void *)min_t(ulong, max_size, + lowmem_size)); + env_set_addr("fdt_high", (void *)min_t(ulong, max_size, lowmem_size)); + return 0; }

There were several changes in past in this file without removing headers (watchdog cleanup, soft reset, etc). That's why remove additional useless headers.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
board/xilinx/microblaze-generic/microblaze-generic.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index 30be0150f309..7e784d10781e 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -12,15 +12,8 @@
#include <common.h> #include <config.h> -#include <dm.h> #include <dm/lists.h> #include <fdtdec.h> -#include <asm/processor.h> -#include <asm/microblaze_intc.h> -#include <asm/asm.h> -#include <asm/gpio.h> -#include <dm/uclass.h> -#include <wdt.h> #include <linux/sizes.h>
DECLARE_GLOBAL_DATA_PTR;

In case that mac address is not found it is generated randomly.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
configs/microblaze-generic_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 5eaf18f5f951..a0a710e1165c 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -39,6 +39,7 @@ CONFIG_CMD_JFFS2=y CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic" +CONFIG_NET_RANDOM_ETHADDR=y CONFIG_NETCONSOLE=y CONFIG_SPL_DM=y CONFIG_XILINX_GPIO=y

st 25. 9. 2019 v 13:42 odesÃlatel Michal Simek michal.simek@xilinx.com napsal:
Hi,
Microblaze is not changing a lot but there was a real pain for not supporting external initrd. That's why several patches in the series are fixing this issue. The rest of patches are just cleanup which I found when I was trying to fix it.
Thanks, Michal
Michal Simek (10): microblaze: Remove unused variable ram_base microblaze: Move CONFIG_LMB from board file to config.h microblaze: Fix lmb memory initialization microblaze: Define arch_lmb_reserve microblaze: Switch to generic bootm implementation microblaze: Enable cache by default microblaze: Setup reasonable maximum bootm len microblaze: Setup initrd_high and fdt_high at run time microblaze: Remove additional headers microblaze: Enable random mac generation
arch/microblaze/Kconfig | 8 ++ arch/microblaze/include/asm/config.h | 4 + arch/microblaze/lib/bootm.c | 136 +++++++++++------- .../microblaze-generic/microblaze-generic.c | 28 ++-- common/image.c | 5 +- configs/microblaze-generic_defconfig | 2 + include/configs/microblaze-generic.h | 8 +- 7 files changed, 129 insertions(+), 62 deletions(-)
-- 2.17.1
Applied all. M
participants (2)
-
Michal Simek
-
Michal Simek