aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/core/loader.c10
-rw-r--r--hw/mips/mips_malta.c6
-rw-r--r--hw/s390x/ipl.c18
-rw-r--r--hw/sparc/sun4m.c4
-rw-r--r--hw/sparc64/sun4u.c4
-rw-r--r--include/hw/loader.h2
-rw-r--r--target/arm/cpu.c2
7 files changed, 27 insertions, 19 deletions
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 06bdbca537..bbb6e65bb5 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -191,7 +191,7 @@ void pstrcpy_targphys(const char *name, hwaddr dest, int buf_size,
rom_add_blob_fixed(name, source, (nulp - source) + 1, dest);
} else {
rom_add_blob_fixed(name, source, buf_size, dest);
- ptr = rom_ptr(dest + buf_size - 1);
+ ptr = rom_ptr(dest + buf_size - 1, sizeof(*ptr));
*ptr = 0;
}
}
@@ -1165,7 +1165,7 @@ void rom_reset_order_override(void)
fw_cfg_reset_order_override(fw_cfg);
}
-static Rom *find_rom(hwaddr addr)
+static Rom *find_rom(hwaddr addr, size_t size)
{
Rom *rom;
@@ -1179,7 +1179,7 @@ static Rom *find_rom(hwaddr addr)
if (rom->addr > addr) {
continue;
}
- if (rom->addr + rom->romsize < addr) {
+ if (rom->addr + rom->romsize < addr + size) {
continue;
}
return rom;
@@ -1249,11 +1249,11 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
return (d + l) - dest;
}
-void *rom_ptr(hwaddr addr)
+void *rom_ptr(hwaddr addr, size_t size)
{
Rom *rom;
- rom = find_rom(addr);
+ rom = find_rom(addr, size);
if (!rom || !rom->data)
return NULL;
return rom->data + (addr - rom->addr);
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index b9d92bf47e..1b4e32e58e 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1133,11 +1133,13 @@ void mips_malta_init(MachineState *machine)
a neat trick which allows bi-endian firmware. */
#ifndef TARGET_WORDS_BIGENDIAN
{
- uint32_t *end, *addr = rom_ptr(FLASH_ADDRESS);
+ uint32_t *end, *addr;
+ const size_t swapsize = MIN(bios_size, 0x3e0000);
+ addr = rom_ptr(FLASH_ADDRESS, swapsize);
if (!addr) {
addr = memory_region_get_ram_ptr(bios);
}
- end = (void *)addr + MIN(bios_size, 0x3e0000);
+ end = (void *)addr + swapsize;
while (addr < end) {
bswap32s(addr);
addr++;
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index f278036fa7..21f64ad26a 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -33,7 +33,6 @@
#define KERN_PARM_AREA 0x010480UL
#define INITRD_START 0x800000UL
#define INITRD_PARM_START 0x010408UL
-#define INITRD_PARM_SIZE 0x010410UL
#define PARMFILE_START 0x001000UL
#define ZIPL_IMAGE_START 0x009000UL
#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64)
@@ -165,12 +164,12 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
goto error;
}
/* if this is Linux use KERN_IMAGE_START */
- magic = rom_ptr(LINUX_MAGIC_ADDR);
+ magic = rom_ptr(LINUX_MAGIC_ADDR, 6);
if (magic && !memcmp(magic, "S390EP", 6)) {
pentry = KERN_IMAGE_START;
} else {
/* if not Linux load the address of the (short) IPL PSW */
- ipl_psw = rom_ptr(4);
+ ipl_psw = rom_ptr(4, 4);
if (ipl_psw) {
pentry = be32_to_cpu(*ipl_psw) & 0x7fffffffUL;
} else {
@@ -186,9 +185,12 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
* loader) and it won't work. For this case we force it to 0x10000, too.
*/
if (pentry == KERN_IMAGE_START || pentry == 0x800) {
+ char *parm_area = rom_ptr(KERN_PARM_AREA, strlen(ipl->cmdline) + 1);
ipl->start_addr = KERN_IMAGE_START;
/* Overwrite parameters in the kernel image, which are "rom" */
- strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline);
+ if (parm_area) {
+ strcpy(parm_area, ipl->cmdline);
+ }
} else {
ipl->start_addr = pentry;
}
@@ -196,6 +198,7 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
if (ipl->initrd) {
ram_addr_t initrd_offset;
int initrd_size;
+ uint64_t *romptr;
initrd_offset = INITRD_START;
while (kernel_size + 0x100000 > initrd_offset) {
@@ -212,8 +215,11 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
* we have to overwrite values in the kernel image,
* which are "rom"
*/
- stq_p(rom_ptr(INITRD_PARM_START), initrd_offset);
- stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size);
+ romptr = rom_ptr(INITRD_PARM_START, 16);
+ if (romptr) {
+ stq_p(romptr, initrd_offset);
+ stq_p(romptr + 1, initrd_size);
+ }
}
}
/*
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index b984d2da0e..21078cc121 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -272,8 +272,8 @@ static unsigned long sun4m_load_kernel(const char *kernel_filename,
}
if (initrd_size > 0) {
for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
- ptr = rom_ptr(KERNEL_LOAD_ADDR + i);
- if (ldl_p(ptr) == 0x48647253) { // HdrS
+ ptr = rom_ptr(KERNEL_LOAD_ADDR + i, 24);
+ if (ptr && ldl_p(ptr) == 0x48647253) { /* HdrS */
stl_p(ptr + 16, INITRD_LOAD_ADDR);
stl_p(ptr + 20, initrd_size);
break;
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 3975a7b65a..334dd7008e 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -186,8 +186,8 @@ static uint64_t sun4u_load_kernel(const char *kernel_filename,
}
if (*initrd_size > 0) {
for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
- ptr = rom_ptr(*kernel_addr + i);
- if (ldl_p(ptr + 8) == 0x48647253) { /* HdrS */
+ ptr = rom_ptr(*kernel_addr + i, 32);
+ if (ptr && ldl_p(ptr + 8) == 0x48647253) { /* HdrS */
stl_p(ptr + 24, *initrd_addr + *kernel_addr);
stl_p(ptr + 28, *initrd_size);
break;
diff --git a/include/hw/loader.h b/include/hw/loader.h
index 5ed3fd8ae6..e98b84b8f9 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -226,7 +226,7 @@ void rom_set_fw(FWCfgState *f);
void rom_set_order_override(int order);
void rom_reset_order_override(void);
int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
-void *rom_ptr(hwaddr addr);
+void *rom_ptr(hwaddr addr, size_t size);
void hmp_info_roms(Monitor *mon, const QDict *qdict);
#define rom_add_file_fixed(_f, _a, _i) \
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 82ff450f9a..64a8005a4b 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -239,7 +239,7 @@ static void arm_cpu_reset(CPUState *s)
/* Load the initial SP and PC from offset 0 and 4 in the vector table */
vecbase = env->v7m.vecbase[env->v7m.secure];
- rom = rom_ptr(vecbase);
+ rom = rom_ptr(vecbase, 8);
if (rom) {
/* Address zero is covered by ROM which hasn't yet been
* copied into physical memory.