summary refs log tree commit diff stats
path: root/hw/core/loader.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-12-15 16:58:27 +0000
committerPeter Maydell <peter.maydell@linaro.org>2020-12-15 16:58:27 +0000
commit657ee88ef3ec55c3a6164da88c11a6640ca7507c (patch)
tree294359f1bbb52fa1209247025dc04f2ef7952824 /hw/core/loader.c
parent69e92bd558d71fdbd0c1989391b20edcc700daa9 (diff)
parent23af268566069183285bebbdf95b1b37cb7c0942 (diff)
downloadfocaccia-qemu-657ee88ef3ec55c3a6164da88c11a6640ca7507c.tar.gz
focaccia-qemu-657ee88ef3ec55c3a6164da88c11a6640ca7507c.zip
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20201215' into staging
target-arm queue:
 * gdbstub: Correct misparsing of vCont C/S requests
 * openrisc: Move pic_cpu code into CPU object proper
 * nios2: Move IIC code into CPU object proper
 * Improve reporting of ROM overlap errors
 * xlnx-versal: Add USB support
 * hw/misc/zynq_slcr: Avoid #DIV/0! error
 * Numonyx: Fix dummy cycles and check for SPI mode on cmds

# gpg: Signature made Tue 15 Dec 2020 13:59:46 GMT
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20201215:
  hw/block/m25p80: Fix Numonyx fast read dummy cycle count
  hw/block/m25p80: Check SPI mode before running some Numonyx commands
  hw/block/m25p80: Fix when VCFG XIP bit is set for Numonyx
  hw/block/m25p80: Make Numonyx config field names more accurate
  hw/misc/zynq_slcr: Avoid #DIV/0! error
  arm: xlnx-versal: Connect usb to virt-versal
  usb: xlnx-usb-subsystem: Add xilinx usb subsystem
  usb: Add DWC3 model
  usb: Add versal-usb2-ctrl-regs module
  elf_ops.h: Be more verbose with ROM blob names
  elf_ops.h: Don't truncate name of the ROM blobs we create
  hw/core/loader.c: Improve reporting of ROM overlap errors
  hw/core/loader.c: Track last-seen ROM in rom_check_and_register_reset()
  target/nios2: Use deposit32() to update ipending register
  target/nios2: Move nios2_check_interrupts() into target/nios2
  target/nios2: Move IIC code into CPU object proper
  target/openrisc: Move pic_cpu code into CPU object proper
  hw/openrisc/openrisc_sim: Abstract out "get IRQ x of CPU y"
  hw/openrisc/openrisc_sim: Use IRQ splitter when connecting IRQ to multiple CPUs
  gdbstub: Correct misparsing of vCont C/S requests

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/core/loader.c')
-rw-r--r--hw/core/loader.c67
1 files changed, 55 insertions, 12 deletions
diff --git a/hw/core/loader.c b/hw/core/loader.c
index fea22d265c..9feca32de9 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -1166,34 +1166,77 @@ static void rom_reset(void *unused)
     }
 }
 
+/* Return true if two consecutive ROMs in the ROM list overlap */
+static bool roms_overlap(Rom *last_rom, Rom *this_rom)
+{
+    if (!last_rom) {
+        return false;
+    }
+    return last_rom->as == this_rom->as &&
+        last_rom->addr + last_rom->romsize > this_rom->addr;
+}
+
+static const char *rom_as_name(Rom *rom)
+{
+    const char *name = rom->as ? rom->as->name : NULL;
+    return name ?: "anonymous";
+}
+
+static void rom_print_overlap_error_header(void)
+{
+    error_report("Some ROM regions are overlapping");
+    error_printf(
+        "These ROM regions might have been loaded by "
+        "direct user request or by default.\n"
+        "They could be BIOS/firmware images, a guest kernel, "
+        "initrd or some other file loaded into guest memory.\n"
+        "Check whether you intended to load all this guest code, and "
+        "whether it has been built to load to the correct addresses.\n");
+}
+
+static void rom_print_one_overlap_error(Rom *last_rom, Rom *rom)
+{
+    error_printf(
+        "\nThe following two regions overlap (in the %s address space):\n",
+        rom_as_name(rom));
+    error_printf(
+        "  %s (addresses 0x" TARGET_FMT_plx " - 0x" TARGET_FMT_plx ")\n",
+        last_rom->name, last_rom->addr, last_rom->addr + last_rom->romsize);
+    error_printf(
+        "  %s (addresses 0x" TARGET_FMT_plx " - 0x" TARGET_FMT_plx ")\n",
+        rom->name, rom->addr, rom->addr + rom->romsize);
+}
+
 int rom_check_and_register_reset(void)
 {
-    hwaddr addr = 0;
     MemoryRegionSection section;
-    Rom *rom;
-    AddressSpace *as = NULL;
+    Rom *rom, *last_rom = NULL;
+    bool found_overlap = false;
 
     QTAILQ_FOREACH(rom, &roms, next) {
         if (rom->fw_file) {
             continue;
         }
         if (!rom->mr) {
-            if ((addr > rom->addr) && (as == rom->as)) {
-                fprintf(stderr, "rom: requested regions overlap "
-                        "(rom %s. free=0x" TARGET_FMT_plx
-                        ", addr=0x" TARGET_FMT_plx ")\n",
-                        rom->name, addr, rom->addr);
-                return -1;
+            if (roms_overlap(last_rom, rom)) {
+                if (!found_overlap) {
+                    found_overlap = true;
+                    rom_print_overlap_error_header();
+                }
+                rom_print_one_overlap_error(last_rom, rom);
+                /* Keep going through the list so we report all overlaps */
             }
-            addr  = rom->addr;
-            addr += rom->romsize;
-            as = rom->as;
+            last_rom = rom;
         }
         section = memory_region_find(rom->mr ? rom->mr : get_system_memory(),
                                      rom->addr, 1);
         rom->isrom = int128_nz(section.size) && memory_region_is_rom(section.mr);
         memory_region_unref(section.mr);
     }
+    if (found_overlap) {
+        return -1;
+    }
+
     qemu_register_reset(rom_reset, NULL);
     roms_loaded = 1;
     return 0;