]> git.proxmox.com Git - qemu.git/commitdiff
Merge remote-tracking branch 'cohuck/virtio-ccw-upstr' into staging
authorAnthony Liguori <aliguori@us.ibm.com>
Mon, 15 Jul 2013 19:02:41 +0000 (14:02 -0500)
committerAnthony Liguori <aliguori@us.ibm.com>
Mon, 15 Jul 2013 19:02:41 +0000 (14:02 -0500)
# By Dominik Dingel
# Via Cornelia Huck
* cohuck/virtio-ccw-upstr:
  virtio-ccw: Enable x-data-plane for virtio-ccw-blk

Message-id: 1373903207-27085-1-git-send-email-cornelia.huck@de.ibm.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
36 files changed:
block.c
block/sheepdog.c
blockdev.c
cpus.c
exec.c
hmp-commands.hx
hmp.c
hmp.h
hw/alpha/alpha_sys.h
hw/alpha/dp264.c
hw/alpha/pci.c
hw/alpha/typhoon.c
hw/arm/highbank.c
hw/arm/vexpress.c
hw/char/cadence_uart.c
hw/cpu/a15mpcore.c
hw/dma/omap_dma.c
hw/ide/ahci.c
hw/ide/core.c
hw/ide/internal.h
hw/sd/pl181.c
include/block/block.h
include/sysemu/sysemu.h
migration.c
qapi-schema.json
qemu-img.c
qmp-commands.hx
stubs/vm-stop.c
target-arm/cpu.c
target-arm/cpu.h
target-arm/helper.c
target-arm/translate.c
tests/qemu-iotests/051
tests/qemu-iotests/051.out
tests/qemu-iotests/055
tests/qemu-iotests/common.filter

diff --git a/block.c b/block.c
index 183fec8aa532f857fd785b7e8c855e184d0a3391..b56024113b8da3590066fa4726d644391698a3c2 100644 (file)
--- a/block.c
+++ b/block.c
@@ -417,7 +417,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
 {
     BlockDriver *drv;
 
-    drv = bdrv_find_protocol(filename);
+    drv = bdrv_find_protocol(filename, true);
     if (drv == NULL) {
         return -ENOENT;
     }
@@ -482,7 +482,8 @@ static BlockDriver *find_hdev_driver(const char *filename)
     return drv;
 }
 
-BlockDriver *bdrv_find_protocol(const char *filename)
+BlockDriver *bdrv_find_protocol(const char *filename,
+                                bool allow_protocol_prefix)
 {
     BlockDriver *drv1;
     char protocol[128];
@@ -503,9 +504,10 @@ BlockDriver *bdrv_find_protocol(const char *filename)
         return drv1;
     }
 
-    if (!path_has_protocol(filename)) {
+    if (!path_has_protocol(filename) || !allow_protocol_prefix) {
         return bdrv_find_format("file");
     }
+
     p = strchr(filename, ':');
     assert(p != NULL);
     len = p - filename;
@@ -784,6 +786,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
     BlockDriverState *bs;
     BlockDriver *drv;
     const char *drvname;
+    bool allow_protocol_prefix = false;
     int ret;
 
     /* NULL means an empty set of options */
@@ -800,6 +803,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
         filename = qdict_get_try_str(options, "filename");
     } else if (filename && !qdict_haskey(options, "filename")) {
         qdict_put(options, "filename", qstring_from_str(filename));
+        allow_protocol_prefix = true;
     } else {
         qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't specify 'file' and "
                       "'filename' options at the same time");
@@ -813,7 +817,10 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
         drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR));
         qdict_del(options, "driver");
     } else if (filename) {
-        drv = bdrv_find_protocol(filename);
+        drv = bdrv_find_protocol(filename, allow_protocol_prefix);
+        if (!drv) {
+            qerror_report(ERROR_CLASS_GENERIC_ERROR, "Unknown protocol");
+        }
     } else {
         qerror_report(ERROR_CLASS_GENERIC_ERROR,
                       "Must specify either driver or file");
@@ -2903,13 +2910,19 @@ int bdrv_get_flags(BlockDriverState *bs)
     return bs->open_flags;
 }
 
-void bdrv_flush_all(void)
+int bdrv_flush_all(void)
 {
     BlockDriverState *bs;
+    int result = 0;
 
     QTAILQ_FOREACH(bs, &bdrv_states, list) {
-        bdrv_flush(bs);
+        int ret = bdrv_flush(bs);
+        if (ret < 0 && !result) {
+            result = ret;
+        }
     }
+
+    return result;
 }
 
 int bdrv_has_zero_init_1(BlockDriverState *bs)
@@ -4452,7 +4465,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
         return;
     }
 
