summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/core/loader.c48
1 files changed, 42 insertions, 6 deletions
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 45aaba6158..9feca32de9 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -1176,10 +1176,42 @@ static bool roms_overlap(Rom *last_rom, Rom *this_rom)
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)
{
MemoryRegionSection section;
Rom *rom, *last_rom = NULL;
+ bool found_overlap = false;
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->fw_file) {
@@ -1187,12 +1219,12 @@ int rom_check_and_register_reset(void)
}
if (!rom->mr) {
if (roms_overlap(last_rom, rom)) {
- fprintf(stderr, "rom: requested regions overlap "
- "(rom %s. free=0x" TARGET_FMT_plx
- ", addr=0x" TARGET_FMT_plx ")\n",
- rom->name, last_rom->addr + last_rom->romsize,
- rom->addr);
- return -1;
+ 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 */
}
last_rom = rom;
}
@@ -1201,6 +1233,10 @@ int rom_check_and_register_reset(void)
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;