aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/armv7m_nvic.c3
-rw-r--r--hw/fdc.c4
-rw-r--r--hw/fw_cfg.c25
-rw-r--r--hw/ide/core.c8
-rw-r--r--hw/ivshmem.c13
-rw-r--r--hw/pc_piix.c20
-rw-r--r--hw/pl190.c18
-rw-r--r--hw/scsi-disk.c8
-rw-r--r--hw/scsi-generic.c4
-rw-r--r--hw/vexpress.c33
-rw-r--r--hw/virtio-blk.c8
11 files changed, 111 insertions, 33 deletions
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 6a0832eb3..5c0911647 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -489,7 +489,8 @@ static int armv7m_nvic_init(SysBusDevice *dev)
*/
memory_region_init_alias(&s->gic_iomem_alias, "nvic-gic", &s->gic.iomem,
0x100, 0xc00);
- memory_region_add_subregion_overlap(&s->container, 0x100, &s->gic.iomem, 1);
+ memory_region_add_subregion_overlap(&s->container, 0x100,
+ &s->gic_iomem_alias, 1);
/* Map the whole thing into system memory at the location required
* by the v7M architecture.
*/
diff --git a/hw/fdc.c b/hw/fdc.c
index 08830c1ba..43b0f2050 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1994,11 +1994,11 @@ static int fdctrl_connect_drives(FDCtrl *fdctrl)
drive->fdctrl = fdctrl;
if (drive->bs) {
- if (bdrv_get_on_error(drive->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
+ if (bdrv_get_on_error(drive->bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
error_report("fdc doesn't support drive option werror");
return -1;
}
- if (bdrv_get_on_error(drive->bs, 1) != BLOCK_ERR_REPORT) {
+ if (bdrv_get_on_error(drive->bs, 1) != BLOCKDEV_ON_ERROR_REPORT) {
error_report("fdc doesn't support drive option rerror");
return -1;
}
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 7b3b5769a..dcde1a943 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -183,6 +183,30 @@ static void fw_cfg_bootsplash(FWCfgState *s)
}
}
+static void fw_cfg_reboot(FWCfgState *s)
+{
+ int reboot_timeout = -1;
+ char *p;
+ const char *temp;
+
+ /* get user configuration */
+ QemuOptsList *plist = qemu_find_opts("boot-opts");
+ QemuOpts *opts = QTAILQ_FIRST(&plist->head);
+ if (opts != NULL) {
+ temp = qemu_opt_get(opts, "reboot-timeout");
+ if (temp != NULL) {
+ p = (char *)temp;
+ reboot_timeout = strtol(p, (char **)&p, 10);
+ }
+ }
+ /* validate the input */
+ if (reboot_timeout > 0xffff) {
+ error_report("reboot timeout is larger than 65535, force it to 65535.");
+ reboot_timeout = 0xffff;
+ }
+ fw_cfg_add_file(s, "etc/boot-fail-wait", g_memdup(&reboot_timeout, 4), 4);
+}
+
static void fw_cfg_write(FWCfgState *s, uint8_t value)
{
int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL);
@@ -497,6 +521,7 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
fw_cfg_add_i16(s, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu);
fw_cfg_bootsplash(s);
+ fw_cfg_reboot(s);
s->machine_ready.notify = fw_cfg_machine_ready;
qemu_add_machine_init_done_notifier(&s->machine_ready);
diff --git a/hw/ide/core.c b/hw/ide/core.c
index d6fb69c63..2620e87ae 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -557,15 +557,15 @@ void ide_dma_error(IDEState *s)
static int ide_handle_rw_error(IDEState *s, int error, int op)
{
int is_read = (op & BM_STATUS_RETRY_READ);
- BlockErrorAction action = bdrv_get_on_error(s->bs, is_read);
+ BlockdevOnError action = bdrv_get_on_error(s->bs, is_read);
- if (action == BLOCK_ERR_IGNORE) {
+ if (action == BLOCKDEV_ON_ERROR_IGNORE) {
bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_IGNORE, is_read);
return 0;
}
- if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
- || action == BLOCK_ERR_STOP_ANY) {
+ if ((error == ENOSPC && action == BLOCKDEV_ON_ERROR_ENOSPC)
+ || action == BLOCKDEV_ON_ERROR_STOP) {
s->bus->dma->ops->set_unit(s->bus->dma, s->unit);
s->bus->error_status = op;
bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_STOP, is_read);
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 62fe53ae2..59f1aa426 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -71,6 +71,8 @@ typedef struct IVShmemState {
MemoryRegion bar;
MemoryRegion ivshmem;
uint64_t ivshmem_size; /* size of shared memory region */
+ uint32_t ivshmem_attr;
+ uint32_t ivshmem_64bit;
int shm_fd; /* shared memory file descriptor */
Peer *peers;
@@ -339,7 +341,7 @@ static void create_shared_memory_BAR(IVShmemState *s, int fd) {
memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
/* region for shared memory */
- pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
+ pci_register_bar(&s->dev, 2, s->ivshmem_attr, &s->bar);
}
static void ivshmem_add_eventfd(IVShmemState *s, int posn, int i)
@@ -690,6 +692,11 @@ static int pci_ivshmem_init(PCIDevice *dev)
&s->ivshmem_mmio);
memory_region_init(&s->bar, "ivshmem-bar2-container", s->ivshmem_size);
+ s->ivshmem_attr = PCI_BASE_ADDRESS_SPACE_MEMORY |
+ PCI_BASE_ADDRESS_MEM_PREFETCH;
+ if (s->ivshmem_64bit) {
+ s->ivshmem_attr |= PCI_BASE_ADDRESS_MEM_TYPE_64;
+ }
if ((s->server_chr != NULL) &&
(strncmp(s->server_chr->filename, "unix:", 5) == 0)) {
@@ -715,8 +722,7 @@ static int pci_ivshmem_init(PCIDevice *dev)
/* allocate/initialize space for interrupt handling */
s->peers = g_malloc0(s->nb_peers * sizeof(Peer));
- pci_register_bar(&s->dev, 2,
- PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
+ pci_register_bar(&s->dev, 2, s->ivshmem_attr, &s->bar);
s->eventfd_chr = g_malloc0(s->vectors * sizeof(CharDriverState *));
@@ -786,6 +792,7 @@ static Property ivshmem_properties[] = {
DEFINE_PROP_BIT("msi", IVShmemState, features, IVSHMEM_MSI, true),
DEFINE_PROP_STRING("shm", IVShmemState, shmobj),
DEFINE_PROP_STRING("role", IVShmemState, role),
+ DEFINE_PROP_UINT32("use64", IVShmemState, ivshmem_64bit, 1),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 7229d2f16..1fc20cda9 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -369,14 +369,34 @@ static QEMUMachine pc_machine_v1_3 = {
.default_machine_opts = KVM_MACHINE_OPTIONS,
};
+#define PC_COMPAT_1_2 \
+ {\
+ .driver = "nec-usb-xhci",\
+ .property = "msi",\
+ .value = "off",\
+ },{\
+ .driver = "nec-usb-xhci",\
+ .property = "msix",\
+ .value = "off",\
+ },{\
+ .driver = "ivshmem",\
+ .property = "use64",\
+ .value = "0",\
+ }
+
static QEMUMachine pc_machine_v1_2 = {
.name = "pc-1.2",
.desc = "Standard PC",
.init = pc_init_pci,
.max_cpus = 255,
+ .compat_props = (GlobalProperty[]) {
+ PC_COMPAT_1_2,
+ { /* end of list */ }
+ },
};
#define PC_COMPAT_1_1 \
+ PC_COMPAT_1_2,\
{\
.driver = "virtio-scsi-pci",\
.property = "hotplug",\
diff --git a/hw/pl190.c b/hw/pl190.c
index cb50afb9f..7332f4dba 100644
--- a/hw/pl190.c
+++ b/hw/pl190.c
@@ -117,12 +117,18 @@ static uint64_t pl190_read(void *opaque, target_phys_addr_t offset,
return s->protected;
case 12: /* VECTADDR */
/* Read vector address at the start of an ISR. Increases the
- current priority level to that of the current interrupt. */
- for (i = 0; i < s->priority; i++)
- {
- if ((s->level | s->soft_level) & s->prio_mask[i])
- break;
- }
+ * current priority level to that of the current interrupt.
+ *
+ * Since an enabled interrupt X at priority P causes prio_mask[Y]
+ * to have bit X set for all Y > P, this loop will stop with
+ * i == the priority of the highest priority set interrupt.
+ */
+ for (i = 0; i < s->priority; i++) {
+ if ((s->level | s->soft_level) & s->prio_mask[i + 1]) {
+ break;
+ }
+ }
+
/* Reading this value with no pending interrupts is undefined.
We return the default address. */
if (i == PL190_NUM_PRIO)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 95e91585e..c295326e9 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -388,15 +388,15 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error)
{
int is_read = (r->req.cmd.xfer == SCSI_XFER_FROM_DEV);
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
- BlockErrorAction action = bdrv_get_on_error(s->qdev.conf.bs, is_read);
+ BlockdevOnError action = bdrv_get_on_error(s->qdev.conf.bs, is_read);
- if (action == BLOCK_ERR_IGNORE) {
+ if (action == BLOCKDEV_ON_ERROR_IGNORE) {
bdrv_emit_qmp_error_event(s->qdev.conf.bs, BDRV_ACTION_IGNORE, is_read);
return 0;
}
- if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
- || action == BLOCK_ERR_STOP_ANY) {
+ if ((error == ENOSPC && action == BLOCKDEV_ON_ERROR_ENOSPC)
+ || action == BLOCKDEV_ON_ERROR_STOP) {
bdrv_emit_qmp_error_event(s->qdev.conf.bs, BDRV_ACTION_STOP, is_read);
vm_stop(RUN_STATE_IO_ERROR);
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index a5eb663ec..d9045341b 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -400,11 +400,11 @@ static int scsi_generic_initfn(SCSIDevice *s)
return -1;
}
- if (bdrv_get_on_error(s->conf.bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
+ if (bdrv_get_on_error(s->conf.bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
error_report("Device doesn't support drive option werror");
return -1;
}
- if (bdrv_get_on_error(s->conf.bs, 1) != BLOCK_ERR_REPORT) {
+ if (bdrv_get_on_error(s->conf.bs, 1) != BLOCKDEV_ON_ERROR_REPORT) {
error_report("Device doesn't support drive option rerror");
return -1;
}
diff --git a/hw/vexpress.c b/hw/vexpress.c
index b6158447d..3596d1e33 100644
--- a/hw/vexpress.c
+++ b/hw/vexpress.c
@@ -29,8 +29,12 @@
#include "sysemu.h"
#include "boards.h"
#include "exec-memory.h"
+#include "blockdev.h"
+#include "flash.h"
#define VEXPRESS_BOARD_ID 0x8e0
+#define VEXPRESS_FLASH_SIZE (64 * 1024 * 1024)
+#define VEXPRESS_FLASH_SECT_SIZE (256 * 1024)
static struct arm_boot_info vexpress_binfo;
@@ -62,7 +66,6 @@ enum {
VE_COMPACTFLASH,
VE_CLCD,
VE_NORFLASH0,
- VE_NORFLASH0ALIAS,
VE_NORFLASH1,
VE_SRAM,
VE_VIDEORAM,
@@ -104,9 +107,8 @@ static target_phys_addr_t motherboard_legacy_map[] = {
};
static target_phys_addr_t motherboard_aseries_map[] = {
- /* CS0: 0x00000000 .. 0x0c000000 */
- [VE_NORFLASH0] = 0x00000000,
- [VE_NORFLASH0ALIAS] = 0x08000000,
+ /* CS0: 0x08000000 .. 0x0c000000 */
+ [VE_NORFLASH0] = 0x08000000,
/* CS4: 0x0c000000 .. 0x10000000 */
[VE_NORFLASH1] = 0x0c000000,
/* CS5: 0x10000000 .. 0x14000000 */
@@ -357,6 +359,7 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard,
qemu_irq pic[64];
uint32_t proc_id;
uint32_t sys_id;
+ DriveInfo *dinfo;
ram_addr_t vram_size, sram_size;
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *vram = g_new(MemoryRegion, 1);
@@ -412,9 +415,25 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard,
sysbus_create_simple("pl111", map[VE_CLCD], pic[14]);
- /* VE_NORFLASH0: not modelled */
- /* VE_NORFLASH0ALIAS: not modelled */
- /* VE_NORFLASH1: not modelled */
+ dinfo = drive_get_next(IF_PFLASH);
+ if (!pflash_cfi01_register(map[VE_NORFLASH0], NULL, "vexpress.flash0",
+ VEXPRESS_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL,
+ VEXPRESS_FLASH_SECT_SIZE,
+ VEXPRESS_FLASH_SIZE / VEXPRESS_FLASH_SECT_SIZE, 4,
+ 0x00, 0x89, 0x00, 0x18, 0)) {
+ fprintf(stderr, "vexpress: error registering flash 0.\n");
+ exit(1);
+ }
+
+ dinfo = drive_get_next(IF_PFLASH);
+ if (!pflash_cfi01_register(map[VE_NORFLASH1], NULL, "vexpress.flash1",
+ VEXPRESS_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL,
+ VEXPRESS_FLASH_SECT_SIZE,
+ VEXPRESS_FLASH_SIZE / VEXPRESS_FLASH_SECT_SIZE, 4,
+ 0x00, 0x89, 0x00, 0x18, 0)) {
+ fprintf(stderr, "vexpress: error registering flash 1.\n");
+ exit(1);
+ }
sram_size = 0x2000000;
memory_region_init_ram(sram, "vexpress.sram", sram_size);
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 6f6d172fd..f178fa86c 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -66,16 +66,16 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
int is_read)
{
- BlockErrorAction action = bdrv_get_on_error(req->dev->bs, is_read);
+ BlockdevOnError action = bdrv_get_on_error(req->dev->bs, is_read);
VirtIOBlock *s = req->dev;
- if (action == BLOCK_ERR_IGNORE) {
+ if (action == BLOCKDEV_ON_ERROR_IGNORE) {
bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_IGNORE, is_read);
return 0;
}
- if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
- || action == BLOCK_ERR_STOP_ANY) {
+ if ((error == ENOSPC && action == BLOCKDEV_ON_ERROR_ENOSPC)
+ || action == BLOCKDEV_ON_ERROR_STOP) {
req->next = s->rq;
s->rq = req;
bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_STOP, is_read);