summaryrefslogtreecommitdiff
path: root/hw/arm
diff options
context:
space:
mode:
Diffstat (limited to 'hw/arm')
-rw-r--r--hw/arm/armv7m.c15
-rw-r--r--hw/arm/boot.c105
-rw-r--r--hw/arm/collie.c10
-rw-r--r--hw/arm/cubieboard.c2
-rw-r--r--hw/arm/digic_boards.c2
-rw-r--r--hw/arm/exynos4210.c9
-rw-r--r--hw/arm/gumstix.c6
-rw-r--r--hw/arm/highbank.c7
-rw-r--r--hw/arm/integratorcp.c5
-rw-r--r--hw/arm/kzm.c4
-rw-r--r--hw/arm/mainstone.c11
-rw-r--r--hw/arm/musicpal.c19
-rw-r--r--hw/arm/nseries.c7
-rw-r--r--hw/arm/omap1.c10
-rw-r--r--hw/arm/omap2.c10
-rw-r--r--hw/arm/omap_sx1.c16
-rw-r--r--hw/arm/palm.c3
-rw-r--r--hw/arm/pxa2xx.c18
-rw-r--r--hw/arm/realview.c11
-rw-r--r--hw/arm/spitz.c8
-rw-r--r--hw/arm/stellaris.c3
-rw-r--r--hw/arm/strongarm.c3
-rw-r--r--hw/arm/tosa.c5
-rw-r--r--hw/arm/versatilepb.c8
-rw-r--r--hw/arm/vexpress.c20
-rw-r--r--hw/arm/virt.c175
-rw-r--r--hw/arm/xilinx_zynq.c11
-rw-r--r--hw/arm/z2.c8
28 files changed, 362 insertions, 149 deletions
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 397e8dfb3..ef24ca40f 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -166,7 +166,7 @@ static void armv7m_reset(void *opaque)
flash_size and sram_size are in kb.
Returns the NVIC array. */
-qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
+qemu_irq *armv7m_init(MemoryRegion *system_memory,
int flash_size, int sram_size,
const char *kernel_filename, const char *cpu_model)
{
@@ -210,13 +210,14 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
#endif
/* Flash programming is done via the SCU, so pretend it is ROM. */
- memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size);
+ memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size,
+ &error_abort);
vmstate_register_ram_global(flash);
memory_region_set_readonly(flash, true);
- memory_region_add_subregion(address_space_mem, 0, flash);
- memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size);
+ memory_region_add_subregion(system_memory, 0, flash);
+ memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size, &error_abort);
vmstate_register_ram_global(sram);
- memory_region_add_subregion(address_space_mem, 0x20000000, sram);
+ memory_region_add_subregion(system_memory, 0x20000000, sram);
armv7m_bitband_init();
nvic = qdev_create(NULL, "armv7m_nvic");
@@ -255,9 +256,9 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
/* Hack to map an additional page of ram at the top of the address
space. This stops qemu complaining about executing code outside RAM
when returning from an exception. */
- memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000);
+ memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000, &error_abort);
vmstate_register_ram_global(hack);
- memory_region_add_subregion(address_space_mem, 0xfffff000, hack);
+ memory_region_add_subregion(system_memory, 0xfffff000, hack);
qemu_register_reset(armv7m_reset, cpu);
return pic;
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 3d1f4a255..0014c34dd 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -312,7 +312,26 @@ static void set_kernel_args_old(const struct arm_boot_info *info)
}
}
-static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
+/**
+ * load_dtb() - load a device tree binary image into memory
+ * @addr: the address to load the image at
+ * @binfo: struct describing the boot environment
+ * @addr_limit: upper limit of the available memory area at @addr
+ *
+ * Load a device tree supplied by the machine or by the user with the
+ * '-dtb' command line option, and put it at offset @addr in target
+ * memory.
+ *
+ * If @addr_limit contains a meaningful value (i.e., it is strictly greater
+ * than @addr), the device tree is only loaded if its size does not exceed
+ * the limit.
+ *
+ * Returns: the size of the device tree image on success,
+ * 0 if the image size exceeds the limit,
+ * -1 on errors.
+ */
+static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
+ hwaddr addr_limit)
{
void *fdt = NULL;
int size, rc;
@@ -341,6 +360,15 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
}
}
+ if (addr_limit > addr && size > (addr_limit - addr)) {
+ /* Installing the device tree blob at addr would exceed addr_limit.
+ * Whether this constitutes failure is up to the caller to decide,
+ * so just return 0 as size, i.e., no error.
+ */
+ g_free(fdt);
+ return 0;
+ }
+
acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells");
scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells");
if (acells == 0 || scells == 0) {
@@ -396,11 +424,14 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
qemu_fdt_dumpdtb(fdt, size);
- cpu_physical_memory_write(addr, fdt, size);
+ /* Put the DTB into the memory map as a ROM image: this will ensure
+ * the DTB is copied again upon reset, even if addr points into RAM.
+ */
+ rom_add_blob_fixed("dtb", fdt, size, addr);
g_free(fdt);
- return 0;
+ return size;
fail:
g_free(fdt);
@@ -417,8 +448,12 @@ static void do_cpu_reset(void *opaque)
if (info) {
if (!info->is_linux) {
/* Jump to the entry point. */
- env->regs[15] = info->entry & 0xfffffffe;
- env->thumb = info->entry & 1;
+ if (env->aarch64) {
+ env->pc = info->entry;
+ } else {
+ env->regs[15] = info->entry & 0xfffffffe;
+ env->thumb = info->entry & 1;
+ }
} else {
if (CPU(cpu) == first_cpu) {
if (env->aarch64) {
@@ -443,18 +478,37 @@ static void do_cpu_reset(void *opaque)
void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
{
- CPUState *cs = CPU(cpu);
+ CPUState *cs;
int kernel_size;
int initrd_size;
int is_linux = 0;
- uint64_t elf_entry;
+ uint64_t elf_entry, elf_low_addr, elf_high_addr;
int elf_machine;
hwaddr entry, kernel_load_offset;
int big_endian;
static const ARMInsnFixup *primary_loader;
+ /* CPU objects (unlike devices) are not automatically reset on system
+ * reset, so we must always register a handler to do so. If we're
+ * actually loading a kernel, the handler is also responsible for
+ * arranging that we start it correctly.
+ */
+ for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) {
+ qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
+ }
+
/* Load the kernel. */
if (!info->kernel_filename) {
+
+ if (have_dtb(info)) {
+ /* If we have a device tree blob, but no kernel to supply it to,
+ * copy it to the base of RAM for a bootloader to pick up.
+ */
+ if (load_dtb(info->loader_start, info, 0) < 0) {
+ exit(1);
+ }
+ }
+
/* If no kernel specified, do nothing; we will start from address 0
* (typically a boot ROM image) in the same way as hardware.
*/
@@ -504,11 +558,36 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
/* Assume that raw images are linux kernels, and ELF images are not. */
kernel_size = load_elf(info->kernel_filename, NULL, NULL, &elf_entry,
- NULL, NULL, big_endian, elf_machine, 1);
+ &elf_low_addr, &elf_high_addr, big_endian,
+ elf_machine, 1);
+ if (kernel_size > 0 && have_dtb(info)) {
+ /* If there is still some room left at the base of RAM, try and put
+ * the DTB there like we do for images loaded with -bios or -pflash.
+ */
+ if (elf_low_addr > info->loader_start
+ || elf_high_addr < info->loader_start) {
+ /* Pass elf_low_addr as address limit to load_dtb if it may be
+ * pointing into RAM, otherwise pass '0' (no limit)
+ */
+ if (elf_low_addr < info->loader_start) {
+ elf_low_addr = 0;
+ }
+ if (load_dtb(info->loader_start, info, elf_low_addr) < 0) {
+ exit(1);
+ }
+ }
+ }
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(info->kernel_filename, &entry, NULL,
- &is_linux);
+ &is_linux, NULL, NULL);
+ }
+ /* On aarch64, it's the bootloader's job to uncompress the kernel. */
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) {
+ entry = info->loader_start + kernel_load_offset;
+ kernel_size = load_image_gzipped(info->kernel_filename, entry,
+ info->ram_size - kernel_load_offset);
+ is_linux = 1;
}
if (kernel_size < 0) {
entry = info->loader_start + kernel_load_offset;
@@ -558,7 +637,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
*/
hwaddr dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
4096);
- if (load_dtb(dtb_start, info)) {
+ if (load_dtb(dtb_start, info, 0) < 0) {
exit(1);
}
fixupcontext[FIXUP_ARGPTR] = dtb_start;
@@ -582,9 +661,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
}
info->is_linux = is_linux;
- for (; cs; cs = CPU_NEXT(cs)) {
- cpu = ARM_CPU(cs);
- cpu->env.boot_info = info;
- qemu_register_reset(do_cpu_reset, cpu);
+ for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) {
+ ARM_CPU(cs)->env.boot_info = info;
}
}
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
index ed7851fe0..6c9b82fc5 100644
--- a/hw/arm/collie.c
+++ b/hw/arm/collie.c
@@ -15,7 +15,7 @@
#include "strongarm.h"
#include "hw/arm/arm.h"
#include "hw/block/flash.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "exec/address-spaces.h"
static struct arm_boot_info collie_binfo = {
@@ -41,13 +41,13 @@ static void collie_init(MachineState *machine)
dinfo = drive_get(IF_PFLASH, 0, 0);
pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x02000000,
- dinfo ? dinfo->bdrv : NULL, (64 * 1024),
- 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
+ (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
dinfo = drive_get(IF_PFLASH, 0, 1);
pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x02000000,
- dinfo ? dinfo->bdrv : NULL, (64 * 1024),
- 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
+ (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
sysbus_create_simple("scoop", 0x40800000, NULL);
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index e2260e379..d1e53be92 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -64,7 +64,7 @@ static void cubieboard_init(MachineState *machine)
}
memory_region_init_ram(&s->sdram, NULL, "cubieboard.ram",
- machine->ram_size);
+ machine->ram_size, &error_abort);
vmstate_register_ram_global(&s->sdram);
memory_region_add_subregion(get_system_memory(), AW_A10_SDRAM_BASE,
&s->sdram);
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
index d1424eee2..2a4b8720a 100644
--- a/hw/arm/digic_boards.c
+++ b/hw/arm/digic_boards.c
@@ -51,7 +51,7 @@ typedef struct DigicBoard {
static void digic4_board_setup_ram(DigicBoardState *s, hwaddr ram_size)
{
- memory_region_init_ram(&s->ram, NULL, "ram", ram_size);
+ memory_region_init_ram(&s->ram, NULL, "ram", ram_size, &error_abort);
memory_region_add_subregion(get_system_memory(), 0, &s->ram);
vmstate_register_ram_global(&s->ram);
}
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index 6426d168d..582794c19 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -248,7 +248,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
/* Internal ROM */
memory_region_init_ram(&s->irom_mem, NULL, "exynos4210.irom",
- EXYNOS4210_IROM_SIZE);
+ EXYNOS4210_IROM_SIZE, &error_abort);
vmstate_register_ram_global(&s->irom_mem);
memory_region_set_readonly(&s->irom_mem, true);
memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
@@ -264,7 +264,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
/* Internal RAM */
memory_region_init_ram(&s->iram_mem, NULL, "exynos4210.iram",
- EXYNOS4210_IRAM_SIZE);
+ EXYNOS4210_IRAM_SIZE, &error_abort);
vmstate_register_ram_global(&s->iram_mem);
memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
&s->iram_mem);
@@ -273,13 +273,14 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
mem_size = ram_size;
if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) {
memory_region_init_ram(&s->dram1_mem, NULL, "exynos4210.dram1",
- mem_size - EXYNOS4210_DRAM_MAX_SIZE);
+ mem_size - EXYNOS4210_DRAM_MAX_SIZE, &error_abort);
vmstate_register_ram_global(&s->dram1_mem);
memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
&s->dram1_mem);
mem_size = EXYNOS4210_DRAM_MAX_SIZE;
}
- memory_region_init_ram(&s->dram0_mem, NULL, "exynos4210.dram0", mem_size);
+ memory_region_init_ram(&s->dram0_mem, NULL, "exynos4210.dram0", mem_size,
+ &error_abort);
vmstate_register_ram_global(&s->dram0_mem);
memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
&s->dram0_mem);
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
index 3f8465ebc..8103278b1 100644
--- a/hw/arm/gumstix.c
+++ b/hw/arm/gumstix.c
@@ -40,7 +40,7 @@
#include "hw/block/flash.h"
#include "hw/devices.h"
#include "hw/boards.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "exec/address-spaces.h"
#include "sysemu/qtest.h"
@@ -71,7 +71,7 @@ static void connex_init(MachineState *machine)
be = 0;
#endif
if (!pflash_cfi01_register(0x00000000, NULL, "connext.rom", connex_rom,
- dinfo ? dinfo->bdrv : NULL,
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
sector_len, connex_rom / sector_len,
2, 0, 0, 0, 0, be)) {
fprintf(stderr, "qemu: Error registering flash memory.\n");
@@ -109,7 +109,7 @@ static void verdex_init(MachineState *machine)
be = 0;
#endif
if (!pflash_cfi01_register(0x00000000, NULL, "verdex.rom", verdex_rom,
- dinfo ? dinfo->bdrv : NULL,
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
sector_len, verdex_rom / sector_len,
2, 0, 0, 0, 0, be)) {
fprintf(stderr, "qemu: Error registering flash memory.\n");
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 834043421..30f744a1b 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -24,7 +24,7 @@
#include "net/net.h"
#include "sysemu/sysemu.h"
#include "hw/boards.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "exec/address-spaces.h"
#include "qemu/error-report.h"
@@ -255,12 +255,13 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
sysmem = get_system_memory();
dram = g_new(MemoryRegion, 1);
- memory_region_init_ram(dram, NULL, "highbank.dram", ram_size);
+ memory_region_init_ram(dram, NULL, "highbank.dram", ram_size, &error_abort);
/* SDRAM at address zero. */
memory_region_add_subregion(sysmem, 0, dram);
sysram = g_new(MemoryRegion, 1);
- memory_region_init_ram(sysram, NULL, "highbank.sysram", 0x8000);
+ memory_region_init_ram(sysram, NULL, "highbank.sysram", 0x8000,
+ &error_abort);
memory_region_add_subregion(sysmem, 0xfff88000, sysram);
if (bios_name != NULL) {
sysboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index 0e476c3db..266ec18fb 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -264,7 +264,8 @@ static int integratorcm_init(SysBusDevice *dev)
s->cm_init = 0x00000112;
s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
1000);
- memory_region_init_ram(&s->flash, OBJECT(s), "integrator.flash", 0x100000);
+ memory_region_init_ram(&s->flash, OBJECT(s), "integrator.flash", 0x100000,
+ &error_abort);
vmstate_register_ram_global(&s->flash);
memory_region_init_io(&s->iomem, OBJECT(s), &integratorcm_ops, s,
@@ -485,7 +486,7 @@ static void integratorcp_init(MachineState *machine)
exit(1);
}
- memory_region_init_ram(ram, NULL, "integrator.ram", ram_size);
+ memory_region_init_ram(ram, NULL, "integrator.ram", ram_size, &error_abort);
vmstate_register_ram_global(ram);
/* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash. */
/* ??? RAM should repeat to fill physical memory space. */
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index 0555d1265..94ceab6c8 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -97,14 +97,14 @@ static void kzm_init(MachineState *machine)
/* On a real system, the first 16k is a `secure boot rom' */
- memory_region_init_ram(ram, NULL, "kzm.ram", ram_size);
+ memory_region_init_ram(ram, NULL, "kzm.ram", ram_size, &error_abort);
vmstate_register_ram_global(ram);
memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram);
memory_region_init_alias(ram_alias, NULL, "ram.alias", ram, 0, ram_size);
memory_region_add_subregion(address_space_mem, 0x88000000, ram_alias);
- memory_region_init_ram(sram, NULL, "kzm.sram", 0x4000);
+ memory_region_init_ram(sram, NULL, "kzm.sram", 0x4000, &error_abort);
memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
dev = sysbus_create_varargs("imx_avic", 0x68000000,
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index 44f187310..0da02a67e 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -18,7 +18,7 @@
#include "hw/devices.h"
#include "hw/boards.h"
#include "hw/block/flash.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "hw/sysbus.h"
#include "exec/address-spaces.h"
#include "sysemu/qtest.h"
@@ -123,7 +123,8 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
/* Setup CPU & memory */
mpu = pxa270_init(address_space_mem, mainstone_binfo.ram_size, cpu_model);
- memory_region_init_ram(rom, NULL, "mainstone.rom", MAINSTONE_ROM);
+ memory_region_init_ram(rom, NULL, "mainstone.rom", MAINSTONE_ROM,
+ &error_abort);
vmstate_register_ram_global(rom);
memory_region_set_readonly(rom, true);
memory_region_add_subregion(address_space_mem, 0, rom);
@@ -148,9 +149,9 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
if (!pflash_cfi01_register(mainstone_flash_base[i], NULL,
i ? "mainstone.flash1" : "mainstone.flash0",
MAINSTONE_FLASH,
- dinfo->bdrv, sector_len,
- MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0,
- be)) {
+ blk_by_legacy_dinfo(dinfo),
+ sector_len, MAINSTONE_FLASH / sector_len,
+ 4, 0, 0, 0, 0, be)) {
fprintf(stderr, "qemu: Error registering flash memory.\n");
exit(1);
}
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index 6a134f23d..3712de6cb 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -18,11 +18,10 @@
#include "hw/char/serial.h"
#include "qemu/timer.h"
#include "hw/ptimer.h"
-#include "block/block.h"
#include "hw/block/flash.h"
#include "ui/console.h"
#include "hw/i2c/i2c.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "exec/address-spaces.h"
#include "ui/pixel_ops.h"
@@ -1601,11 +1600,13 @@ static void musicpal_init(MachineState *machine)
}
/* For now we use a fixed - the original - RAM size */
- memory_region_init_ram(ram, NULL, "musicpal.ram", MP_RAM_DEFAULT_SIZE);
+ memory_region_init_ram(ram, NULL, "musicpal.ram", MP_RAM_DEFAULT_SIZE,
+ &error_abort);
vmstate_register_ram_global(ram);
memory_region_add_subregion(address_space_mem, 0, ram);
- memory_region_init_ram(sram, NULL, "musicpal.sram", MP_SRAM_SIZE);
+ memory_region_init_ram(sram, NULL, "musicpal.sram", MP_SRAM_SIZE,
+ &error_abort);
vmstate_register_ram_global(sram);
memory_region_add_subregion(address_space_mem, MP_SRAM_BASE, sram);
@@ -1630,7 +1631,9 @@ static void musicpal_init(MachineState *machine)
/* Register flash */
dinfo = drive_get(IF_PFLASH, 0, 0);
if (dinfo) {
- flash_size = bdrv_getlength(dinfo->bdrv);
+ BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
+
+ flash_size = blk_getlength(blk);
if (flash_size != 8*1024*1024 && flash_size != 16*1024*1024 &&
flash_size != 32*1024*1024) {
fprintf(stderr, "Invalid flash image size\n");
@@ -1645,16 +1648,14 @@ static void musicpal_init(MachineState *machine)
#ifdef TARGET_WORDS_BIGENDIAN
pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
"musicpal.flash", flash_size,
- dinfo->bdrv, 0x10000,
- (flash_size + 0xffff) >> 16,
+ blk, 0x10000, (flash_size + 0xffff) >> 16,
MP_FLASH_SIZE_MAX / flash_size,
2, 0x00BF, 0x236D, 0x0000, 0x0000,
0x5555, 0x2AAA, 1);
#else
pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
"musicpal.flash", flash_size,
- dinfo->bdrv, 0x10000,
- (flash_size + 0xffff) >> 16,
+ blk, 0x10000, (flash_size + 0xffff) >> 16,
MP_FLASH_SIZE_MAX / flash_size,
2, 0x00BF, 0x236D, 0x0000, 0x0000,
0x5555, 0x2AAA, 0);
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index 4f092d644..c7ebaa6ab 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -31,7 +31,7 @@
#include "hw/hw.h"
#include "hw/bt.h"
#include "hw/loader.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "hw/sysbus.h"
#include "exec/address-spaces.h"
@@ -172,8 +172,9 @@ static void n8x0_nand_setup(struct n800_s *s)
qdev_prop_set_uint16(s->nand, "version_id", 0);
qdev_prop_set_int32(s->nand, "shift", 1);
dinfo = drive_get(IF_MTD, 0, 0);
- if (dinfo && dinfo->bdrv) {
- qdev_prop_set_drive_nofail(s->nand, "drive", dinfo->bdrv);
+ if (dinfo) {
+ qdev_prop_set_drive_nofail(s->nand, "drive",
+ blk_by_legacy_dinfo(dinfo));
}
qdev_init_nofail(s->nand);
sysbus_connect_irq(SYS_BUS_DEVICE(s->nand), 0,
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index e7cc5d757..abb183c2d 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -21,6 +21,7 @@
#include "hw/arm/omap.h"
#include "sysemu/sysemu.h"
#include "hw/arm/soc_dma.h"
+#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "qemu/range.h"
#include "hw/sysbus.h"
@@ -3854,10 +3855,12 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
omap_clk_init(s);
/* Memory-mapped stuff */
- memory_region_init_ram(&s->emiff_ram, NULL, "omap1.dram", s->sdram_size);
+ memory_region_init_ram(&s->emiff_ram, NULL, "omap1.dram", s->sdram_size,
+ &error_abort);
vmstate_register_ram_global(&s->emiff_ram);
memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram);
- memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size);
+ memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size,
+ &error_abort);
vmstate_register_ram_global(&s->imif_ram);
memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram);
@@ -3976,7 +3979,8 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
fprintf(stderr, "qemu: missing SecureDigital device\n");
exit(1);
}
- s->mmc = omap_mmc_init(0xfffb7800, system_memory, dinfo->bdrv,
+ s->mmc = omap_mmc_init(0xfffb7800, system_memory,
+ blk_by_legacy_dinfo(dinfo),
qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
&s->drq[OMAP_DMA_MMC_TX],
omap_findclk(s, "mmc_ck"));
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index dc53a7abb..b083ebebc 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -18,6 +18,7 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "hw/hw.h"
#include "hw/arm/arm.h"
@@ -2266,10 +2267,12 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
omap_clk_init(s);
/* Memory-mapped stuff */
- memory_region_init_ram(&s->sdram, NULL, "omap2.dram", s->sdram_size);
+ memory_region_init_ram(&s->sdram, NULL, "omap2.dram", s->sdram_size,
+ &error_abort);
vmstate_register_ram_global(&s->sdram);
memory_region_add_subregion(sysmem, OMAP2_Q2_BASE, &s->sdram);
- memory_region_init_ram(&s->sram, NULL, "omap2.sram", s->sram_size);
+ memory_region_init_ram(&s->sram, NULL, "omap2.sram", s->sram_size,
+ &error_abort);
vmstate_register_ram_global(&s->sram);
memory_region_add_subregion(sysmem, OMAP2_SRAM_BASE, &s->sram);
@@ -2459,7 +2462,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
fprintf(stderr, "qemu: missing SecureDigital device\n");
exit(1);
}
- s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), dinfo->bdrv,
+ s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9),
+ blk_by_legacy_dinfo(dinfo),
qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MMC_IRQ),
&s->drq[OMAP24XX_DMA_MMC1_TX],
omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index b4f6da606..671e02c4e 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -31,7 +31,7 @@
#include "hw/boards.h"
#include "hw/arm/arm.h"
#include "hw/block/flash.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "sysemu/qtest.h"
#include "exec/address-spaces.h"
@@ -122,7 +122,8 @@ static void sx1_init(MachineState *machine, const int version)
machine->cpu_model);
/* External Flash (EMIFS) */
- memory_region_init_ram(flash, NULL, "omap_sx1.flash0-0", flash_size);
+ memory_region_init_ram(flash, NULL, "omap_sx1.flash0-0", flash_size,
+ &error_abort);
vmstate_register_ram_global(flash);
memory_region_set_readonly(flash, true);
memory_region_add_subregion(address_space, OMAP_CS0_BASE, flash);
@@ -153,8 +154,8 @@ static void sx1_init(MachineState *machine, const int version)
if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
if (!pflash_cfi01_register(OMAP_CS0_BASE, NULL,
"omap_sx1.flash0-1", flash_size,
- dinfo->bdrv, sector_size,
- flash_size / sector_size,
+ blk_by_legacy_dinfo(dinfo),
+ sector_size, flash_size / sector_size,
4, 0, 0, 0, 0, be)) {
fprintf(stderr, "qemu: Error registering flash memory %d.\n",
fl_idx);
@@ -164,7 +165,8 @@ static void sx1_init(MachineState *machine, const int version)
if ((version == 1) &&
(dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
- memory_region_init_ram(flash_1, NULL, "omap_sx1.flash1-0", flash1_size);
+ memory_region_init_ram(flash_1, NULL, "omap_sx1.flash1-0", flash1_size,
+ &error_abort);
vmstate_register_ram_global(flash_1);
memory_region_set_readonly(flash_1, true);
memory_region_add_subregion(address_space, OMAP_CS1_BASE, flash_1);
@@ -176,8 +178,8 @@ static void sx1_init(MachineState *machine, const int version)
if (!pflash_cfi01_register(OMAP_CS1_BASE, NULL,
"omap_sx1.flash1-1", flash1_size,
- dinfo->bdrv, sector_size,
- flash1_size / sector_size,
+ blk_by_legacy_dinfo(dinfo),
+ sector_size, flash1_size / sector_size,
4, 0, 0, 0, 0, be)) {
fprintf(stderr, "qemu: Error registering flash memory %d.\n",
fl_idx);
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
index e61995f96..7f1cfb8f6 100644
--- a/hw/arm/palm.c
+++ b/hw/arm/palm.c
@@ -212,7 +212,8 @@ static void palmte_init(MachineState *machine)
mpu = omap310_mpu_init(address_space_mem, sdram_size, cpu_model);
/* External Flash (EMIFS) */
- memory_region_init_ram(flash, NULL, "palmte.flash", flash_size);
+ memory_region_init_ram(flash, NULL, "palmte.flash", flash_size,
+ &error_abort);
vmstate_register_ram_global(flash);
memory_region_set_readonly(flash, true);
memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE, flash);
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 557e0f127..693dfec9f 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -14,6 +14,7 @@
#include "hw/i2c/i2c.h"
#include "hw/ssi.h"
#include "sysemu/char.h"
+#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
static struct {
@@ -2055,10 +2056,12 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
s->reset = qemu_allocate_irq(pxa2xx_reset, s, 0);
/* SDRAM & Internal Memory Storage */
- memory_region_init_ram(&s->sdram, NULL, "pxa270.sdram", sdram_size);
+ memory_region_init_ram(&s->sdram, NULL, "pxa270.sdram", sdram_size,
+ &error_abort);
vmstate_register_ram_global(&s->sdram);
memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram);
- memory_region_init_ram(&s->internal, NULL, "pxa270.internal", 0x40000);
+ memory_region_init_ram(&s->internal, NULL, "pxa270.internal", 0x40000,
+ &error_abort);
vmstate_register_ram_global(&s->internal);
memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE,
&s->internal);
@@ -2083,7 +2086,8 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
fprintf(stderr, "qemu: missing SecureDigital device\n");
exit(1);
}
- s->mmc = pxa2xx_mmci_init(address_space, 0x41100000, dinfo->bdrv,
+ s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
+ blk_by_legacy_dinfo(dinfo),
qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
@@ -2186,11 +2190,12 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
s->reset = qemu_allocate_irq(pxa2xx_reset, s, 0);
/* SDRAM & Internal Memory Storage */
- memory_region_init_ram(&s->sdram, NULL, "pxa255.sdram", sdram_size);
+ memory_region_init_ram(&s->sdram, NULL, "pxa255.sdram", sdram_size,
+ &error_abort);
vmstate_register_ram_global(&s->sdram);
memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram);
memory_region_init_ram(&s->internal, NULL, "pxa255.internal",
- PXA2XX_INTERNAL_SIZE);
+ PXA2XX_INTERNAL_SIZE, &error_abort);
vmstate_register_ram_global(&s->internal);
memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE,
&s->internal);
@@ -2214,7 +2219,8 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
fprintf(stderr, "qemu: missing SecureDigital device\n");
exit(1);
}
- s->mmc = pxa2xx_mmci_init(address_space, 0x41100000, dinfo->bdrv,
+ s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
+ blk_by_legacy_dinfo(dinfo),
qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 64b92518d..af65aa408 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -16,7 +16,7 @@
#include "sysemu/sysemu.h"
#include "hw/boards.h"
#include "hw/i2c/i2c.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "exec/address-spaces.h"
#include "qemu/error-report.h"
@@ -137,12 +137,14 @@ static void realview_init(MachineState *machine,
/* Core tile RAM. */
low_ram_size = ram_size - 0x20000000;
ram_size = 0x20000000;
- memory_region_init_ram(ram_lo, NULL, "realview.lowmem", low_ram_size);
+ memory_region_init_ram(ram_lo, NULL, "realview.lowmem", low_ram_size,
+ &error_abort);
vmstate_register_ram_global(ram_lo);
memory_region_add_subregion(sysmem, 0x20000000, ram_lo);
}
- memory_region_init_ram(ram_hi, NULL, "realview.highmem", ram_size);
+ memory_region_init_ram(ram_hi, NULL, "realview.highmem", ram_size,
+ &error_abort);
vmstate_register_ram_global(ram_hi);
low_ram_size = ram_size;
if (low_ram_size > 0x10000000)
@@ -337,7 +339,8 @@ static void realview_init(MachineState *machine,
startup code. I guess this works on real hardware because the
BootROM happens to be in ROM/flash or in memory that isn't clobbered
until after Linux boots the secondary CPUs. */
- memory_region_init_ram(ram_hack, NULL, "realview.hack", 0x1000);
+ memory_region_init_ram(ram_hack, NULL, "realview.hack", 0x1000,
+ &error_abort);
vmstate_register_ram_global(ram_hack);
memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack);
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 03cc6ce2f..a16831c2e 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -22,10 +22,9 @@
#include "hw/devices.h"
#include "hw/arm/sharpsl.h"
#include "ui/console.h"
-#include "block/block.h"
#include "audio/audio.h"
#include "hw/boards.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "hw/sysbus.h"
#include "exec/address-spaces.h"
@@ -170,7 +169,8 @@ static int sl_nand_init(SysBusDevice *dev)
s->ctl = 0;
nand = drive_get(IF_MTD, 0, 0);
- s->nand = nand_init(nand ? nand->bdrv : NULL, s->manf_id, s->chip_id);
+ s->nand = nand_init(nand ? blk_by_legacy_dinfo(nand) : NULL,
+ s->manf_id, s->chip_id);
memory_region_init_io(&s->iomem, OBJECT(s), &sl_ops, s, "sl", 0x40);
sysbus_init_mmio(dev, &s->iomem);
@@ -912,7 +912,7 @@ static void spitz_common_init(MachineState *machine,
sl_flash_register(mpu, (model == spitz) ? FLASH_128M : FLASH_1024M);
- memory_region_init_ram(rom, NULL, "spitz.rom", SPITZ_ROM);
+ memory_region_init_ram(rom, NULL, "spitz.rom", SPITZ_ROM, &error_abort);
vmstate_register_ram_global(rom);
memory_region_set_readonly(rom, true);
memory_region_add_subregion(address_space_mem, 0, rom);
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 80028e80c..64bd4b4c4 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -1208,7 +1208,6 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
0x40024000, 0x40025000, 0x40026000};
static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
- MemoryRegion *address_space_mem = get_system_memory();
qemu_irq *pic;
DeviceState *gpio_dev[7];
qemu_irq gpio_in[7][8];
@@ -1223,7 +1222,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
flash_size = ((board->dc0 & 0xffff) + 1) << 1;
sram_size = (board->dc0 >> 18) + 1;
- pic = armv7m_init(address_space_mem,
+ pic = armv7m_init(get_system_memory(),
flash_size, sram_size, kernel_filename, cpu_model);
if (board->dc1 & (1 << 16)) {
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index 9e2a0d48a..32063459d 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -1604,7 +1604,8 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
exit(1);
}
- memory_region_init_ram(&s->sdram, NULL, "strongarm.sdram", sdram_size);
+ memory_region_init_ram(&s->sdram, NULL, "strongarm.sdram", sdram_size,
+ &error_abort);
vmstate_register_ram_global(&s->sdram);
memory_region_add_subregion(sysmem, SA_SDCS0, &s->sdram);
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index abc0f2a96..73572ebe0 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -17,11 +17,10 @@
#include "hw/devices.h"
#include "hw/arm/sharpsl.h"
#include "hw/pcmcia.h"
-#include "block/block.h"
#include "hw/boards.h"
#include "hw/i2c/i2c.h"
#include "hw/ssi.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "hw/sysbus.h"
#include "exec/address-spaces.h"
@@ -228,7 +227,7 @@ static void tosa_init(MachineState *machine)
mpu = pxa255_init(address_space_mem, tosa_binfo.ram_size);
- memory_region_init_ram(rom, NULL, "tosa.rom", TOSA_ROM);
+ memory_region_init_ram(rom, NULL, "tosa.rom", TOSA_ROM, &error_abort);
vmstate_register_ram_global(rom);
memory_region_set_readonly(rom, true);
memory_region_add_subregion(address_space_mem, 0, rom);
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index dea5fc7a9..e6ef0a2e7 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -15,7 +15,7 @@
#include "hw/pci/pci.h"
#include "hw/i2c/i2c.h"
#include "hw/boards.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "exec/address-spaces.h"
#include "hw/block/flash.h"
@@ -198,7 +198,8 @@ static void versatile_init(MachineState *machine, int board_id)
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
}
- memory_region_init_ram(ram, NULL, "versatile.ram", machine->ram_size);
+ memory_region_init_ram(ram, NULL, "versatile.ram", machine->ram_size,
+ &error_abort);
vmstate_register_ram_global(ram);
/* ??? RAM should repeat to fill physical memory space. */
/* SDRAM at address zero. */
@@ -337,7 +338,8 @@ static void versatile_init(MachineState *machine, int board_id)
dinfo = drive_get(IF_PFLASH, 0, 0);
if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, NULL, "versatile.flash",
- VERSATILE_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL,
+ VERSATILE_FLASH_SIZE,
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
VERSATILE_FLASH_SECT_SIZE,
VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE,
4, 0x0089, 0x0018, 0x0000, 0x0, 0)) {
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index a88732c7e..7cbd13f18 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -30,7 +30,7 @@
#include "hw/boards.h"
#include "hw/loader.h"
#include "exec/address-spaces.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "hw/block/flash.h"
#include "sysemu/device_tree.h"
#include "qemu/error-report.h"
@@ -252,7 +252,8 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
exit(1);
}
- memory_region_init_ram(ram, NULL, "vexpress.highmem", ram_size);
+ memory_region_init_ram(ram, NULL, "vexpress.highmem", ram_size,
+ &error_abort);
vmstate_register_ram_global(ram);
low_ram_size = ram_size;
if (low_ram_size > 0x4000000) {
@@ -346,7 +347,8 @@ static void a15_daughterboard_init(const VEDBoardInfo *daughterboard,
}
}
- memory_region_init_ram(ram, NULL, "vexpress.highmem", ram_size);
+ memory_region_init_ram(ram, NULL, "vexpress.highmem", ram_size,
+ &error_abort);
vmstate_register_ram_global(ram);
/* RAM is from 0x80000000 upwards; there is no low-memory alias for it. */
memory_region_add_subregion(sysmem, 0x80000000, ram);
@@ -364,7 +366,8 @@ static void a15_daughterboard_init(const VEDBoardInfo *daughterboard,
/* 0x2b060000: SP805 watchdog: not modelled */
/* 0x2b0a0000: PL341 dynamic memory controller: not modelled */
/* 0x2e000000: system SRAM */
- memory_region_init_ram(sram, NULL, "vexpress.a15sram", 0x10000);
+ memory_region_init_ram(sram, NULL, "vexpress.a15sram", 0x10000,
+ &error_abort);
vmstate_register_ram_global(sram);
memory_region_add_subregion(sysmem, 0x2e000000, sram);
@@ -488,7 +491,8 @@ static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,
{
DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
- if (di && qdev_prop_set_drive(dev, "drive", di->bdrv)) {
+ if (di && qdev_prop_set_drive(dev, "drive",
+ blk_by_legacy_dinfo(di))) {
abort();
}
@@ -634,12 +638,14 @@ static void vexpress_common_init(VEDBoardInfo *daughterboard,
}
sram_size = 0x2000000;
- memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size);
+ memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size,
+ &error_abort);
vmstate_register_ram_global(sram);
memory_region_add_subregion(sysmem, map[VE_SRAM], sram);
vram_size = 0x800000;
- memory_region_init_ram(vram, NULL, "vexpress.vram", vram_size);
+ memory_region_init_ram(vram, NULL, "vexpress.vram", vram_size,
+ &error_abort);
vmstate_register_ram_global(vram);
memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 89532bd78..314e55b56 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -33,10 +33,12 @@
#include "hw/arm/primecell.h"
#include "hw/devices.h"
#include "net/net.h"
+#include "sysemu/block-backend.h"
#include "sysemu/device_tree.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "hw/boards.h"
+#include "hw/loader.h"
#include "exec/address-spaces.h"
#include "qemu/bitops.h"
#include "qemu/error-report.h"
@@ -98,17 +100,17 @@ typedef struct VirtBoardInfo {
*/
static const MemMapEntry a15memmap[] = {
/* Space up to 0x8000000 is reserved for a boot ROM */
- [VIRT_FLASH] = { 0, 0x8000000 },
- [VIRT_CPUPERIPHS] = { 0x8000000, 0x20000 },
+ [VIRT_FLASH] = { 0, 0x08000000 },
+ [VIRT_CPUPERIPHS] = { 0x08000000, 0x00020000 },
/* GIC distributor and CPU interfaces sit inside the CPU peripheral space */
- [VIRT_GIC_DIST] = { 0x8000000, 0x10000 },
- [VIRT_GIC_CPU] = { 0x8010000, 0x10000 },
- [VIRT_UART] = { 0x9000000, 0x1000 },
- [VIRT_RTC] = { 0x9010000, 0x1000 },
- [VIRT_MMIO] = { 0xa000000, 0x200 },
+ [VIRT_GIC_DIST] = { 0x08000000, 0x00010000 },
+ [VIRT_GIC_CPU] = { 0x08010000, 0x00010000 },
+ [VIRT_UART] = { 0x09000000, 0x00001000 },
+ [VIRT_RTC] = { 0x09010000, 0x00001000 },
+ [VIRT_MMIO] = { 0x0a000000, 0x00000200 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
/* 0x10000000 .. 0x40000000 reserved for PCI */
- [VIRT_MEM] = { 0x40000000, 30ULL * 1024 * 1024 * 1024 },
+ [VIRT_MEM] = { 0x40000000, 30ULL * 1024 * 1024 * 1024 },
};
static const int a15irqmap[] = {
@@ -189,26 +191,48 @@ static void create_fdt(VirtBoardInfo *vbi)
static void fdt_add_psci_node(const VirtBoardInfo *vbi)
{
+ uint32_t cpu_suspend_fn;
+ uint32_t cpu_off_fn;
+ uint32_t cpu_on_fn;
+ uint32_t migrate_fn;
void *fdt = vbi->fdt;
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
- /* No PSCI for TCG yet */
- if (kvm_enabled()) {
- qemu_fdt_add_subnode(fdt, "/psci");
- if (armcpu->psci_version == 2) {
- const char comp[] = "arm,psci-0.2\0arm,psci";
- qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
+ qemu_fdt_add_subnode(fdt, "/psci");
+ if (armcpu->psci_version == 2) {
+ const char comp[] = "arm,psci-0.2\0arm,psci";
+ qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
+
+ cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
+ if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
+ cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND;
+ cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON;
+ migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE;
} else {
- qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
+ cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND;
+ cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON;
+ migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE;
}
+ } else {
+ qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
- qemu_fdt_setprop_string(fdt, "/psci", "method", "hvc");
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend",
- PSCI_FN_CPU_SUSPEND);
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", PSCI_FN_CPU_OFF);
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", PSCI_FN_CPU_ON);
- qemu_fdt_setprop_cell(fdt, "/psci", "migrate", PSCI_FN_MIGRATE);
+ cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND;
+ cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF;
+ cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON;
+ migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE;
}
+
+ /* We adopt the PSCI spec's nomenclature, and use 'conduit' to refer
+ * to the instruction that should be used to invoke PSCI functions.
+ * However, the device tree binding uses 'method' instead, so that is
+ * what we should use here.
+ */
+ qemu_fdt_setprop_string(fdt, "/psci", "method", "hvc");
+
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn);
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn);
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn);
+ qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
}
static void fdt_add_timer_nodes(const VirtBoardInfo *vbi)
@@ -217,14 +241,23 @@ static void fdt_add_timer_nodes(const VirtBoardInfo *vbi)
* but for the GIC implementation provided by both QEMU and KVM
* they are edge-triggered.
*/
+ ARMCPU *armcpu;
uint32_t irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI;
irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
GIC_FDT_IRQ_PPI_CPU_WIDTH, (1 << vbi->smp_cpus) - 1);
qemu_fdt_add_subnode(vbi->fdt, "/timer");
- qemu_fdt_setprop_string(vbi->fdt, "/timer",
- "compatible", "arm,armv7-timer");
+
+ armcpu = ARM_CPU(qemu_get_cpu(0));
+ if (arm_feature(&armcpu->env, ARM_FEATURE_V8)) {
+ const char compat[] = "arm,armv8-timer\0arm,armv7-timer";
+ qemu_fdt_setprop(vbi->fdt, "/timer", "compatible",
+ compat, sizeof(compat));
+ } else {
+ qemu_fdt_setprop_string(vbi->fdt, "/timer", "compatible",
+ "arm,armv7-timer");
+ }
qemu_fdt_setprop_cells(vbi->fdt, "/timer", "interrupts",
GIC_FDT_IRQ_TYPE_PPI, 13, irqflags,
GIC_FDT_IRQ_TYPE_PPI, 14, irqflags,
@@ -350,11 +383,13 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
2, base, 2, size);
qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
GIC_FDT_IRQ_TYPE_SPI, irq,
- GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
qemu_fdt_setprop_cells(vbi->fdt, nodename, "clocks",
vbi->clock_phandle, vbi->clock_phandle);
qemu_fdt_setprop(vbi->fdt, nodename, "clock-names",
clocknames, sizeof(clocknames));
+
+ qemu_fdt_setprop_string(vbi->fdt, "/chosen", "stdout-path", nodename);
g_free(nodename);
}
@@ -375,7 +410,7 @@ static void create_rtc(const VirtBoardInfo *vbi, qemu_irq *pic)
2, base, 2, size);
qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
GIC_FDT_IRQ_TYPE_SPI, irq,
- GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
qemu_fdt_setprop_cell(vbi->fdt, nodename, "clocks", vbi->clock_phandle);
qemu_fdt_setprop_string(vbi->fdt, nodename, "clock-names", "apb_pclk");
g_free(nodename);
@@ -416,6 +451,74 @@ static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic)
}
}
+static void create_one_flash(const char *name, hwaddr flashbase,
+ hwaddr flashsize)
+{
+ /* Create and map a single flash device. We use the same
+ * parameters as the flash devices on the Versatile Express board.
+ */
+ DriveInfo *dinfo = drive_get_next(IF_PFLASH);
+ DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
+ const uint64_t sectorlength = 256 * 1024;
+
+ if (dinfo && qdev_prop_set_drive(dev, "drive",
+ blk_by_legacy_dinfo(dinfo))) {
+ abort();
+ }
+
+ qdev_prop_set_uint32(dev, "num-blocks", flashsize / sectorlength);
+ qdev_prop_set_uint64(dev, "sector-length", sectorlength);
+ qdev_prop_set_uint8(dev, "width", 4);
+ qdev_prop_set_uint8(dev, "device-width", 2);
+ qdev_prop_set_uint8(dev, "big-endian", 0);
+ qdev_prop_set_uint16(dev, "id0", 0x89);
+ qdev_prop_set_uint16(dev, "id1", 0x18);
+ qdev_prop_set_uint16(dev, "id2", 0x00);
+ qdev_prop_set_uint16(dev, "id3", 0x00);
+ qdev_prop_set_string(dev, "name", name);
+ qdev_init_nofail(dev);
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, flashbase);
+}
+
+static void create_flash(const VirtBoardInfo *vbi)
+{
+ /* Create two flash devices to fill the VIRT_FLASH space in the memmap.
+ * Any file passed via -bios goes in the first of these.
+ */
+ hwaddr flashsize = vbi->memmap[VIRT_FLASH].size / 2;
+ hwaddr flashbase = vbi->memmap[VIRT_FLASH].base;
+ char *nodename;
+
+ if (bios_name) {
+ const char *fn;
+
+ if (drive_get(IF_PFLASH, 0, 0)) {
+ error_report("The contents of the first flash device may be "
+ "specified with -bios or with -drive if=pflash... "
+ "but you cannot use both options at once");
+ exit(1);
+ }
+ fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ if (!fn || load_image_targphys(fn, flashbase, flashsize) < 0) {
+ error_report("Could not load ROM image '%s'", bios_name);
+ exit(1);
+ }
+ }
+
+ create_one_flash("virt.flash0", flashbase, flashsize);
+ create_one_flash("virt.flash1", flashbase + flashsize, flashsize);
+
+ nodename = g_strdup_printf("/flash@%" PRIx64, flashbase);
+ qemu_fdt_add_subnode(vbi->fdt, nodename);
+ qemu_fdt_setprop_string(vbi->fdt, nodename, "compatible", "cfi-flash");
+ qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
+ 2, flashbase, 2, flashsize,
+ 2, flashbase + flashsize, 2, flashsize);
+ qemu_fdt_setprop_cell(vbi->fdt, nodename, "bank-width", 4);
+ g_free(nodename);
+}
+
static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
{
const VirtBoardInfo *board = (const VirtBoardInfo *)binfo;
@@ -446,23 +549,12 @@ static void machvirt_init(MachineState *machine)
vbi->smp_cpus = smp_cpus;
- /*
- * Only supported method of starting secondary CPUs is PSCI and
- * PSCI is not yet supported with TCG, so limit smp_cpus to 1
- * if we're not using KVM.
- */
- if (!kvm_enabled() && smp_cpus > 1) {
- error_report("mach-virt: must enable KVM to use multiple CPUs");
- exit(1);
- }
-
if (machine->ram_size > vbi->memmap[VIRT_MEM].size) {
error_report("mach-virt: cannot model more than 30GB RAM");
exit(1);
}
create_fdt(vbi);
- fdt_add_timer_nodes(vbi);
for (n = 0; n < smp_cpus; n++) {
ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
@@ -474,6 +566,9 @@ static void machvirt_init(MachineState *machine)
}
cpuobj = object_new(object_class_get_name(oc));
+ object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_HVC, "psci-conduit",
+ NULL);
+
/* Secondary CPUs start in PSCI powered-down state */
if (n > 0) {
object_property_set_bool(cpuobj, true, "start-powered-off", NULL);
@@ -486,13 +581,17 @@ static void machvirt_init(MachineState *machine)
object_property_set_bool(cpuobj, true, "realized", NULL);
}
+ fdt_add_timer_nodes(vbi);
fdt_add_cpu_nodes(vbi);
fdt_add_psci_node(vbi);
- memory_region_init_ram(ram, NULL, "mach-virt.ram", machine->ram_size);
+ memory_region_init_ram(ram, NULL, "mach-virt.ram", machine->ram_size,
+ &error_abort);
vmstate_register_ram_global(ram);
memory_region_add_subregion(sysmem, vbi->memmap[VIRT_MEM].base, ram);
+ create_flash(vbi);
+
create_gic(vbi, pic);
create_uart(vbi, pic);
@@ -520,7 +619,7 @@ static QEMUMachine machvirt_a15_machine = {
.name = "virt",
.desc = "ARM Virtual Machine",
.init = machvirt_init,
- .max_cpus = 4,
+ .max_cpus = 8,
};
static void machvirt_machine_init(void)
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index ba5aa82cd..b59039297 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -22,7 +22,7 @@
#include "sysemu/sysemu.h"
#include "hw/boards.h"
#include "hw/block/flash.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "hw/loader.h"
#include "hw/ssi.h"
#include "qemu/error-report.h"
@@ -149,12 +149,14 @@ static void zynq_init(MachineState *machine)
}
/* DDR remapped to address zero. */
- memory_region_init_ram(ext_ram, NULL, "zynq.ext_ram", ram_size);
+ memory_region_init_ram(ext_ram, NULL, "zynq.ext_ram", ram_size,
+ &error_abort);
vmstate_register_ram_global(ext_ram);
memory_region_add_subregion(address_space_mem, 0, ext_ram);
/* 256K of on-chip memory */
- memory_region_init_ram(ocm_ram, NULL, "zynq.ocm_ram", 256 << 10);
+ memory_region_init_ram(ocm_ram, NULL, "zynq.ocm_ram", 256 << 10,
+ &error_abort);
vmstate_register_ram_global(ocm_ram);
memory_region_add_subregion(address_space_mem, 0xFFFC0000, ocm_ram);
@@ -162,7 +164,8 @@ static void zynq_init(MachineState *machine)
/* AMD */
pflash_cfi02_register(0xe2000000, NULL, "zynq.pflash", FLASH_SIZE,
- dinfo ? dinfo->bdrv : NULL, FLASH_SECTOR_SIZE,
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
+ FLASH_SECTOR_SIZE,
FLASH_SIZE/FLASH_SECTOR_SIZE, 1,
1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa,
0);
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 36b3b504f..17355479a 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -20,7 +20,7 @@
#include "hw/boards.h"
#include "sysemu/sysemu.h"
#include "hw/block/flash.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
#include "ui/console.h"
#include "audio/audio.h"
#include "exec/address-spaces.h"
@@ -336,9 +336,9 @@ static void z2_init(MachineState *machine)
if (!pflash_cfi01_register(Z2_FLASH_BASE,
NULL, "z2.flash0", Z2_FLASH_SIZE,
- dinfo ? dinfo->bdrv : NULL, sector_len,
- Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0,
- be)) {
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
+ sector_len, Z2_FLASH_SIZE / sector_len,
+ 4, 0, 0, 0, 0, be)) {
fprintf(stderr, "qemu: Error registering flash memory.\n");
exit(1);
}