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>
Message-id: 1455288361-30117-3-git-send-email-peter.maydell@linaro.org
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Peter Maydell 2016-03-04 11:30:17 +00:00
parent 83ec1923cd
commit 76151cacfe
2 changed files with 47 additions and 6 deletions

View File

@ -147,6 +147,28 @@ int load_image_targphys(const char *filename,
return size; 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, void pstrcpy_targphys(const char *name, hwaddr dest, int buf_size,
const char *source) 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, int rom_add_file(const char *file, const char *fw_dir,
hwaddr addr, int32_t bootindex, hwaddr addr, int32_t bootindex,
bool option_rom) bool option_rom, MemoryRegion *mr)
{ {
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
Rom *rom; 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); fw_cfg_add_file(fw_cfg, fw_file_name, data, rom->romsize);
} else { } 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); 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) 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) 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) static void rom_reset(void *unused)

View File

@ -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); ssize_t load_image_size(const char *filename, void *addr, size_t size);
int load_image_targphys(const char *filename, hwaddr, int load_image_targphys(const char *filename, hwaddr,
uint64_t max_sz); 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 /* This is the limit on the maximum uncompressed image size that
* load_image_gzipped_buffer() and load_image_gzipped() will read. It prevents * 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, int rom_add_file(const char *file, const char *fw_dir,
hwaddr addr, int32_t bootindex, 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, MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
size_t max_len, hwaddr addr, size_t max_len, hwaddr addr,
const char *fw_file_name, const char *fw_file_name,
@ -82,9 +94,11 @@ void *rom_ptr(hwaddr addr);
void hmp_info_roms(Monitor *mon, const QDict *qdict); void hmp_info_roms(Monitor *mon, const QDict *qdict);
#define rom_add_file_fixed(_f, _a, _i) \ #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) \ #define rom_add_blob_fixed(_f, _b, _l, _a) \
rom_add_blob(_f, _b, _l, _l, _a, NULL, NULL, NULL) 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_VGA 0xc0000
#define PC_ROM_MIN_OPTION 0xc8000 #define PC_ROM_MIN_OPTION 0xc8000