-    proto_drv = bdrv_find_protocol(filename);
+    proto_drv = bdrv_find_protocol(filename, true);
     if (!proto_drv) {
         error_setg(errp, "Unknown protocol '%s'", filename);
         return;
index b397b5b4d3188f774a08d79b79b860e189770cca..6a41ad9b3c15b5a79041614339aa74e61ee0feef 100644 (file)
@@ -1510,7 +1510,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
         BlockDriver *drv;
 
         /* Currently, only Sheepdog backing image is supported. */
-        drv = bdrv_find_protocol(backing_file);
+        drv = bdrv_find_protocol(backing_file, true);
         if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {
             error_report("backing_file must be a sheepdog image");
             ret = -EINVAL;
index b3a57e0c1d60b417bbe43d0cf5d8ef536b1d22dc..c5abd651821f191bf4eeb4e2ca66e546dc25c588 100644 (file)
@@ -936,6 +936,7 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
 
     qmp_drive_backup(backup->device, backup->target,
                      backup->has_format, backup->format,
+                     backup->sync,
                      backup->has_mode, backup->mode,
                      backup->has_speed, backup->speed,
                      backup->has_on_source_error, backup->on_source_error,
@@ -1421,6 +1422,7 @@ void qmp_block_commit(const char *device,
 
 void qmp_drive_backup(const char *device, const char *target,
                       bool has_format, const char *format,
+                      enum MirrorSyncMode sync,
                       bool has_mode, enum NewImageMode mode,
                       bool has_speed, int64_t speed,
                       bool has_on_source_error, BlockdevOnError on_source_error,
@@ -1435,6 +1437,10 @@ void qmp_drive_backup(const char *device, const char *target,
     int64_t size;
     int ret;
 
+    if (sync != MIRROR_SYNC_MODE_FULL) {
+        error_setg(errp, "only sync mode 'full' is currently supported");
+        return;
+    }
     if (!has_speed) {
         speed = 0;
     }
diff --git a/cpus.c b/cpus.c
index f1414282254298b3cbe7d5816bac5a0f53dc6f2b..29277e109f3bd828e41fe8beabcf58c6f781552b 100644 (file)
--- a/cpus.c
+++ b/cpus.c
@@ -434,17 +434,21 @@ bool cpu_is_stopped(CPUState *cpu)
     return !runstate_is_running() || cpu->stopped;
 }
 
-static void do_vm_stop(RunState state)
+static int do_vm_stop(RunState state)
 {
+    int ret = 0;
+
     if (runstate_is_running()) {
         cpu_disable_ticks();
         pause_all_vcpus();
         runstate_set(state);
         vm_state_notify(0, state);
         bdrv_drain_all();
-        bdrv_flush_all();
+        ret = bdrv_flush_all();
         monitor_protocol_event(QEVENT_STOP, NULL);
     }
+
+    return ret;
 }
 
 static bool cpu_can_run(CPUState *cpu)
@@ -1070,7 +1074,7 @@ void cpu_stop_current(void)
     }
 }
 
-void vm_stop(RunState state)
+int vm_stop(RunState state)
 {
     if (qemu_in_vcpu_thread()) {
         qemu_system_vmstop_request(state);
@@ -1079,19 +1083,21 @@ void vm_stop(RunState state)
          * vm_stop() has been requested.
          */
         cpu_stop_current();
-        return;
+        return 0;
     }
-    do_vm_stop(state);
+
+    return do_vm_stop(state);
 }
 
 /* does a state transition even if the VM is already stopped,
    current state is forgotten forever */
-void vm_stop_force_state(RunState state)
+int vm_stop_force_state(RunState state)
 {
     if (runstate_is_running()) {
-        vm_stop(state);
+        return vm_stop(state);
     } else {
         runstate_set(state);
+        return 0;
     }
 }
 
diff --git a/exec.c b/exec.c
index 80ee2abbc23191790d72abe7d9944dec02f2257a..c99a8839c5704a13292fd7325f2f688ace4adfcb 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -1896,15 +1896,37 @@ static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
     return false;
 }
 
-static inline int memory_access_size(MemoryRegion *mr, int l, hwaddr addr)
+static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr)
 {
-    if (l >= 4 && (((addr & 3) == 0 || mr->ops->impl.unaligned))) {
-        return 4;
+    unsigned access_size_min = mr->ops->impl.min_access_size;
+    unsigned access_size_max = mr->ops->impl.max_access_size;
+
+    /* Regions are assumed to support 1-4 byte accesses unless
+       otherwise specified.  */
+    if (access_size_min == 0) {
+        access_size_min = 1;
+    }
+    if (access_size_max == 0) {
+        access_size_max = 4;
+    }
+
+    /* Bound the maximum access by the alignment of the address.  */
+    if (!mr->ops->impl.unaligned) {
+        unsigned align_size_max = addr & -addr;
+        if (align_size_max != 0 && align_size_max < access_size_max) {
+            access_size_max = align_size_max;
+        }
     }
-    if (l >= 2 && (((addr & 1) == 0) || mr->ops->impl.unaligned)) {
-        return 2;
+
+    /* Don't attempt accesses larger than the maximum.  */
+    if (l > access_size_max) {
+        l = access_size_max;
     }
-    return 1;
+    /* ??? The users of this function are wrong, not supporting minimums larger
+       than the remaining length.  C.f. memory.c:access_with_adjusted_size.  */
+    assert(l >= access_size_min);
+
+    return l;
 }
 
 bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
@@ -1926,18 +1948,29 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                 l = memory_access_size(mr, l, addr1);
                 /* XXX: could force current_cpu to NULL to avoid
                    potential bugs */
-                if (l == 4) {
+                switch (l) {
+                case 8:
+                    /* 64 bit write access */
+                    val = ldq_p(buf);
+                    error |= io_mem_write(mr, addr1, val, 8);
+                    break;
+                case 4:
                     /* 32 bit write access */
                     val = ldl_p(buf);
                     error |= io_mem_write(mr, addr1, val, 4);
-                } else if (l == 2) {
+                    break;
+                case 2:
                     /* 16 bit write access */
                     val = lduw_p(buf);
                     error |= io_mem_write(mr, addr1, val, 2);
-                } else {
+                    break;
+                case 1:
                     /* 8 bit write access */
                     val = ldub_p(buf);
                     error |= io_mem_write(mr, addr1, val, 1);
+                    break;
+                default:
+                    abort();
                 }
             } else {
                 addr1 += memory_region_get_ram_addr(mr);
@@ -1950,18 +1983,29 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
             if (!memory_access_is_direct(mr, is_write)) {
                 /* I/O case */
                 l = memory_access_size(mr, l, addr1);
-                if (l == 4) {
+                switch (l) {
+                case 8:
+                    /* 64 bit read access */
+                    error |= io_mem_read(mr, addr1, &val, 8);
+                    stq_p(buf, val);
+                    break;
+                case 4:
                     /* 32 bit read access */
                     error |= io_mem_read(mr, addr1, &val, 4);
                     stl_p(buf, val);
-                } else if (l == 2) {
+                    break;
+                case 2:
                     /* 16 bit read access */
                     error |= io_mem_read(mr, addr1, &val, 2);
                     stw_p(buf, val);
-                } else {
+                    break;
+                case 1:
                     /* 8 bit read access */
                     error |= io_mem_read(mr, addr1, &val, 1);
                     stb_p(buf, val);
+                    break;
+                default:
+                    abort();
                 }
             } else {
                 /* RAM case */
index d1cdcfb71b9e0273ef819ee02e36731824285a00..8c6b91a9c70ce8ff5ef5421b1e7e7eed7da6665a 100644 (file)
@@ -1056,6 +1056,26 @@ STEXI
 @findex drive_mirror
 Start mirroring a block device's writes to a new destination,
 using the specified target.
+ETEXI
+
+    {
+        .name       = "drive_backup",
+        .args_type  = "reuse:-n,full:-f,device:B,target:s,format:s?",
+        .params     = "[-n] [-f] device target [format]",
+        .help       = "initiates a point-in-time\n\t\t\t"
+                      "copy for a device. The device's contents are\n\t\t\t"
+                      "copied to the new image file, excluding data that\n\t\t\t"
+                      "is written after the command is started.\n\t\t\t"
+                      "The -n flag requests QEMU to reuse the image found\n\t\t\t"
+                      "in new-image-file, instead of recreating it from scratch.\n\t\t\t"
+                      "The -f flag requests QEMU to copy the whole disk,\n\t\t\t"
+                      "so that the result does not need a backing file.\n\t\t\t",
+        .mhandler.cmd = hmp_drive_backup,
+    },
+STEXI
+@item drive_backup
+@findex drive_backup
+Start a point-in-time copy of a block device to a specificed target.
 ETEXI
 
     {
diff --git a/hmp.c b/hmp.c
index 2daed430d60e4beb1ed27a539b080541cbcb3099..dc4d8d453fe2a2af48048f4fd397c24e492bee19 100644 (file)
--- a/hmp.c
+++ b/hmp.c
@@ -907,6 +907,34 @@ void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, &errp);
 }
 
+void hmp_drive_backup(Monitor *mon, const QDict *qdict)
+{
+    const char *device = qdict_get_str(qdict, "device");
+    const char *filename = qdict_get_str(qdict, "target");
+    const char *format = qdict_get_try_str(qdict, "format");
+    int reuse = qdict_get_try_bool(qdict, "reuse", 0);
+    int full = qdict_get_try_bool(qdict, "full", 0);
+    enum NewImageMode mode;
+    Error *errp = NULL;
+
+    if (!filename) {
+        error_set(&errp, QERR_MISSING_PARAMETER, "target");
+        hmp_handle_error(mon, &errp);
+        return;
+    }
+
+    if (reuse) {
+        mode = NEW_IMAGE_MODE_EXISTING;
+    } else {
+        mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+    }
+
+    qmp_drive_backup(device, filename, !!format, format,
+                     full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
+                     true, mode, false, 0, false, 0, false, 0, &errp);
+    hmp_handle_error(mon, &errp);
+}
+
 void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
 {
     const char *device = qdict_get_str(qdict, "device");
diff --git a/hmp.h b/hmp.h
index 56d2e92aa65bfea3bfa7e03adfd9ccf7918a6435..6c3bdcd4c2fd6902a7eeea4012a368e485a99e7a 100644 (file)
--- a/hmp.h
+++ b/hmp.h
@@ -55,6 +55,7 @@ void hmp_balloon(Monitor *mon, const QDict *qdict);
 void hmp_block_resize(Monitor *mon, const QDict *qdict);
 void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict);
 void hmp_drive_mirror(Monitor *mon, const QDict *qdict);
+void hmp_drive_backup(Monitor *mon, const QDict *qdict);
 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
 void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict);
 void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict);
index 50e7730caaf514bca4771d49dc5326336baf08c4..e11025b4be603d3021d7911381185a07b061e86c 100644 (file)
@@ -14,7 +14,7 @@ PCIBus *typhoon_init(ram_addr_t, ISABus **, qemu_irq *, AlphaCPU *[4],
                      pci_map_irq_fn);
 
 /* alpha_pci.c.  */
-extern const MemoryRegionOps alpha_pci_bw_io_ops;
+extern const MemoryRegionOps alpha_pci_ignore_ops;
 extern const MemoryRegionOps alpha_pci_conf1_ops;
 extern const MemoryRegionOps alpha_pci_iack_ops;
 
index 8dad08fac28594a31a3d18221656f1e3dc278def..95fde615bec42d6496985620302f65ef30b5e005 100644 (file)
@@ -73,7 +73,9 @@ static void clipper_init(QEMUMachineInitArgs *args)
     pci_bus = typhoon_init(ram_size, &isa_bus, &rtc_irq, cpus,
                            clipper_pci_map_irq);
 
-    rtc_init(isa_bus, 1980, rtc_irq);
+    /* Since we have an SRM-compatible PALcode, use the SRM epoch.  */
+    rtc_init(isa_bus, 1900, rtc_irq);
+
     pit_init(isa_bus, 0x40, 0, NULL);
     isa_create_simple(isa_bus, "i8042");
 
index 7327d488fdb3bbdf7b6dee148c84e24320f55d14..d839dd556a5b0933d59aefea12d9999a87f45baa 100644 (file)
 #include "sysemu/sysemu.h"
 
 
-/* PCI IO reads/writes, to byte-word addressable memory.  */
-/* ??? Doesn't handle multiple PCI busses.  */
+/* Fallback for unassigned PCI I/O operations.  Avoids MCHK.  */
 
-static uint64_t bw_io_read(void *opaque, hwaddr addr, unsigned size)
+static uint64_t ignore_read(void *opaque, hwaddr addr, unsigned size)
 {
-    switch (size) {
-    case 1:
-        return cpu_inb(addr);
-    case 2:
-        return cpu_inw(addr);
-    case 4:
-        return cpu_inl(addr);
-    }
-    abort();
+    return 0;
 }
 
-static void bw_io_write(void *opaque, hwaddr addr,
-                        uint64_t val, unsigned size)
+static void ignore_write(void *opaque, hwaddr addr, uint64_t v, unsigned size)
 {
-    switch (size) {
-    case 1:
-        cpu_outb(addr, val);
-        break;
-    case 2:
-        cpu_outw(addr, val);
-        break;
-    case 4:
-        cpu_outl(addr, val);
-        break;
-    default:
-        abort();
-    }
 }
 
-const MemoryRegionOps alpha_pci_bw_io_ops = {
-    .read = bw_io_read,
-    .write = bw_io_write,
+const MemoryRegionOps alpha_pci_ignore_ops = {
+    .read = ignore_read,
+    .write = ignore_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 8,
+    },
     .impl = {
         .min_access_size = 1,
-        .max_access_size = 4,
+        .max_access_size = 8,
     },
 };
 
+
 /* PCI config space reads/writes, to byte-word addressable memory.  */
 static uint64_t bw_conf1_read(void *opaque, hwaddr addr,
                               unsigned size)
index 1c3ac8e172cfbe09bb6db7cc7b526110d60b53ce..3d7a1cd8e84a839ede6c6b2ff7c1f5b426593a88 100644 (file)
@@ -51,9 +51,6 @@ typedef struct TyphoonState {
     TyphoonPchip pchip;
     MemoryRegion dchip_region;
     MemoryRegion ram_region;
-
-    /* QEMU emulation state.  */
-    uint32_t latch_tmp;
 } TyphoonState;
 
 /* Called when one of DRIR or DIM changes.  */
@@ -76,10 +73,6 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
     TyphoonState *s = opaque;
     uint64_t ret = 0;
 
-    if (addr & 4) {
-        return s->latch_tmp;
-    }
-
     switch (addr) {
     case 0x0000:
         /* CSC: Cchip System Configuration Register.  */
@@ -199,7 +192,6 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
         return -1;
     }
 
-    s->latch_tmp = ret >> 32;
     return ret;
 }
 
@@ -214,10 +206,6 @@ static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
     TyphoonState *s = opaque;
     uint64_t ret = 0;
 
-    if (addr & 4) {
-        return s->latch_tmp;
-    }
-
     switch (addr) {
     case 0x0000:
         /* WSBA0: Window Space Base Address Register.  */
@@ -302,23 +290,14 @@ static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
         return -1;
     }
 
-    s->latch_tmp = ret >> 32;
     return ret;
 }
 
 static void cchip_write(void *opaque, hwaddr addr,
-                        uint64_t v32, unsigned size)
+                        uint64_t val, unsigned size)
 {
     TyphoonState *s = opaque;
-    uint64_t val, oldval, newval;
-
-    if (addr & 4) {
-        val = v32 << 32 | s->latch_tmp;
-        addr ^= 4;
-    } else {
-        s->latch_tmp = v32;
-        return;
-    }
+    uint64_t oldval, newval;
 
     switch (addr) {
     case 0x0000:
@@ -471,18 +450,10 @@ static void dchip_write(void *opaque, hwaddr addr,
 }
 
 static void pchip_write(void *opaque, hwaddr addr,
-                        uint64_t v32, unsigned size)
+                        uint64_t val, unsigned size)
 {
     TyphoonState *s = opaque;
-    uint64_t val, oldval;
-
-    if (addr & 4) {
-        val = v32 << 32 | s->latch_tmp;
-        addr ^= 4;
-    } else {
-        s->latch_tmp = v32;
-        return;
-    }
+    uint64_t oldval;
 
     switch (addr) {
     case 0x0000:
@@ -585,12 +556,12 @@ static const MemoryRegionOps cchip_ops = {
     .write = cchip_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
     .valid = {
-        .min_access_size = 4,  /* ??? Should be 8.  */
+        .min_access_size = 8,
         .max_access_size = 8,
     },
     .impl = {
-        .min_access_size = 4,
-        .max_access_size = 4,
+        .min_access_size = 8,
+        .max_access_size = 8,
     },
 };
 
@@ -599,11 +570,11 @@ static const MemoryRegionOps dchip_ops = {
     .write = dchip_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
     .valid = {
-        .min_access_size = 4,  /* ??? Should be 8.  */
+        .min_access_size = 8,
         .max_access_size = 8,
     },
     .impl = {
-        .min_access_size = 4,
+        .min_access_size = 8,
         .max_access_size = 8,
     },
 };
@@ -613,12 +584,12 @@ static const MemoryRegionOps pchip_ops = {
     .write = pchip_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
     .valid = {
-        .min_access_size = 4,  /* ??? Should be 8.  */
+        .min_access_size = 8,
         .max_access_size = 8,
     },
     .impl = {
-        .min_access_size = 4,
-        .max_access_size = 4,
+        .min_access_size = 8,
+        .max_access_size = 8,
     },
 };
 
@@ -705,7 +676,6 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
     const uint64_t MB = 1024 * 1024;
     const uint64_t GB = 1024 * MB;
     MemoryRegion *addr_space = get_system_memory();
-    MemoryRegion *addr_space_io = get_system_io();
     DeviceState *dev;
     TyphoonState *s;
     PCIHostState *phb;
@@ -765,28 +735,26 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
                                 &s->pchip.reg_mem);
 
     /* Pchip0 PCI I/O, 0x801.FC00.0000, 32MB.  */
-    /* ??? Ideally we drop the "system" i/o space on the floor and give the
-       PCI subsystem the full address space reserved by the chipset.
-       We can't do that until the MEM and IO paths in memory.c are unified.  */
-    memory_region_init_io(&s->pchip.reg_io, OBJECT(s), &alpha_pci_bw_io_ops,
+    memory_region_init_io(&s->pchip.reg_io, OBJECT(s), &alpha_pci_ignore_ops,
                           NULL, "pci0-io", 32*MB);
     memory_region_add_subregion(addr_space, 0x801fc000000ULL,
                                 &s->pchip.reg_io);
 
     b = pci_register_bus(dev, "pci",
                          typhoon_set_irq, sys_map_irq, s,
-                         &s->pchip.reg_mem, addr_space_io, 0, 64, TYPE_PCI_BUS);
+                         &s->pchip.reg_mem, &s->pchip.reg_io,
+                         0, 64, TYPE_PCI_BUS);
     phb->bus = b;
 
     /* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB.  */
-    memory_region_init_io(&s->pchip.reg_iack, OBJECT(s), &alpha_pci_iack_ops, b,
-                          "pci0-iack", 64*MB);
+    memory_region_init_io(&s->pchip.reg_iack, OBJECT(s), &alpha_pci_iack_ops,
+                          b, "pci0-iack", 64*MB);
     memory_region_add_subregion(addr_space, 0x801f8000000ULL,
                                 &s->pchip.reg_iack);
 
     /* Pchip0 PCI configuration, 0x801.FE00.0000, 16MB.  */
-    memory_region_init_io(&s->pchip.reg_conf, OBJECT(s), &alpha_pci_conf1_ops, b,
-                          "pci0-conf", 16*MB);
+    memory_region_init_io(&s->pchip.reg_conf, OBJECT(s), &alpha_pci_conf1_ops,
+                          b, "pci0-conf", 16*MB);
     memory_region_add_subregion(addr_space, 0x801fe000000ULL,
                                 &s->pchip.reg_conf);
 
@@ -804,7 +772,7 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
     {
         qemu_irq isa_pci_irq, *isa_irqs;
 
-        *isa_bus = isa_bus_new(NULL, addr_space_io);
+        *isa_bus = isa_bus_new(NULL, &s->pchip.reg_io);
         isa_pci_irq = *qemu_allocate_irqs(typhoon_set_isa_irq, s, 1);
         isa_irqs = i8259_init(*isa_bus, isa_pci_irq);
         isa_bus_irqs(*isa_bus, isa_irqs);
index 3a2fb4c81c9be2a4931a14d40daf6b6e2613ab73..be264d3eb35a268969836769f2603736bd89bba2 100644 (file)
@@ -183,20 +183,25 @@ type_init(highbank_regs_register_types)
 
 static struct arm_boot_info highbank_binfo;
 
+enum cxmachines {
+    CALXEDA_HIGHBANK,
+    CALXEDA_MIDWAY,
+};
+
 /* ram_size must be set to match the upper bound of memory in the
  * device tree (linux/arch/arm/boot/dts/highbank.dts), which is
  * normally 0xff900000 or -m 4089. When running this board on a
  * 32-bit host, set the reg value of memory to 0xf7ff00000 in the
  * device tree and pass -m 2047 to QEMU.
  */
-static void highbank_init(QEMUMachineInitArgs *args)
+static void calxeda_init(QEMUMachineInitArgs *args, enum cxmachines machine)
 {
     ram_addr_t ram_size = args->ram_size;
     const char *cpu_model = args->cpu_model;
     const char *kernel_filename = args->kernel_filename;
     const char *kernel_cmdline = args->kernel_cmdline;
     const char *initrd_filename = args->initrd_filename;
-    DeviceState *dev;
+    DeviceState *dev = NULL;
     SysBusDevice *busdev;
     qemu_irq *irqp;
     qemu_irq pic[128];
@@ -208,7 +213,14 @@ static void highbank_init(QEMUMachineInitArgs *args)
     char *sysboot_filename;
 
     if (!cpu_model) {
-        cpu_model = "cortex-a9";
+        switch (machine) {
+        case CALXEDA_HIGHBANK:
+            cpu_model = "cortex-a9";
+            break;
+        case CALXEDA_MIDWAY:
+            cpu_model = "cortex-a15";
+            break;
+        }
     }
 
     for (n = 0; n < smp_cpus; n++) {
@@ -246,7 +258,19 @@ static void highbank_init(QEMUMachineInitArgs *args)
         }
     }
 
-    dev = qdev_create(NULL, "a9mpcore_priv");
+    switch (machine) {
+    case CALXEDA_HIGHBANK:
+        dev = qdev_create(NULL, "l2x0");
+        qdev_init_nofail(dev);
+        busdev = SYS_BUS_DEVICE(dev);
+        sysbus_mmio_map(busdev, 0, 0xfff12000);
+
+        dev = qdev_create(NULL, "a9mpcore_priv");
+        break;
+    case CALXEDA_MIDWAY:
+        dev = qdev_create(NULL, "a15mpcore_priv");
+        break;
+    }
     qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
     qdev_prop_set_uint32(dev, "num-irq", NIRQ_GIC);
     qdev_init_nofail(dev);
@@ -260,11 +284,6 @@ static void highbank_init(QEMUMachineInitArgs *args)
         pic[n] = qdev_get_gpio_in(dev, n);
     }
 
-    dev = qdev_create(NULL, "l2x0");
-    qdev_init_nofail(dev);
-    busdev = SYS_BUS_DEVICE(dev);
-    sysbus_mmio_map(busdev, 0, 0xfff12000);
-
     dev = qdev_create(NULL, "sp804");
     qdev_prop_set_uint32(dev, "freq0", 150000000);
     qdev_prop_set_uint32(dev, "freq1", 150000000);
@@ -324,6 +343,16 @@ static void highbank_init(QEMUMachineInitArgs *args)
     arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo);
 }
 
