summaryrefslogtreecommitdiff
path: root/arch/microblaze/lib
diff options
context:
space:
mode:
authorMichal Simek <michal.simek@xilinx.com>2019-09-25 09:47:02 +0200
committerMichal Simek <michal.simek@xilinx.com>2019-10-08 09:55:11 +0200
commit0905046050b041784869762824f6266c593fec67 (patch)
tree69a24ed41b89648de8493fe9765a759e3a2c8777 /arch/microblaze/lib
parent6131a36be6f046c1db044fdf449436fbe3fa8d21 (diff)
microblaze: Switch to generic bootm implementation
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>
Diffstat (limited to 'arch/microblaze/lib')
-rw-r--r--arch/microblaze/lib/bootm.c105
1 files changed, 52 insertions, 53 deletions
diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c
index a74f1d1e55..11e534715d 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;
}