Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / arch / arm / lib / bootm.c
index 91a64bec34cf27a1124ecbe62342c86dc7b68497..2df98d3e01bd8ce175160069452d2429d034fa00 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,14 +9,18 @@
  * 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 <log.h>
 #include <dm/root.h>
+#include <env.h>
 #include <image.h>
 #include <u-boot/zlib.h>
 #include <asm/byteorder.h>
@@ -27,6 +32,7 @@
 #include <linux/compiler.h>
 #include <bootm.h>
 #include <vxworks.h>
+#include <asm/cache.h>
 
 #ifdef CONFIG_ARMV7_NONSEC
 #include <asm/armv7.h>
@@ -65,13 +71,18 @@ void arch_lmb_reserve(struct lmb *lmb)
        /* 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)
+               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;
-               if (sp >= bank_end)
+                       gd->bd->bi_dram[bank].size - 1;
+               if (sp > bank_end)
                        continue;
-               lmb_reserve(lmb, sp, bank_end - sp);
+               if (bank_end > gd->ram_top)
+                       bank_end = gd->ram_top - 1;
+
+               lmb_reserve(lmb, sp, bank_end - sp + 1);
                break;
        }
 }
@@ -87,8 +98,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();
@@ -103,6 +112,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
@@ -222,6 +233,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)
 {
@@ -268,6 +281,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)
@@ -408,7 +423,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 */
@@ -438,7 +453,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");
                }