+static void highbank_init(QEMUMachineInitArgs *args)
+{
+    calxeda_init(args, CALXEDA_HIGHBANK);
+}
+
+static void midway_init(QEMUMachineInitArgs *args)
+{
+    calxeda_init(args, CALXEDA_MIDWAY);
+}
+
 static QEMUMachine highbank_machine = {
     .name = "highbank",
     .desc = "Calxeda Highbank (ECX-1000)",
@@ -333,9 +362,19 @@ static QEMUMachine highbank_machine = {
     DEFAULT_MACHINE_OPTIONS,
 };
 
-static void highbank_machine_init(void)
+static QEMUMachine midway_machine = {
+    .name = "midway",
+    .desc = "Calxeda Midway (ECX-2000)",
+    .init = midway_init,
+    .block_default_type = IF_SCSI,
+    .max_cpus = 4,
+    DEFAULT_MACHINE_OPTIONS,
+};
+
+static void calxeda_machines_init(void)
 {
     qemu_register_machine(&highbank_machine);
+    qemu_register_machine(&midway_machine);
 }
 
-machine_init(highbank_machine_init);
+machine_init(calxeda_machines_init);
index fd18b605328e1d4e72825b0d7d1685f90a7ac300..7d1b8233cd28f733dcbbd321fd6967467740eea9 100644 (file)
@@ -67,6 +67,7 @@ enum {
     VE_CLCD,
     VE_NORFLASH0,
     VE_NORFLASH1,
+    VE_NORFLASHALIAS,
     VE_SRAM,
     VE_VIDEORAM,
     VE_ETHERNET,
@@ -104,9 +105,11 @@ static hwaddr motherboard_legacy_map[] = {
     [VE_VIDEORAM] = 0x4c000000,
     [VE_ETHERNET] = 0x4e000000,
     [VE_USB] = 0x4f000000,
+    [VE_NORFLASHALIAS] = -1, /* not present */
 };
 
 static hwaddr motherboard_aseries_map[] = {
+    [VE_NORFLASHALIAS] = 0,
     /* CS0: 0x08000000 .. 0x0c000000 */
     [VE_NORFLASH0] = 0x08000000,
     /* CS4: 0x0c000000 .. 0x10000000 */
@@ -400,10 +403,13 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard,
     qemu_irq pic[64];
     uint32_t sys_id;
     DriveInfo *dinfo;
+    pflash_t *pflash0;
     ram_addr_t vram_size, sram_size;
     MemoryRegion *sysmem = get_system_memory();
     MemoryRegion *vram = g_new(MemoryRegion, 1);
     MemoryRegion *sram = g_new(MemoryRegion, 1);
+    MemoryRegion *flashalias = g_new(MemoryRegion, 1);
+    MemoryRegion *flash0mem;
     const hwaddr *map = daughterboard->motherboard_map;
     int i;
 
@@ -471,15 +477,24 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard,
     sysbus_create_simple("pl111", map[VE_CLCD], pic[14]);
 
     dinfo = drive_get_next(IF_PFLASH);
-    if (!pflash_cfi01_register(map[VE_NORFLASH0], NULL, "vexpress.flash0",
+    pflash0 = 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)) {
+            0x00, 0x89, 0x00, 0x18, 0);
+    if (!pflash0) {
         fprintf(stderr, "vexpress: error registering flash 0.\n");
         exit(1);
     }
 
+    if (map[VE_NORFLASHALIAS] != -1) {
+        /* Map flash 0 as an alias into low memory */
+        flash0mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pflash0), 0);
+        memory_region_init_alias(flashalias, NULL, "vexpress.flashalias",
+                                 flash0mem, 0, VEXPRESS_FLASH_SIZE);
+        memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], flashalias);
+    }
+
     dinfo = drive_get_next(IF_PFLASH);
     if (!pflash_cfi01_register(map[VE_NORFLASH1], NULL, "vexpress.flash1",
             VEXPRESS_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL,
index 131370a74bc3afa95c3a9052349be7f7ab812e35..4d457f8c65e9d6afdfa5097093d67f262c122864 100644 (file)
@@ -157,7 +157,9 @@ static void uart_rx_reset(UartState *s)
 {
     s->rx_wpos = 0;
     s->rx_count = 0;
-    qemu_chr_accept_input(s->chr);
+    if (s->chr) {
+        qemu_chr_accept_input(s->chr);
+    }
 
     s->r[R_SR] |= UART_SR_INTR_REMPTY;
     s->r[R_SR] &= ~UART_SR_INTR_RFUL;
index 967b0809f36b70a1eafb02278a60e924478ef8ce..c736257f24b786c7d7052a63c278d1698e630115 100644 (file)
@@ -82,12 +82,12 @@ static int a15mp_priv_init(SysBusDevice *dev)
 static Property a15mp_priv_properties[] = {
     DEFINE_PROP_UINT32("num-cpu", A15MPPrivState, num_cpu, 1),
     /* The Cortex-A15MP may have anything from 0 to 224 external interrupt
-     * IRQ lines (with another 32 internal). We default to 64+32, which
+     * IRQ lines (with another 32 internal). We default to 128+32, which
      * is the number provided by the Cortex-A15MP test chip in the
      * Versatile Express A15 development board.
      * Other boards may differ and should set this property appropriately.
      */
-    DEFINE_PROP_UINT32("num-irq", A15MPPrivState, num_irq, 96),
+    DEFINE_PROP_UINT32("num-irq", A15MPPrivState, num_irq, 160),
     DEFINE_PROP_END_OF_LIST(),
 };
 
index a81ffc40265ac905253e5272c58de7f96319ce9b..0e8cccd27f503abaec9b72f7c7f222cf4ea8e316 100644 (file)
@@ -248,7 +248,7 @@ static void omap_dma_deactivate_channel(struct omap_dma_s *s,
 
     /* Don't deactive the channel if it is synchronized and the DMA request is
        active */
-    if (ch->sync && ch->enable && (s->dma->drqbmp & (1 << ch->sync)))
+    if (ch->sync && ch->enable && (s->dma->drqbmp & (1ULL << ch->sync)))
         return;
 
     if (ch->active) {
@@ -268,8 +268,9 @@ static void omap_dma_enable_channel(struct omap_dma_s *s,
         /* TODO: theoretically if ch->sync && ch->prefetch &&
          * !s->dma->drqbmp[ch->sync], we should also activate and fetch
          * from source and then stall until signalled.  */
-        if ((!ch->sync) || (s->dma->drqbmp & (1 << ch->sync)))
+        if ((!ch->sync) || (s->dma->drqbmp & (1ULL << ch->sync))) {
             omap_dma_activate_channel(s, ch);
+        }
     }
 }
 
@@ -1551,12 +1552,12 @@ static void omap_dma_request(void *opaque, int drq, int req)
     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
     /* The request pins are level triggered in QEMU.  */
     if (req) {
-        if (~s->dma->drqbmp & (1 << drq)) {
-            s->dma->drqbmp |= 1 << drq;
+        if (~s->dma->drqbmp & (1ULL << drq)) {
+            s->dma->drqbmp |= 1ULL << drq;
             omap_dma_process_request(s, drq);
         }
     } else
-        s->dma->drqbmp &= ~(1 << drq);
+        s->dma->drqbmp &= ~(1ULL << drq);
 }
 
 /* XXX: this won't be needed once soc_dma knows about clocks.  */
index 97eddec920268322224358cbc5afb2def36442e5..1d863b5784272ca006e8b400de60683a64abf370 100644 (file)
@@ -1106,10 +1106,15 @@ static int ahci_dma_add_status(IDEDMA *dma, int status)
 }
 
 static int ahci_dma_set_inactive(IDEDMA *dma)
+{
+    return 0;
+}
+
+static int ahci_async_cmd_done(IDEDMA *dma)
 {
     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
 
-    DPRINTF(ad->port_no, "dma done\n");
+    DPRINTF(ad->port_no, "async cmd done\n");
 
     /* update d2h status */
     ahci_write_fis_d2h(ad, NULL);
@@ -1144,6 +1149,7 @@ static const IDEDMAOps ahci_dma_ops = {
     .set_unit = ahci_dma_set_unit,
     .add_status = ahci_dma_add_status,
     .set_inactive = ahci_dma_set_inactive,
+    .async_cmd_done = ahci_async_cmd_done,
     .restart_cb = ahci_dma_restart_cb,
     .reset = ahci_dma_reset,
 };
index 03d1cfa7d241ab443baf382d775e3e4b71905505..a73af7252ac0c42ced9e66868258a4efcfbea490 100644 (file)
@@ -568,10 +568,18 @@ static void dma_buf_commit(IDEState *s)
     qemu_sglist_destroy(&s->sg);
 }
 
+static void ide_async_cmd_done(IDEState *s)
+{
+    if (s->bus->dma->ops->async_cmd_done) {
+        s->bus->dma->ops->async_cmd_done(s->bus->dma);
+    }
+}
+
 void ide_set_inactive(IDEState *s)
 {
     s->bus->dma->aiocb = NULL;
     s->bus->dma->ops->set_inactive(s->bus->dma);
+    ide_async_cmd_done(s);
 }
 
 void ide_dma_error(IDEState *s)
@@ -804,6 +812,7 @@ static void ide_flush_cb(void *opaque, int ret)
 
     bdrv_acct_done(s->bs, &s->acct);
     s->status = READY_STAT | SEEK_STAT;
+    ide_async_cmd_done(s);
     ide_set_irq(s->bus);
 }
 
index 03f14896d6ef97f4f3968e80080b7eef3914bd0e..048a052143534b19d315dd8d2d36fc6704d0df98 100644 (file)
@@ -433,6 +433,7 @@ struct IDEDMAOps {
     DMAIntFunc *set_unit;
     DMAIntFunc *add_status;
     DMAFunc *set_inactive;
+    DMAFunc *async_cmd_done;
     DMARestartFunc *restart_cb;
     DMAFunc *reset;
 };
index 4b1723418d3238f34cf6b9bd35f0a1107d97f934..f5eb1e40120c6a9572b48ba3d135b7c9d9734ab3 100644 (file)
@@ -175,7 +175,7 @@ static void pl181_send_command(pl181_state *s)
     if (rlen < 0)
         goto error;
     if (s->cmd & PL181_CMD_RESPONSE) {
-#define RWORD(n) ((response[n] << 24) | (response[n + 1] << 16) \
+#define RWORD(n) (((uint32_t)response[n] << 24) | (response[n + 1] << 16) \
                   | (response[n + 2] << 8) | response[n + 3])
         if (rlen == 0 || (rlen == 4 && (s->cmd & PL181_CMD_LONGRESP)))
             goto error;
index dd8eca1be16e26c95fac96d1c9adfa1866ec3a56..b6b9014a9ce9392869eb547ec9fcd241fea8cd03 100644 (file)
@@ -111,7 +111,8 @@ bool bdrv_io_limits_enabled(BlockDriverState *bs);
 
 void bdrv_init(void);
 void bdrv_init_with_whitelist(void);
-BlockDriver *bdrv_find_protocol(const char *filename);
+BlockDriver *bdrv_find_protocol(const char *filename,
+                                bool allow_protocol_prefix);
 BlockDriver *bdrv_find_format(const char *format_name);
 BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
                                           bool readonly);
@@ -266,7 +267,7 @@ void bdrv_clear_incoming_migration_all(void);
 /* Ensure contents are flushed to disk.  */
 int bdrv_flush(BlockDriverState *bs);
 int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
-void bdrv_flush_all(void);
+int bdrv_flush_all(void);
 void bdrv_close_all(void);
 void bdrv_drain_all(void);
 
index d85bdc0cacb8dba58c6d6631afc46058697b1a7a..3caeb66eb2fe910fac6565ddc8f015d782d05ce0 100644 (file)
@@ -35,8 +35,8 @@ void vm_state_notify(int running, RunState state);
 #define VMRESET_REPORT   true
 
 void vm_start(void);
-void vm_stop(RunState state);
-void vm_stop_force_state(RunState state);
+int vm_stop(RunState state);
+int vm_stop_force_state(RunState state);
 
 typedef enum WakeupReason {
     QEMU_WAKEUP_REASON_OTHER = 0,
index 635a7e7a08be67d194cc612d69b2fc36d6286a20..0681d8e5f18b145c7fbeea90a1c42a65f360b0b1 100644 (file)
@@ -527,15 +527,26 @@ static void *migration_thread(void *opaque)
             if (pending_size && pending_size >= max_size) {
                 qemu_savevm_state_iterate(s->file);
             } else {
+                int ret;
+
                 DPRINTF("done iterating\n");
                 qemu_mutex_lock_iothread();
                 start_time = qemu_get_clock_ms(rt_clock);
                 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
                 old_vm_running = runstate_is_running();
-                vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
-                qemu_file_set_rate_limit(s->file, INT_MAX);
-                qemu_savevm_state_complete(s->file);
+
+                ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
+                if (ret >= 0) {
+                    qemu_file_set_rate_limit(s->file, INT_MAX);
+                    qemu_savevm_state_complete(s->file);
+                }
                 qemu_mutex_unlock_iothread();
+
+                if (ret < 0) {
+                    migrate_finish_set_state(s, MIG_STATE_ERROR);
+                    break;
+                }
+
                 if (!qemu_file_get_error(s->file)) {
                     migrate_finish_set_state(s, MIG_STATE_COMPLETED);
                     break;
index b251d282cc8790303167780e8a16fdc5194574ad..cf57783cafdd2b642434607c81d14f89ccf4b6f7 100644 (file)
 # @format: #optional the format of the new destination, default is to
 #          probe if @mode is 'existing', else the format of the source
 #
+# @sync: what parts of the disk image should be copied to the destination
+#        (all the disk, only the sectors allocated in the topmost image, or
+#        only new I/O).
+#
 # @mode: #optional whether and how QEMU should create a new image, default is
 #        'absolute-paths'.
 #
 ##
 { 'type': 'DriveBackup',
   'data': { 'device': 'str', 'target': 'str', '*format': 'str',
-            '*mode': 'NewImageMode', '*speed': 'int',
+            'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',
+            '*speed': 'int',
             '*on-source-error': 'BlockdevOnError',
             '*on-target-error': 'BlockdevOnError' } }
 
index f8c97d34d11abbb43a00a0c12fa5b5684d490c34..c55ca5c557fad76aa1acc890bdfd8546557b8280 100644 (file)
@@ -240,7 +240,7 @@ static int print_block_option_help(const char *filename, const char *fmt)
         return 1;
     }
 
-    proto_drv = bdrv_find_protocol(filename);
+    proto_drv = bdrv_find_protocol(filename, true);
     if (!proto_drv) {
         error_report("Unknown protocol '%s'", filename);
         return 1;
@@ -1261,7 +1261,7 @@ static int img_convert(int argc, char **argv)
         goto out;
     }
 
-    proto_drv = bdrv_find_protocol(out_filename);
+    proto_drv = bdrv_find_protocol(out_filename, true);
     if (!proto_drv) {
         error_report("Unknown protocol '%s'", out_filename);
         ret = -1;
index 362f0e1ef862c3bae7c97c77e373c5912dc59cca..e075df423ab3faaca4ab3026eaf94a04c3f22674 100644 (file)
@@ -913,7 +913,7 @@ EQMP
 
     {
         .name       = "drive-backup",
-        .args_type  = "device:B,target:s,speed:i?,mode:s?,format:s?,"
+        .args_type  = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
                       "on-source-error:s?,on-target-error:s?",
         .mhandler.cmd_new = qmp_marshal_input_drive_backup,
     },
@@ -939,6 +939,10 @@ Arguments:
 - "format": the format of the new destination, default is to probe if 'mode' is
             'existing', else the format of the source
             (json-string, optional)
+- "sync": what parts of the disk image should be copied to the destination;
+  possibilities include "full" for all the disk, "top" for only the sectors
+  allocated in the topmost image, or "none" to only replicate new I/O
+  (MirrorSyncMode).
 - "mode": whether and how QEMU should create a new image
           (NewImageMode, optional, default 'absolute-paths')
 - "speed": the maximum speed, in bytes per second (json-int, optional)
index 45689354f663ca64695355c6c01b44a7535d3d37..f82c897dfe805496e34616f2ca36405125065cd8 100644 (file)
@@ -1,7 +1,7 @@
 #include "qemu-common.h"
 #include "sysemu/sysemu.h"
 
-void vm_stop(RunState state)
+int vm_stop(RunState state)
 {
     abort();
 }
index be26acc38db29769e3c1f4072d6537ffd7e4c1a4..9f1696f933877eee8460671557cf7bb5b24e9607 100644 (file)
@@ -157,6 +157,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
     CPUARMState *env = &cpu->env;
 
     /* Some features automatically imply others: */
+    if (arm_feature(env, ARM_FEATURE_V8)) {
+        set_feature(env, ARM_FEATURE_V7);
+        set_feature(env, ARM_FEATURE_ARM_DIV);
+        set_feature(env, ARM_FEATURE_LPAE);
+    }
     if (arm_feature(env, ARM_FEATURE_V7)) {
         set_feature(env, ARM_FEATURE_VAPA);
         set_feature(env, ARM_FEATURE_THUMB2);
@@ -744,7 +749,7 @@ static void pxa270c5_initfn(Object *obj)
 static void arm_any_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
-    set_feature(&cpu->env, ARM_FEATURE_V7);
+    set_feature(&cpu->env, ARM_FEATURE_V8);
     set_feature(&cpu->env, ARM_FEATURE_VFP4);
     set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
     set_feature(&cpu->env, ARM_FEATURE_NEON);
index 1369604d65c6979a260c16ae1056d3c8d3abc020..c798b272a02a9e13b694d7d3faa9ecdfd05c3448 100644 (file)
@@ -387,6 +387,7 @@ enum arm_features {
     ARM_FEATURE_MPIDR, /* has cp15 MPIDR */
     ARM_FEATURE_PXN, /* has Privileged Execute Never bit */
     ARM_FEATURE_LPAE, /* has Large Physical Address Extension */
+    ARM_FEATURE_V8,
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
index 5f639fdeb80122bc891096f609c7de99c7fdcfe9..aeae0241650489005e28181c3ad7c28c10c2120e 100644 (file)
@@ -222,15 +222,23 @@ static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
     return aidx - bidx;
 }
 
+static void cpreg_make_keylist(gpointer key, gpointer value, gpointer udata)
+{
+    GList **plist = udata;
+
+    *plist = g_list_prepend(*plist, key);
+}
+
 void init_cpreg_list(ARMCPU *cpu)
 {
     /* Initialise the cpreg_tuples[] array based on the cp_regs hash.
      * Note that we require cpreg_tuples[] to be sorted by key ID.
      */
-    GList *keys;
+    GList *keys = NULL;
     int arraylen;
 
-    keys = g_hash_table_get_keys(cpu->cp_regs);
+    g_hash_table_foreach(cpu->cp_regs, cpreg_make_keylist, &keys);
+
     keys = g_list_sort(keys, cpreg_key_compare);
 
     cpu->cpreg_array_len = 0;
@@ -891,6 +899,8 @@ static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
 static int vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
                                 uint64_t value)
 {
+    int maskshift = extract32(value, 0, 3);
+
     if (arm_feature(env, ARM_FEATURE_LPAE)) {
         value &= ~((7 << 19) | (3 << 14) | (0xf << 3));
     } else {
@@ -902,8 +912,8 @@ static int vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
      * and the c2_mask and c2_base_mask values are meaningless.
      */
     env->cp15.c2_control = value;
-    env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> value);
-    env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> value);
+    env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> maskshift);
+    env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> maskshift);
     return 0;
 }
 
@@ -1378,9 +1388,6 @@ void register_cp_regs_for_features(ARMCPU *cpu)
     if (arm_feature(env, ARM_FEATURE_DUMMY_C15_REGS)) {
         define_arm_cp_regs(cpu, dummy_c15_cp_reginfo);
     }
-    if (arm_feature(env, ARM_FEATURE_MPIDR)) {
-        define_arm_cp_regs(cpu, mpidr_cp_reginfo);
-    }
     if (arm_feature(env, ARM_FEATURE_LPAE)) {
         define_arm_cp_regs(cpu, lpae_cp_reginfo);
     }
@@ -1393,12 +1400,17 @@ void register_cp_regs_for_features(ARMCPU *cpu)
             /* Note that the MIDR isn't a simple constant register because
              * of the TI925 behaviour where writes to another register can
              * cause the MIDR value to change.
+             *
+             * Unimplemented registers in the c15 0 0 0 space default to
+             * MIDR. Define MIDR first as this entire space, then CTR, TCMTR
+             * and friends override accordingly.
              */
             { .name = "MIDR",
-              .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
+              .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = CP_ANY,
               .access = PL1_R, .resetvalue = cpu->midr,
               .writefn = arm_cp_write_ignore, .raw_writefn = raw_write,
-              .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid) },
+              .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
+              .type = ARM_CP_OVERRIDE },
             { .name = "CTR",
               .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
               .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
@@ -1435,21 +1447,20 @@ void register_cp_regs_for_features(ARMCPU *cpu)
             arm_feature(env, ARM_FEATURE_STRONGARM)) {
             ARMCPRegInfo *r;
             /* Register the blanket "writes ignored" value first to cover the
-             * whole space. Then define the specific ID registers, but update
-             * their access field to allow write access, so that they ignore
-             * writes rather than causing them to UNDEF.
+             * whole space. Then update the specific ID registers to allow write
+             * access, so that they ignore writes rather than causing them to
+             * UNDEF.
              */
             define_one_arm_cp_reg(cpu, &crn0_wi_reginfo);
             for (r = id_cp_reginfo; r->type != ARM_CP_SENTINEL; r++) {
                 r->access = PL1_RW;
-                define_one_arm_cp_reg(cpu, r);
             }
-        } else {
-            /* Just register the standard ID registers (read-only, meaning
-             * that writes will UNDEF).
-             */
-            define_arm_cp_regs(cpu, id_cp_reginfo);
         }
