command: Remove the cmd_tbl_t typedef
[oweals/u-boot.git] / arch / arm / lib / bootm.c
index 5c62d9c144061aa888730a3dda682042e77a4208..0facd0c989385e2145f6e3cde1a3bb490e304028 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /* Copyright (C) 2011
  * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
  *  - Added prep subcommand support
@@ -8,18 +9,21 @@
  * Marius Groeger <mgroeger@sysgo.de>
  *
  * Copyright (C) 2001  Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
+#include <bootstage.h>
 #include <command.h>
+#include <cpu_func.h>
 #include <dm.h>
+#include <hang.h>
+#include <lmb.h>
 #include <dm/root.h>
+#include <env.h>
 #include <image.h>
 #include <u-boot/zlib.h>
 #include <asm/byteorder.h>
-#include <libfdt.h>
+#include <linux/libfdt.h>
 #include <mapmem.h>
 #include <fdt_support.h>
 #include <asm/bootm.h>
@@ -27,6 +31,7 @@
 #include <linux/compiler.h>
 #include <bootm.h>
 #include <vxworks.h>
+#include <asm/cache.h>
 
 #ifdef CONFIG_ARMV7_NONSEC
 #include <asm/armv7.h>
@@ -47,7 +52,8 @@ static ulong get_sp(void)
 
 void arch_lmb_reserve(struct lmb *lmb)
 {
-       ulong sp;
+       ulong sp, bank_end;
+       int bank;
 
        /*
         * Booting a (Linux) kernel image
@@ -63,8 +69,21 @@ void arch_lmb_reserve(struct lmb *lmb)
 
        /* adjust sp by 4K to be safe */
        sp -= 4096;
-       lmb_reserve(lmb, sp,
-                   gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp);
+       for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
+               if (!gd->bd->bi_dram[bank].size ||
+                   sp < gd->bd->bi_dram[bank].start)
+                       continue;
+               /* Watch out for RAM at end of address space! */
+               bank_end = gd->bd->bi_dram[bank].start +
+                       gd->bd->bi_dram[bank].size - 1;
+               if (sp > bank_end)
+                       continue;
+               if (bank_end > gd->ram_top)
+                       bank_end = gd->ram_top - 1;
+
+               lmb_reserve(lmb, sp, bank_end - sp + 1);
+               break;
+       }
 }
 
 __weak void board_quiesce_devices(void)
@@ -78,8 +97,6 @@ __weak void board_quiesce_devices(void)
  */
 static void announce_and_cleanup(int fake)
 {
-       printf("\nStarting kernel ...%s\n\n", fake ?
-               "(fake run for tracing)" : "");
        bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
 #ifdef CONFIG_BOOTSTAGE_FDT
        bootstage_fdt_add_report();
@@ -94,6 +111,8 @@ static void announce_and_cleanup(int fake)
 
        board_quiesce_devices();
 
+       printf("\nStarting kernel ...%s\n\n", fake ?
+               "(fake run for tracing)" : "");
        /*
         * Call remove function of all devices with a removal flag set.
         * This may be useful for last-stage operations, like cancelling
@@ -213,6 +232,8 @@ static void do_nonsec_virt_switch(void)
 }
 #endif
 
+__weak void board_prep_linux(bootm_headers_t *images) { }
+
 /* Subcommand: PREP */
 static void boot_prep_linux(bootm_headers_t *images)
 {
@@ -259,6 +280,8 @@ static void boot_prep_linux(bootm_headers_t *images)
                printf("FDT and ATAGS support not compiled in - hanging\n");
                hang();
        }
+
+       board_prep_linux(images);
 }
 
 __weak bool armv7_boot_nonsec_default(void)
@@ -399,7 +422,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
  * DIFFERENCE: Instead of calling prep and go at the end
  * they are called if subcommand is equal 0.
  */
-int do_bootm_linux(int flag, int argc, char * const argv[],
+int do_bootm_linux(int flag, int argc, char *const argv[],
                   bootm_headers_t *images)
 {
        /* No need for those on ARM */
@@ -429,7 +452,7 @@ void boot_prep_vxworks(bootm_headers_t *images)
 
        if (images->ft_addr) {
                off = fdt_path_offset(images->ft_addr, "/memory");
-               if (off < 0) {
+               if (off > 0) {
                        if (arch_fixup_fdt(images->ft_addr))
                                puts("## WARNING: fixup memory failed!\n");
                }
@@ -439,6 +462,11 @@ void boot_prep_vxworks(bootm_headers_t *images)
 }
 void boot_jump_vxworks(bootm_headers_t *images)
 {
+#if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI)
+       armv8_setup_psci();
+       smp_kick_all_cpus();
+#endif
+
        /* ARM VxWorks requires device tree physical address to be passed */
        ((void (*)(void *))images->ep)(images->ft_addr);
 }