aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-02-12 13:13:01 +0000
committerPeter Maydell <peter.maydell@linaro.org>2016-02-18 18:15:11 +0000
commit40554bcea4c33ee5854f50e977f64ccf0cc50f0a (patch)
tree321ea5d8128e2cb2a64b189c86984ed8fc87e9da
parent2e37f7b1e6cb479e3061001b4f723c1e0952865f (diff)
downloadqemu-arm-40554bcea4c33ee5854f50e977f64ccf0cc50f0a.tar.gz
loader: Add load_image_mr() to load ROM image to a MemoryRegion
Add a new function load_image_mr(), which behaves like load_image_targphys() except that it loads the ROM image to a specified MemoryRegion rather than to a specified physical address. This is useful when a ROM blob needs to be loaded to a particular flash or ROM device but the address of that device in the machine's address space is not known. (For instance, ROMs in devices, or ROMs which might exist in a different address space to the system address space.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/core/loader.c35
-rw-r--r--include/hw/loader.h18
2 files changed, 47 insertions, 6 deletions
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 3a57415bf8..260b3d62cb 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -147,6 +147,28 @@ int load_image_targphys(const char *filename,
return size;
}
+int load_image_mr(const char *filename, MemoryRegion *mr)
+{
+ int size;
+
+ if (!memory_access_is_direct(mr, false)) {
+ /* Can only load an image into RAM or ROM */
+ return -1;
+ }
+
+ size = get_image_size(filename);
+
+ if (size > memory_region_size(mr)) {
+ return -1;
+ }
+ if (size > 0) {
+ if (rom_add_file_mr(filename, mr, -1) < 0) {
+ return -1;
+ }
+ }
+ return size;
+}
+
void pstrcpy_targphys(const char *name, hwaddr dest, int buf_size,
const char *source)
{
@@ -751,7 +773,7 @@ static void *rom_set_mr(Rom *rom, Object *owner, const char *name)
int rom_add_file(const char *file, const char *fw_dir,
hwaddr addr, int32_t bootindex,
- bool option_rom)
+ bool option_rom, MemoryRegion *mr)
{
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
Rom *rom;
@@ -818,7 +840,12 @@ int rom_add_file(const char *file, const char *fw_dir,
fw_cfg_add_file(fw_cfg, fw_file_name, data, rom->romsize);
} else {
- snprintf(devpath, sizeof(devpath), "/rom@" TARGET_FMT_plx, addr);
+ if (mr) {
+ rom->mr = mr;
+ snprintf(devpath, sizeof(devpath), "/rom@%s", file);
+ } else {
+ snprintf(devpath, sizeof(devpath), "/rom@" TARGET_FMT_plx, addr);
+ }
}
add_boot_device_path(bootindex, NULL, devpath);
@@ -892,12 +919,12 @@ int rom_add_elf_program(const char *name, void *data, size_t datasize,
int rom_add_vga(const char *file)
{
- return rom_add_file(file, "vgaroms", 0, -1, true);
+ return rom_add_file(file, "vgaroms", 0, -1, true, NULL);
}
int rom_add_option(const char *file, int32_t bootindex)
{
- return rom_add_file(file, "genroms", 0, bootindex, true);
+ return rom_add_file(file, "genroms", 0, bootindex, true, NULL);
}
static void rom_reset(void *unused)
diff --git a/include/hw/loader.h b/include/hw/loader.h
index f7b43ab62f..09c3764875 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -16,6 +16,18 @@ int load_image(const char *filename, uint8_t *addr); /* deprecated */
ssize_t load_image_size(const char *filename, void *addr, size_t size);
int load_image_targphys(const char *filename, hwaddr,
uint64_t max_sz);
+/**
+ * load_image_mr: load an image into a memory region
+ * @filename: Path to the image file
+ * @mr: Memory Region to load into
+ *
+ * Load the specified file into the memory region.
+ * The file loaded is registered as a ROM, so its contents will be
+ * reinstated whenever the system is reset.
+ * If the file is larger than the memory region's size the call will fail.
+ * Returns -1 on failure, or the size of the file.
+ */
+int load_image_mr(const char *filename, MemoryRegion *mr);
/* This is the limit on the maximum uncompressed image size that
* load_image_gzipped_buffer() and load_image_gzipped() will read. It prevents
@@ -67,7 +79,7 @@ extern bool rom_file_has_mr;
int rom_add_file(const char *file, const char *fw_dir,
hwaddr addr, int32_t bootindex,
- bool option_rom);
+ bool option_rom, MemoryRegion *mr);
MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
size_t max_len, hwaddr addr,
const char *fw_file_name,
@@ -82,9 +94,11 @@ void *rom_ptr(hwaddr addr);
void hmp_info_roms(Monitor *mon, const QDict *qdict);
#define rom_add_file_fixed(_f, _a, _i) \
- rom_add_file(_f, NULL, _a, _i, false)
+ rom_add_file(_f, NULL, _a, _i, false, NULL)
#define rom_add_blob_fixed(_f, _b, _l, _a) \
rom_add_blob(_f, _b, _l, _l, _a, NULL, NULL, NULL)
+#define rom_add_file_mr(_f, _mr, _i) \
+ rom_add_file(_f, NULL, 0, _i, false, mr)
#define PC_ROM_MIN_VGA 0xc0000
#define PC_ROM_MIN_OPTION 0xc8000