+        define_arm_cp_regs(cpu, id_cp_reginfo);
+    }
+
+    if (arm_feature(env, ARM_FEATURE_MPIDR)) {
+        define_arm_cp_regs(cpu, mpidr_cp_reginfo);
     }
 
     if (arm_feature(env, ARM_FEATURE_AUXCR)) {
@@ -1607,7 +1618,9 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
                 ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
                 int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
                 *key = ENCODE_CP_REG(r->cp, is64, r->crn, crm, opc1, opc2);
-                r2->opaque = opaque;
+                if (opaque) {
+                    r2->opaque = opaque;
+                }
                 /* Make sure reginfo passed to helpers for wildcarded regs
                  * has the correct crm/opc1/opc2 for this reg, not CP_ANY:
                  */
index 9310c586de502538b762bb69c1842811f4cbce84..7b50c8c308ca2c78b42161b99bf68d81cd9f18d4 100644 (file)
@@ -42,6 +42,7 @@
 #define ENABLE_ARCH_6K   arm_feature(env, ARM_FEATURE_V6K)
 #define ENABLE_ARCH_6T2   arm_feature(env, ARM_FEATURE_THUMB2)
 #define ENABLE_ARCH_7     arm_feature(env, ARM_FEATURE_V7)
+#define ENABLE_ARCH_8     arm_feature(env, ARM_FEATURE_V8)
 
 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
 
@@ -3500,7 +3501,8 @@ static void gen_nop_hint(DisasContext *s, int val)
         break;
     case 2: /* wfe */
     case 4: /* sev */
-        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
+    case 5: /* sevl */
+        /* TODO: Implement SEV, SEVL and WFE.  May help SMP performance.  */
     default: /* nop */
         break;
     }
@@ -7273,14 +7275,72 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
                     rd = (insn >> 12) & 0xf;
                     if (insn & (1 << 23)) {
                         /* load/store exclusive */
+                        int op2 = (insn >> 8) & 3;
                         op1 = (insn >> 21) & 0x3;
-                        if (op1)
-                            ARCH(6K);
-                        else
-                            ARCH(6);
+
+                        switch (op2) {
+                        case 0: /* lda/stl */
+                            if (op1 == 1) {
+                                goto illegal_op;
+                            }
+                            ARCH(8);
+                            break;
+                        case 1: /* reserved */
+                            goto illegal_op;
+                        case 2: /* ldaex/stlex */
+                            ARCH(8);
+                            break;
+                        case 3: /* ldrex/strex */
+                            if (op1) {
+                                ARCH(6K);
+                            } else {
+                                ARCH(6);
+                            }
+                            break;
+                        }
+
                         addr = tcg_temp_local_new_i32();
                         load_reg_var(s, addr, rn);
-                        if (insn & (1 << 20)) {
+
+                        /* Since the emulation does not have barriers,
+                           the acquire/release semantics need no special
+                           handling */
+                        if (op2 == 0) {
+                            if (insn & (1 << 20)) {
+                                tmp = tcg_temp_new_i32();
+                                switch (op1) {
+                                case 0: /* lda */
+                                    tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
+                                    break;
+                                case 2: /* ldab */
+                                    tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
+                                    break;
+                                case 3: /* ldah */
+                                    tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
+                                    break;
+                                default:
+                                    abort();
+                                }
+                                store_reg(s, rd, tmp);
+                            } else {
+                                rm = insn & 0xf;
+                                tmp = load_reg(s, rm);
+                                switch (op1) {
+                                case 0: /* stl */
+                                    tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+                                    break;
+                                case 2: /* stlb */
+                                    tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
+                                    break;
+                                case 3: /* stlh */
+                                    tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
+                                    break;
+                                default:
+                                    abort();
+                                }
+                                tcg_temp_free_i32(tmp);
+                            }
+                        } else if (insn & (1 << 20)) {
                             switch (op1) {
                             case 0: /* ldrex */
                                 gen_load_exclusive(s, rd, 15, addr, 2);
@@ -8125,7 +8185,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                     gen_store_exclusive(s, rd, rs, 15, addr, 2);
                 }
                 tcg_temp_free_i32(addr);
-            } else if ((insn & (1 << 6)) == 0) {
+            } else if ((insn & (7 << 5)) == 0) {
                 /* Table Branch.  */
                 if (rn == 15) {
                     addr = tcg_temp_new_i32();
@@ -8151,15 +8211,66 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                 tcg_gen_addi_i32(tmp, tmp, s->pc);
                 store_reg(s, 15, tmp);
             } else {
-                /* Load/store exclusive byte/halfword/doubleword.  */
-                ARCH(7);
+                int op2 = (insn >> 6) & 0x3;
                 op = (insn >> 4) & 0x3;
-                if (op == 2) {
+                switch (op2) {
+                case 0:
                     goto illegal_op;
+                case 1:
+                    /* Load/store exclusive byte/halfword/doubleword */
+                    if (op == 2) {
+                        goto illegal_op;
+                    }
+                    ARCH(7);
+                    break;
+                case 2:
+                    /* Load-acquire/store-release */
+                    if (op == 3) {
+                        goto illegal_op;
+                    }
+                    /* Fall through */
+                case 3:
+                    /* Load-acquire/store-release exclusive */
+                    ARCH(8);
+                    break;
                 }
                 addr = tcg_temp_local_new_i32();
                 load_reg_var(s, addr, rn);
-                if (insn & (1 << 20)) {
+                if (!(op2 & 1)) {
+                    if (insn & (1 << 20)) {
+                        tmp = tcg_temp_new_i32();
+                        switch (op) {
+                        case 0: /* ldab */
+                            tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
+                            break;
+                        case 1: /* ldah */
+                            tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
+                            break;
+                        case 2: /* lda */
+                            tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
+                            break;
+                        default:
+                            abort();
+                        }
+                        store_reg(s, rs, tmp);
+                    } else {
+                        tmp = load_reg(s, rs);
+                        switch (op) {
+                        case 0: /* stlb */
+                            tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
+                            break;
+                        case 1: /* stlh */
+                            tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
+                            break;
+                        case 2: /* stl */
+                            tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+                            break;
+                        default:
+                            abort();
+                        }
+                        tcg_temp_free_i32(tmp);
+                    }
+                } else if (insn & (1 << 20)) {
                     gen_load_exclusive(s, rs, rd, addr, op);
                 } else {
                     gen_store_exclusive(s, rm, rs, rd, addr, op);
index 8039e23ab3b53c022d57b60f46c3d7b386727fd2..1cf8bf79b6cc0580481a1a1ff43b15676d1b8886 100755 (executable)
@@ -149,6 +149,18 @@ echo
 run_qemu -drive file=$TEST_IMG,file.driver=file
 run_qemu -drive file=$TEST_IMG,file.driver=qcow2
 
+echo
+echo === Parsing protocol from file name ===
+echo
+
+# Protocol strings are supposed to be parsed from traditional option strings,
+# but not when using driver-specific options. We can distinguish them by the
+# error message for non-existing files.
+
+run_qemu -hda foo:bar
+run_qemu -drive file=foo:bar
+run_qemu -drive file.filename=foo:bar
+
 # success, all done
 echo "*** done"
 rm -f $seq.full
index 3d1ac7b7daf8446ef2a9c7d09d57bd9a467c62bc..95ff245f4006d0e99701e2efa6d6b39972caa82e 100644 (file)
@@ -23,10 +23,12 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo: could not
 === Enable and disable lazy refcounting on the command line, plus some invalid values ===
 
 Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=on
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=off
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=
 QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=: Parameter 'lazy_refcounts' expects 'on' or 'off'
@@ -49,112 +51,152 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=on: Lazy ref
 QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=on: could not open disk image TEST_DIR/t.qcow2: Invalid argument
 
 Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=off
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 
 === No medium ===
 
 Testing: -drive if=floppy
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive if=ide,media=cdrom
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive if=scsi,media=cdrom
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive if=ide
-QEMU_PROG: Device needs media, but drive is empty
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) QEMU_PROG: Device needs media, but drive is empty
+QEMU_PROG: Device initialization failed.
 QEMU_PROG: Initialization of device ide-hd failed
 
 Testing: -drive if=virtio
-QEMU_PROG: -drive if=virtio: Device needs media, but drive is empty
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) QEMU_PROG: -drive if=virtio: Device needs media, but drive is empty
+QEMU_PROG: -drive if=virtio: Device initialization failed.
+QEMU_PROG: -drive if=virtio: Device initialization failed.
 QEMU_PROG: -drive if=virtio: Device 'virtio-blk-pci' could not be initialized
 
 Testing: -drive if=scsi
-QEMU_PROG: -drive if=scsi: Device needs media, but drive is empty
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) QEMU_PROG: -drive if=scsi: Device needs media, but drive is empty
+QEMU_PROG: -drive if=scsi: Device initialization failed.
+QEMU_PROG: Device initialization failed.
 QEMU_PROG: Initialization of device lsi53c895a failed
 
 Testing: -drive if=none,id=disk -device ide-cd,drive=disk
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive if=none,id=disk -device ide-drive,drive=disk
-QEMU_PROG: -device ide-drive,drive=disk: Device needs media, but drive is empty
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) QEMU_PROG: -device ide-drive,drive=disk: Device needs media, but drive is empty
+QEMU_PROG: -device ide-drive,drive=disk: Device initialization failed.
 QEMU_PROG: -device ide-drive,drive=disk: Device 'ide-drive' could not be initialized
 
 Testing: -drive if=none,id=disk -device ide-hd,drive=disk
-QEMU_PROG: -device ide-hd,drive=disk: Device needs media, but drive is empty
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) QEMU_PROG: -device ide-hd,drive=disk: Device needs media, but drive is empty
+QEMU_PROG: -device ide-hd,drive=disk: Device initialization failed.
 QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
 
 Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk
-QEMU_PROG: -device scsi-disk,drive=disk: Device needs media, but drive is empty
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) QEMU_PROG: -device scsi-disk,drive=disk: Device needs media, but drive is empty
+QEMU_PROG: -device scsi-disk,drive=disk: Device initialization failed.
 QEMU_PROG: -device scsi-disk,drive=disk: Device 'scsi-disk' could not be initialized
 
 Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk
-QEMU_PROG: -device scsi-hd,drive=disk: Device needs media, but drive is empty
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) QEMU_PROG: -device scsi-hd,drive=disk: Device needs media, but drive is empty
+QEMU_PROG: -device scsi-hd,drive=disk: Device initialization failed.
 QEMU_PROG: -device scsi-hd,drive=disk: Device 'scsi-hd' could not be initialized
 
 
 === Read-only ===
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=floppy,readonly=on
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=ide,media=cdrom,readonly=on
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on
 QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on: readonly not supported by this bus type
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-cd,drive=disk
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-drive,drive=disk
-QEMU_PROG: -device ide-drive,drive=disk: Can't use a read-only drive
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) QEMU_PROG: -device ide-drive,drive=disk: Can't use a read-only drive
+QEMU_PROG: -device ide-drive,drive=disk: Device initialization failed.
 QEMU_PROG: -device ide-drive,drive=disk: Device 'ide-drive' could not be initialized
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-hd,drive=disk
-QEMU_PROG: -device ide-hd,drive=disk: Can't use a read-only drive
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) QEMU_PROG: -device ide-hd,drive=disk: Can't use a read-only drive
+QEMU_PROG: -device ide-hd,drive=disk: Device initialization failed.
 QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 
 === Cache modes ===
 
 Testing: -drive media=cdrom,cache=none
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive media=cdrom,cache=directsync
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive media=cdrom,cache=writeback
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive media=cdrom,cache=writethrough
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive media=cdrom,cache=unsafe
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive media=cdrom,cache=invalid_value
 QEMU_PROG: -drive media=cdrom,cache=invalid_value: invalid cache option
@@ -163,10 +205,25 @@ QEMU_PROG: -drive media=cdrom,cache=invalid_value: invalid cache option
 === Specifying the protocol layer ===
 
 Testing: -drive file=TEST_DIR/t.qcow2,file.driver=file
-q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
+QEMU 1.5.50 monitor - type 'help' for more information\r
+(qemu) q\e[K\e[Dqu\e[K\e[D\e[Dqui\e[K\e[D\e[D\e[Dquit\e[K\r
 
 Testing: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2
 QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: Can't use 'qcow2' as a block driver for the protocol level
 QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: could not open disk image TEST_DIR/t.qcow2: Invalid argument
 
+
+=== Parsing protocol from file name ===
+
+Testing: -hda foo:bar
+QEMU_PROG: -hda foo:bar: Unknown protocol
+QEMU_PROG: -hda foo:bar: could not open disk image foo:bar: No such file or directory
+
+Testing: -drive file=foo:bar
+QEMU_PROG: -drive file=foo:bar: Unknown protocol
+QEMU_PROG: -drive file=foo:bar: could not open disk image foo:bar: No such file or directory
+
+Testing: -drive file.filename=foo:bar
+QEMU_PROG: -drive file.filename=foo:bar: could not open disk image ide0-hd0: No such file or directory
+
 *** done
index 887c959a3d216d21efc007e6fa5cd5662526b069..c66f8dbd7d1625f6016ccc7e9210e0b0cde9e1d7 100755 (executable)
@@ -54,7 +54,7 @@ class TestSingleDrive(iotests.QMPTestCase):
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-backup', device='drive0',
-                             target=target_img)
+                             target=target_img, sync='full')
         self.assert_qmp(result, 'return', {})
 
         event = self.cancel_and_wait()
@@ -64,7 +64,7 @@ class TestSingleDrive(iotests.QMPTestCase):
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-backup', device='drive0',
-                             target=target_img)
+                             target=target_img, sync='full')
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('block-job-pause', device='drive0')
@@ -89,17 +89,17 @@ class TestSingleDrive(iotests.QMPTestCase):
 
     def test_medium_not_found(self):
         result = self.vm.qmp('drive-backup', device='ide1-cd0',
-                             target=target_img)
+                             target=target_img, sync='full')
         self.assert_qmp(result, 'error/class', 'GenericError')
 
     def test_image_not_found(self):
         result = self.vm.qmp('drive-backup', device='drive0',
-                             mode='existing', target=target_img)
+                             target=target_img, sync='full', mode='existing')
         self.assert_qmp(result, 'error/class', 'GenericError')
 
     def test_device_not_found(self):
         result = self.vm.qmp('drive-backup', device='nonexistent',
-                             target=target_img)
+                             target=target_img, sync='full')
         self.assert_qmp(result, 'error/class', 'DeviceNotFound')
 
 class TestSetSpeed(iotests.QMPTestCase):
@@ -119,7 +119,7 @@ class TestSetSpeed(iotests.QMPTestCase):
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-backup', device='drive0',
-                             target=target_img)
+                             target=target_img, sync='full')
         self.assert_qmp(result, 'return', {})
 
         # Default speed is 0
@@ -140,7 +140,7 @@ class TestSetSpeed(iotests.QMPTestCase):
 
         # Check setting speed in drive-backup works
         result = self.vm.qmp('drive-backup', device='drive0',
-                             target=target_img, speed=4*1024*1024)
+                             target=target_img, sync='full', speed=4*1024*1024)
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('query-block-jobs')
@@ -154,13 +154,13 @@ class TestSetSpeed(iotests.QMPTestCase):
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-backup', device='drive0',
-                             target=target_img, speed=-1)
+                             target=target_img, sync='full', speed=-1)
         self.assert_qmp(result, 'error/class', 'GenericError')
 
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-backup', device='drive0',
-                             target=target_img)
+                             target=target_img, sync='full')
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
@@ -196,7 +196,8 @@ class TestSingleTransaction(iotests.QMPTestCase):
         result = self.vm.qmp('transaction', actions=[{
                 'type': 'drive-backup',
                 'data': { 'device': 'drive0',
-                          'target': target_img },
+                          'target': target_img,
+                          'sync': 'full' },
             }
         ])
         self.assert_qmp(result, 'return', {})
@@ -210,7 +211,8 @@ class TestSingleTransaction(iotests.QMPTestCase):
         result = self.vm.qmp('transaction', actions=[{
                 'type': 'drive-backup',
                 'data': { 'device': 'drive0',
-                          'target': target_img },
+                          'target': target_img,
+                          'sync': 'full' },
             }
         ])
         self.assert_qmp(result, 'return', {})
@@ -239,7 +241,8 @@ class TestSingleTransaction(iotests.QMPTestCase):
         result = self.vm.qmp('transaction', actions=[{
                 'type': 'drive-backup',
                 'data': { 'device': 'ide1-cd0',
-                          'target': target_img },
+                          'target': target_img,
+                          'sync': 'full' },
             }
         ])
         self.assert_qmp(result, 'error/class', 'GenericError')
@@ -249,7 +252,8 @@ class TestSingleTransaction(iotests.QMPTestCase):
                 'type': 'drive-backup',
                 'data': { 'device': 'drive0',
                           'mode': 'existing',
-                          'target': target_img },
+                          'target': target_img,
+                          'sync': 'full' },
             }
         ])
         self.assert_qmp(result, 'error/class', 'GenericError')
@@ -259,7 +263,8 @@ class TestSingleTransaction(iotests.QMPTestCase):
                 'type': 'drive-backup',
                 'data': { 'device': 'nonexistent',
                           'mode': 'existing',
-                          'target': target_img },
+                          'target': target_img,
+                          'sync': 'full' },
             }
         ])
         self.assert_qmp(result, 'error/class', 'DeviceNotFound')
@@ -269,7 +274,8 @@ class TestSingleTransaction(iotests.QMPTestCase):
                 'type': 'drive-backup',
                 'data': { 'device': 'nonexistent',
                           'mode': 'existing',
-                          'target': target_img },
+                          'target': target_img,
+                          'sync': 'full' },
             }, {
                 'type': 'Abort',
                 'data': {},
index dcf6391ea2339081d62af325940984843d44df9a..9dbcae8d8ce357ad6d2efadc8e1de921d00d1366 100644 (file)
@@ -155,7 +155,7 @@ _filter_qemu_io()
 # replace occurrences of QEMU_PROG with "qemu"
 _filter_qemu()
 {
-    sed -e "s#^$(basename $QEMU_PROG):#QEMU_PROG:#"
+    sed -e "s#\\(^\\|(qemu) \\)$(basename $QEMU_PROG):#\1QEMU_PROG:#"
 }
 
 # make sure this script returns success