$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libcacard V="$(V)" TARGET_DIR="$*/" install-libcacard,)
endif
-vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) qemu-timer-common.o libcacard/vscclient.o
- $(call quiet-command,$(CC) -o $@ $^ $(libcacard_libs) $(LIBS)," LINK $@")
+vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) qemu-timer-common.o libcacard/vscclient.o
+ $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^ $(libcacard_libs) $(LIBS)," LINK $@")
######################################################################
install-doc: $(DOCS)
$(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)"
$(INSTALL_DATA) qemu-doc.html qemu-tech.html "$(DESTDIR)$(qemu_docdir)"
+ $(INSTALL_DATA) QMP/qmp-commands.txt "$(DESTDIR)$(qemu_docdir)"
ifdef CONFIG_POSIX
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
$(INSTALL_DATA) qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1"
Makefile: $(GENERATED_HEADERS)
# Include automatically generated dependency files
--include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d qapi/*.d)
--include $(wildcard qga/*.d hw/*.d hw/usb/*.d)
+# All subdir dependencies come automatically from our recursive subdir rules
+-include $(wildcard *.d)
rm -f *.o *.d *.a *~
# Include automatically generated dependency files
--include $(wildcard *.d */*.d)
+-include $(wildcard *.d)
#######################################################################
# Target-independent parts used in system and user emulation
universal-obj-y =
+universal-obj-y += qemu-log.o
#######################################################################
# QObject
Makefile: $(GENERATED_HEADERS)
# Include automatically generated dependency files
--include $(wildcard *.d */*.d)
+-include $(wildcard *.d)
done
# Include automatically generated dependency files
--include $(wildcard *.d */*.d)
+-include $(wildcard *.d)
"len": 10737418240, "offset": 134217728,
"speed": 0 },
"timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
+
+
+BALLOON_CHANGE
+----------
+
+Emitted when the guest changes the actual BALLOON level. This
+value is equivalent to the 'actual' field return by the
+'query-balloon' command
+
+Data:
+
+- "actual": actual level of the guest memory balloon in bytes (json-number)
+
+Example:
+
+{ "event": "BALLOON_CHANGE",
+ "data": { "actual": 944766976 },
+ "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
#include "balloon.h"
#include "trace.h"
#include "qmp-commands.h"
+#include "qjson.h"
static QEMUBalloonEvent *balloon_event_fn;
static QEMUBalloonStatus *balloon_stat_fn;
return 1;
}
+void qemu_balloon_changed(int64_t actual)
+{
+ QObject *data;
+
+ data = qobject_from_jsonf("{ 'actual': %" PRId64 " }",
+ actual);
+
+ monitor_protocol_event(QEVENT_BALLOON_CHANGE, data);
+
+ qobject_decref(data);
+}
+
+
BalloonInfo *qmp_query_balloon(Error **errp)
{
BalloonInfo *info;
QEMUBalloonStatus *stat_func, void *opaque);
void qemu_remove_balloon_handler(void *opaque);
+void qemu_balloon_changed(int64_t actual);
+
#endif
bs->opaque = g_malloc0(drv->instance_size);
bs->enable_write_cache = !!(flags & BDRV_O_CACHE_WB);
+ open_flags = flags | BDRV_O_CACHE_WB;
/*
* Clear flags that are internal to the block layer before opening the
* image.
*/
- open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
+ open_flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
/*
* Snapshots should be writable.
tmp.buffer_alignment = bs_top->buffer_alignment;
tmp.copy_on_read = bs_top->copy_on_read;
+ tmp.enable_write_cache = bs_top->enable_write_cache;
+
/* i/o timing parameters */
tmp.slice_time = bs_top->slice_time;
tmp.slice_start = bs_top->slice_start;
* swapping bs_new and bs_top contents. */
tmp.backing_hd = bs_new;
pstrcpy(tmp.backing_file, sizeof(tmp.backing_file), bs_top->filename);
- bdrv_get_format(bs_top, tmp.backing_format, sizeof(tmp.backing_format));
+ pstrcpy(tmp.backing_format, sizeof(tmp.backing_format),
+ bs_top->drv ? bs_top->drv->format_name : "");
/* swap contents of the fixed new bs and the current top */
*bs_new = *bs_top;
* free of errors) or -errno when an internal error occurred. The results of the
* check are stored in res.
*/
-int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
+int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix)
{
if (bs->drv->bdrv_check == NULL) {
return -ENOTSUP;
}
memset(res, 0, sizeof(*res));
- return bs->drv->bdrv_check(bs, res);
+ return bs->drv->bdrv_check(bs, res, fix);
}
#define COMMIT_BUF_SECTORS 2048
return ret;
}
- /* No flush needed for cache modes that use O_DSYNC */
- if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) {
+ /* No flush needed for cache modes that already do it */
+ if (bs->enable_write_cache) {
bdrv_flush(bs);
}
ret = bdrv_co_do_write_zeroes(bs, cluster_sector_num,
cluster_nb_sectors);
} else {
+ /* This does not change the data on the disk, it is not necessary
+ * to flush even in cache=writethrough mode.
+ */
ret = drv->bdrv_co_writev(bs, cluster_sector_num, cluster_nb_sectors,
&bounce_qiov);
}
ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
}
+ if (ret == 0 && !bs->enable_write_cache) {
+ ret = bdrv_co_flush(bs);
+ }
+
if (bs->dirty_bitmap) {
set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
}
return bs->enable_write_cache;
}
+void bdrv_set_enable_write_cache(BlockDriverState *bs, bool wce)
+{
+ bs->enable_write_cache = wce;
+}
+
int bdrv_is_encrypted(BlockDriverState *bs)
{
if (bs->backing_hd && bs->backing_hd->encrypted)
return ret;
}
-void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
+const char *bdrv_get_format_name(BlockDriverState *bs)
{
- if (!bs->drv) {
- buf[0] = '\0';
- } else {
- pstrcpy(buf, buf_size, bs->drv->format_name);
- }
+ return bs->drv ? bs->drv->format_name : NULL;
}
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
return bs->device_name;
}
+int bdrv_get_flags(BlockDriverState *bs)
+{
+ return bs->open_flags;
+}
+
void bdrv_flush_all(void)
{
BlockDriverState *bs;
return data.ret;
}
+/*
+ * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP]
+ *
+ * Return true if the given sector is allocated in any image between
+ * BASE and TOP (inclusive). BASE can be NULL to check if the given
+ * sector is allocated in any image of the chain. Return false otherwise.
+ *
+ * 'pnum' is set to the number of sectors (including and immediately following
+ * the specified sector) that are known to be in the same
+ * allocated/unallocated state.
+ *
+ */
+int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top,
+ BlockDriverState *base,
+ int64_t sector_num,
+ int nb_sectors, int *pnum)
+{
+ BlockDriverState *intermediate;
+ int ret, n = nb_sectors;
+
+ intermediate = top;
+ while (intermediate && intermediate != base) {
+ int pnum_inter;
+ ret = bdrv_co_is_allocated(intermediate, sector_num, nb_sectors,
+ &pnum_inter);
+ if (ret < 0) {
+ return ret;
+ } else if (ret) {
+ *pnum = pnum_inter;
+ return 1;
+ }
+
+ /*
+ * [sector_num, nb_sectors] is unallocated on top but intermediate
+ * might have
+ *
+ * [sector_num+x, nr_sectors] allocated.
+ */
+ if (n > pnum_inter) {
+ n = pnum_inter;
+ }
+
+ intermediate = intermediate->backing_hd;
+ }
+
+ *pnum = n;
+ return 0;
+}
+
BlockInfoList *qmp_query_block(Error **errp)
{
BlockInfoList *head = NULL, *cur_item = NULL;
int nb_sectors);
int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum);
+int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top,
+ BlockDriverState *base,
+ int64_t sector_num,
+ int nb_sectors, int *pnum);
BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
const char *backing_file);
int bdrv_truncate(BlockDriverState *bs, int64_t offset);
int corruptions;
int leaks;
int check_errors;
+ int corruptions_fixed;
+ int leaks_fixed;
BlockFragInfo bfi;
} BdrvCheckResult;
-int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res);
+typedef enum {
+ BDRV_FIX_LEAKS = 1,
+ BDRV_FIX_ERRORS = 2,
+} BdrvCheckMode;
+
+int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
/* async block I/O */
typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector,
int bdrv_is_read_only(BlockDriverState *bs);
int bdrv_is_sg(BlockDriverState *bs);
int bdrv_enable_write_cache(BlockDriverState *bs);
+void bdrv_set_enable_write_cache(BlockDriverState *bs, bool wce);
int bdrv_is_inserted(BlockDriverState *bs);
int bdrv_media_changed(BlockDriverState *bs);
void bdrv_lock_medium(BlockDriverState *bs, bool locked);
void bdrv_eject(BlockDriverState *bs, bool eject_flag);
-void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
+const char *bdrv_get_format_name(BlockDriverState *bs);
BlockDriverState *bdrv_find(const char *name);
BlockDriverState *bdrv_next(BlockDriverState *bs);
void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs),
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
void *opaque);
const char *bdrv_get_device_name(BlockDriverState *bs);
+int bdrv_get_flags(BlockDriverState *bs);
int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
struct Qcow2Cache* depends;
int size;
bool depends_on_flush;
- bool writethrough;
};
-Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables,
- bool writethrough)
+Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables)
{
BDRVQcowState *s = bs->opaque;
Qcow2Cache *c;
c = g_malloc0(sizeof(*c));
c->size = num_tables;
c->entries = g_malloc0(sizeof(*c->entries) * num_tables);
- c->writethrough = writethrough;
for (i = 0; i < c->size; i++) {
c->entries[i].table = qemu_blockalign(bs, s->cluster_size);
*table = NULL;
assert(c->entries[i].ref >= 0);
-
- if (c->writethrough) {
- return qcow2_cache_entry_flush(bs, c, i);
- } else {
- return 0;
- }
+ return 0;
}
void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table)
found:
c->entries[i].dirty = true;
}
-
-bool qcow2_cache_set_writethrough(BlockDriverState *bs, Qcow2Cache *c,
- bool enable)
-{
- bool old = c->writethrough;
-
- if (!old && enable) {
- qcow2_cache_flush(bs, c);
- }
-
- c->writethrough = enable;
- return old;
-}
if (l2_offset) {
qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));
}
- l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK;
}
/* find the cluster offset for the given disk offset */
}
if (m->nb_available & (s->cluster_sectors - 1)) {
- uint64_t end = m->nb_available & ~(uint64_t)(s->cluster_sectors - 1);
cow = true;
qemu_co_mutex_unlock(&s->lock);
- ret = copy_sectors(bs, start_sect + end, cluster_offset + (end << 9),
- m->nb_available - end, s->cluster_sectors);
+ ret = copy_sectors(bs, start_sect, cluster_offset, m->nb_available,
+ align_offset(m->nb_available, s->cluster_sectors));
qemu_co_mutex_lock(&s->lock);
if (ret < 0)
goto err;
/* save info needed for meta data update */
if (nb_clusters > 0) {
+ /*
+ * requested_sectors: Number of sectors from the start of the first
+ * newly allocated cluster to the end of the (possibly shortened
+ * before) write request.
+ *
+ * avail_sectors: Number of sectors from the start of the first
+ * newly allocated to the end of the last newly allocated cluster.
+ */
int requested_sectors = n_end - keep_clusters * s->cluster_sectors;
- int avail_sectors = (keep_clusters + nb_clusters)
+ int avail_sectors = nb_clusters
<< (s->cluster_bits - BDRV_SECTOR_BITS);
*m = (QCowL2Meta) {
}
for(i = 0; i < table_size; i++) {
- cpu_to_be64s(&new_table[i]);
+ be64_to_cpus(&new_table[i]);
}
/* Hook up the new refcount table in the qcow2 header */
int64_t old_offset, old_l2_offset;
int i, j, l1_modified = 0, nb_csectors, refcount;
int ret;
- bool old_l2_writethrough, old_refcount_writethrough;
-
- /* Switch caches to writeback mode during update */
- old_l2_writethrough =
- qcow2_cache_set_writethrough(bs, s->l2_table_cache, false);
- old_refcount_writethrough =
- qcow2_cache_set_writethrough(bs, s->refcount_block_cache, false);
l2_table = NULL;
l1_table = NULL;
qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
}
- /* Enable writethrough cache mode again */
- qcow2_cache_set_writethrough(bs, s->l2_table_cache, old_l2_writethrough);
- qcow2_cache_set_writethrough(bs, s->refcount_block_cache,
- old_refcount_writethrough);
-
/* Update L1 only if it isn't deleted anyway (addend = -1) */
if (addend >= 0 && l1_modified) {
for(i = 0; i < l1_size; i++)
* Returns 0 if no errors are found, the number of errors in case the image is
* detected as corrupted, and -errno when an internal error occurred.
*/
-int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
+int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
+ BdrvCheckMode fix)
{
BDRVQcowState *s = bs->opaque;
- int64_t size;
- int nb_clusters, refcount1, refcount2, i;
+ int64_t size, i;
+ int nb_clusters, refcount1, refcount2;
QCowSnapshot *sn;
uint16_t *refcount_table;
int ret;
/* Refcount blocks are cluster aligned */
if (offset & (s->cluster_size - 1)) {
- fprintf(stderr, "ERROR refcount block %d is not "
+ fprintf(stderr, "ERROR refcount block %" PRId64 " is not "
"cluster aligned; refcount table entry corrupted\n", i);
res->corruptions++;
continue;
}
if (cluster >= nb_clusters) {
- fprintf(stderr, "ERROR refcount block %d is outside image\n", i);
+ fprintf(stderr, "ERROR refcount block %" PRId64
+ " is outside image\n", i);
res->corruptions++;
continue;
}
inc_refcounts(bs, res, refcount_table, nb_clusters,
offset, s->cluster_size);
if (refcount_table[cluster] != 1) {
- fprintf(stderr, "ERROR refcount block %d refcount=%d\n",
+ fprintf(stderr, "ERROR refcount block %" PRId64
+ " refcount=%d\n",
i, refcount_table[cluster]);
res->corruptions++;
}
for(i = 0; i < nb_clusters; i++) {
refcount1 = get_refcount(bs, i);
if (refcount1 < 0) {
- fprintf(stderr, "Can't get refcount for cluster %d: %s\n",
+ fprintf(stderr, "Can't get refcount for cluster %" PRId64 ": %s\n",
i, strerror(-refcount1));
res->check_errors++;
continue;
refcount2 = refcount_table[i];
if (refcount1 != refcount2) {
- fprintf(stderr, "%s cluster %d refcount=%d reference=%d\n",
- refcount1 < refcount2 ? "ERROR" : "Leaked",
+
+ /* Check if we're allowed to fix the mismatch */
+ int *num_fixed = NULL;
+ if (refcount1 > refcount2 && (fix & BDRV_FIX_LEAKS)) {
+ num_fixed = &res->leaks_fixed;
+ } else if (refcount1 < refcount2 && (fix & BDRV_FIX_ERRORS)) {
+ num_fixed = &res->corruptions_fixed;
+ }
+
+ fprintf(stderr, "%s cluster %" PRId64 " refcount=%d reference=%d\n",
+ num_fixed != NULL ? "Repairing" :
+ refcount1 < refcount2 ? "ERROR" :
+ "Leaked",
i, refcount1, refcount2);
+
+ if (num_fixed) {
+ ret = update_refcount(bs, i << s->cluster_bits, 1,
+ refcount2 - refcount1);
+ if (ret >= 0) {
+ (*num_fixed)++;
+ continue;
+ }
+ }
+
+ /* And if we couldn't, print an error */
if (refcount1 < refcount2) {
res->corruptions++;
} else {
int len, i, ret = 0;
QCowHeader header;
uint64_t ext_end;
- bool writethrough;
ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
if (ret < 0) {
goto fail;
}
- if (!bs->read_only && s->autoclear_features != 0) {
- s->autoclear_features = 0;
- ret = qcow2_update_header(bs);
- if (ret < 0) {
- goto fail;
- }
- }
-
/* Check support for various header values */
if (header.refcount_order != 4) {
report_unsupported(bs, "%d bit reference counts",
}
/* alloc L2 table/refcount block cache */
- writethrough = ((flags & BDRV_O_CACHE_WB) == 0);
- s->l2_table_cache = qcow2_cache_create(bs, L2_CACHE_SIZE, writethrough);
- s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE,
- writethrough);
+ s->l2_table_cache = qcow2_cache_create(bs, L2_CACHE_SIZE);
+ s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE);
s->cluster_cache = g_malloc(s->cluster_size);
/* one more sector for decompressed data alignment */
goto fail;
}
+ /* Clear unknown autoclear feature bits */
+ if (!bs->read_only && s->autoclear_features != 0) {
+ s->autoclear_features = 0;
+ ret = qcow2_update_header(bs);
+ if (ret < 0) {
+ goto fail;
+ }
+ }
+
/* Initialise locks */
qemu_co_mutex_init(&s->lock);
}
-static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result)
+static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
+ BdrvCheckMode fix)
{
- return qcow2_check_refcounts(bs, result);
+ return qcow2_check_refcounts(bs, result, fix);
}
#if 0
int qcow2_update_snapshot_refcount(BlockDriverState *bs,
int64_t l1_table_offset, int l1_size, int addend);
-int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res);
+int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
+ BdrvCheckMode fix);
/* qcow2-cluster.c functions */
int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size);
int qcow2_read_snapshots(BlockDriverState *bs);
/* qcow2-cache.c functions */
-Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables,
- bool writethrough);
+Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables);
int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c);
-bool qcow2_cache_set_writethrough(BlockDriverState *bs, Qcow2Cache *c,
- bool enable);
void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table);
int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c);
if (!qed_check_cluster_offset(s, offset)) {
if (check->fix) {
table->offsets[i] = 0;
+ check->result->corruptions_fixed++;
} else {
check->result->corruptions++;
}
/* Clear invalid offset */
if (check->fix) {
table->offsets[i] = 0;
+ check->result->corruptions_fixed++;
} else {
check->result->corruptions++;
}
bdrv_qed_open(bs, bs->open_flags);
}
-static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result)
+static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result,
+ BdrvCheckMode fix)
{
BDRVQEDState *s = bs->opaque;
- return qed_check(s, result, false);
+ return qed_check(s, result, !!fix);
}
static QEMUOptionParameter qed_create_options[] = {
#include <sys/param.h>
#include <linux/cdrom.h>
#include <linux/fd.h>
+#include <linux/fs.h>
+#endif
+#ifdef CONFIG_FIEMAP
+#include <linux/fiemap.h>
#endif
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <sys/disk.h>
return result;
}
+/*
+ * Returns true iff the specified sector is present in the disk image. Drivers
+ * not implementing the functionality are assumed to not support backing files,
+ * hence all their sectors are reported as allocated.
+ *
+ * If 'sector_num' is beyond the end of the disk image the return value is 0
+ * and 'pnum' is set to 0.
+ *
+ * 'pnum' is set to the number of sectors (including and immediately following
+ * the specified sector) that are known to be in the same
+ * allocated/unallocated state.
+ *
+ * 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes
+ * beyond the end of the disk image it will be clamped.
+ */
+static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
+ int64_t sector_num,
+ int nb_sectors, int *pnum)
+{
+ BDRVRawState *s = bs->opaque;
+ off_t start, data, hole;
+ int ret;
+
+ ret = fd_open(bs);
+ if (ret < 0) {
+ return ret;
+ }
+
+ start = sector_num * BDRV_SECTOR_SIZE;
+#ifdef CONFIG_FIEMAP
+ struct {
+ struct fiemap fm;
+ struct fiemap_extent fe;
+ } f;
+ f.fm.fm_start = start;
+ f.fm.fm_length = (int64_t)nb_sectors * BDRV_SECTOR_SIZE;
+ f.fm.fm_flags = 0;
+ f.fm.fm_extent_count = 1;
+ f.fm.fm_reserved = 0;
+ if (ioctl(s->fd, FS_IOC_FIEMAP, &f) == -1) {
+ /* Assume everything is allocated. */
+ *pnum = nb_sectors;
+ return 1;
+ }
+
+ if (f.fm.fm_mapped_extents == 0) {
+ /* No extents found, data is beyond f.fm.fm_start + f.fm.fm_length.
+ * f.fm.fm_start + f.fm.fm_length must be clamped to the file size!
+ */
+ off_t length = lseek(s->fd, 0, SEEK_END);
+ hole = f.fm.fm_start;
+ data = MIN(f.fm.fm_start + f.fm.fm_length, length);
+ } else {
+ data = f.fe.fe_logical;
+ hole = f.fe.fe_logical + f.fe.fe_length;
+ }
+#elif defined SEEK_HOLE && defined SEEK_DATA
+ hole = lseek(s->fd, start, SEEK_HOLE);
+ if (hole == -1) {
+ /* -ENXIO indicates that sector_num was past the end of the file.
+ * There is a virtual hole there. */
+ assert(errno != -ENXIO);
+
+ /* Most likely EINVAL. Assume everything is allocated. */
+ *pnum = nb_sectors;
+ return 1;
+ }
+
+ if (hole > start) {
+ data = start;
+ } else {
+ /* On a hole. We need another syscall to find its end. */
+ data = lseek(s->fd, start, SEEK_DATA);
+ if (data == -1) {
+ data = lseek(s->fd, 0, SEEK_END);
+ }
+ }
+#else
+ *pnum = nb_sectors;
+ return 1;
+#endif
+
+ if (data <= start) {
+ /* On a data extent, compute sectors to the end of the extent. */
+ *pnum = MIN(nb_sectors, (hole - start) / BDRV_SECTOR_SIZE);
+ return 1;
+ } else {
+ /* On a hole, compute sectors to the beginning of the next extent. */
+ *pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE);
+ return 0;
+ }
+}
+
#ifdef CONFIG_XFS
static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
{
.bdrv_close = raw_close,
.bdrv_create = raw_create,
.bdrv_co_discard = raw_co_discard,
+ .bdrv_co_is_allocated = raw_co_is_allocated,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_aio_writev = raw_aio_writev,
{
}
+static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
+ int64_t sector_num,
+ int nb_sectors, int *pnum)
+{
+ return bdrv_co_is_allocated(bs->file, sector_num, nb_sectors, pnum);
+}
+
static int64_t raw_getlength(BlockDriverState *bs)
{
return bdrv_getlength(bs->file);
.bdrv_co_readv = raw_co_readv,
.bdrv_co_writev = raw_co_writev,
+ .bdrv_co_is_allocated = raw_co_is_allocated,
.bdrv_co_discard = raw_co_discard,
.bdrv_probe = raw_probe,
s->snap = g_strdup(snap_buf);
}
+ /*
+ * Fallback to more conservative semantics if setting cache
+ * options fails. Ignore errors from setting rbd_cache because the
+ * only possible error is that the option does not exist, and
+ * librbd defaults to no caching. If write through caching cannot
+ * be set up, fall back to no caching.
+ */
+ if (flags & BDRV_O_NOCACHE) {
+ rados_conf_set(s->cluster, "rbd_cache", "false");
+ } else {
+ rados_conf_set(s->cluster, "rbd_cache", "true");
+ if (!(flags & BDRV_O_CACHE_WB)) {
+ r = rados_conf_set(s->cluster, "rbd_cache_max_dirty", "0");
+ if (r < 0) {
+ rados_conf_set(s->cluster, "rbd_cache", "false");
+ }
+ }
+ }
+
if (strstr(conf, "conf=") == NULL) {
/* try default location, but ignore failure */
rados_conf_read_file(s->cluster, NULL);
return ret;
}
-static int send_co_req(int sockfd, SheepdogReq *hdr, void *data,
- unsigned int *wlen)
+static coroutine_fn int send_co_req(int sockfd, SheepdogReq *hdr, void *data,
+ unsigned int *wlen)
{
int ret;
return ret;
}
+
static int do_req(int sockfd, SheepdogReq *hdr, void *data,
unsigned int *wlen, unsigned int *rlen)
{
return ret;
}
-static int do_co_req(int sockfd, SheepdogReq *hdr, void *data,
- unsigned int *wlen, unsigned int *rlen)
+static coroutine_fn int do_co_req(int sockfd, SheepdogReq *hdr, void *data,
+ unsigned int *wlen, unsigned int *rlen)
{
int ret;
#include "trace.h"
#include "block_int.h"
+#include "qemu/ratelimit.h"
enum {
/*
#define SLICE_TIME 100000000ULL /* ns */
-typedef struct {
- int64_t next_slice_time;
- uint64_t slice_quota;
- uint64_t dispatched;
-} RateLimit;
-
-static int64_t ratelimit_calculate_delay(RateLimit *limit, uint64_t n)
-{
- int64_t now = qemu_get_clock_ns(rt_clock);
-
- if (limit->next_slice_time < now) {
- limit->next_slice_time = now + SLICE_TIME;
- limit->dispatched = 0;
- }
- if (limit->dispatched == 0 || limit->dispatched + n <= limit->slice_quota) {
- limit->dispatched += n;
- return 0;
- } else {
- limit->dispatched = n;
- return limit->next_slice_time - now;
- }
-}
-
-static void ratelimit_set_speed(RateLimit *limit, uint64_t speed)
-{
- limit->slice_quota = speed / (1000000000ULL / SLICE_TIME);
-}
-
typedef struct StreamBlockJob {
BlockJob common;
RateLimit limit;
top->backing_hd = base;
}
-/*
- * Given an image chain: [BASE] -> [INTER1] -> [INTER2] -> [TOP]
- *
- * Return true if the given sector is allocated in top.
- * Return false if the given sector is allocated in intermediate images.
- * Return true otherwise.
- *
- * 'pnum' is set to the number of sectors (including and immediately following
- * the specified sector) that are known to be in the same
- * allocated/unallocated state.
- *
- */
-static int coroutine_fn is_allocated_base(BlockDriverState *top,
- BlockDriverState *base,
- int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- BlockDriverState *intermediate;
- int ret, n;
-
- ret = bdrv_co_is_allocated(top, sector_num, nb_sectors, &n);
- if (ret) {
- *pnum = n;
- return ret;
- }
-
- /*
- * Is the unallocated chunk [sector_num, n] also
- * unallocated between base and top?
- */
- intermediate = top->backing_hd;
-
- while (intermediate != base) {
- int pnum_inter;
-
- ret = bdrv_co_is_allocated(intermediate, sector_num, nb_sectors,
- &pnum_inter);
- if (ret < 0) {
- return ret;
- } else if (ret) {
- *pnum = pnum_inter;
- return 0;
- }
-
- /*
- * [sector_num, nb_sectors] is unallocated on top but intermediate
- * might have
- *
- * [sector_num+x, nr_sectors] allocated.
- */
- if (n > pnum_inter) {
- n = pnum_inter;
- }
-
- intermediate = intermediate->backing_hd;
- }
-
- *pnum = n;
- return 1;
-}
-
static void coroutine_fn stream_run(void *opaque)
{
StreamBlockJob *s = opaque;
for (sector_num = 0; sector_num < end; sector_num += n) {
uint64_t delay_ns = 0;
+ bool copy;
wait:
/* Note that even when no rate limit is applied we need to yield
break;
}
- ret = is_allocated_base(bs, base, sector_num,
- STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, &n);
+ ret = bdrv_co_is_allocated(bs, sector_num,
+ STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, &n);
+ if (ret == 1) {
+ /* Allocated in the top, no need to copy. */
+ copy = false;
+ } else {
+ /* Copy if allocated in the intermediate images. Limit to the
+ * known-unallocated area [sector_num, sector_num+n). */
+ ret = bdrv_co_is_allocated_above(bs->backing_hd, base,
+ sector_num, n, &n);
+ copy = (ret == 1);
+ }
trace_stream_one_iteration(s, sector_num, n, ret);
- if (ret == 0) {
+ if (ret >= 0 && copy) {
if (s->common.speed) {
delay_ns = ratelimit_calculate_delay(&s->limit, n);
if (delay_ns > 0) {
error_set(errp, QERR_INVALID_PARAMETER, "speed");
return;
}
- ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE);
+ ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE, SLICE_TIME);
}
static BlockJobType stream_job_type = {
}
#endif
-static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res)
+static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res,
+ BdrvCheckMode fix)
{
/* TODO: additional checks possible. */
BDRVVdiState *s = (BDRVVdiState *)bs->opaque;
uint32_t *bmap;
logout("\n");
+ if (fix) {
+ return -ENOTSUP;
+ }
+
bmap = g_malloc(s->header.blocks_in_image * sizeof(uint32_t));
memset(bmap, 0xff, s->header.blocks_in_image * sizeof(uint32_t));
* Returns 0 for completed check, -errno for internal errors.
* The check results are stored in result.
*/
- int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result);
+ int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result,
+ BdrvCheckMode fix);
void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event);
{
const char *buf;
const char *file = NULL;
- char devname[128];
const char *serial;
const char *mediastr = "";
BlockInterfaceType type;
serial = qemu_opt_get(opts, "serial");
if ((buf = qemu_opt_get(opts, "if")) != NULL) {
- pstrcpy(devname, sizeof(devname), buf);
for (type = 0; type < IF_COUNT && strcmp(buf, if_name[type]); type++)
;
if (type == IF_COUNT) {
}
} else {
type = default_to_scsi ? IF_SCSI : IF_IDE;
- pstrcpy(devname, sizeof(devname), if_name[type]);
}
max_devs = if_max_devs[type];
mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
if (max_devs)
snprintf(dinfo->id, 32, "%s%i%s%i",
- devname, bus_id, mediastr, unit_id);
+ if_name[type], bus_id, mediastr, unit_id);
else
snprintf(dinfo->id, 32, "%s%s%i",
- devname, mediastr, unit_id);
+ if_name[type], mediastr, unit_id);
}
dinfo->bdrv = bdrv_new(dinfo->id);
dinfo->devaddr = devaddr;
QEMU_CFLAGS="-Wall -Wundef -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS"
QEMU_CFLAGS="-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS"
QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS"
-QEMU_CFLAGS="-D_FORTIFY_SOURCE=2 $QEMU_CFLAGS"
QEMU_INCLUDES="-I. -I\$(SRC_PATH) -I\$(SRC_PATH)/fpu"
if test "$debug_info" = "yes"; then
CFLAGS="-g $CFLAGS"
open_by_hande_at=no
cat > $TMPC << EOF
#include <fcntl.h>
+#if !defined(AT_EMPTY_PATH)
+# error missing definition
+#else
int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
+#endif
EOF
if compile_prog "" "" ; then
open_by_handle_at=yes
# After here, no more $cc or $ld runs
if test "$debug" = "no" ; then
- CFLAGS="-O2 $CFLAGS"
+ CFLAGS="-O2 -D_FORTIFY_SOURCE=2 $CFLAGS"
fi
# Consult white-list to determine whether to enable werror
int cpu_is_stopped(CPUArchState *env);
void run_on_cpu(CPUArchState *env, void (*func)(void *data), void *data);
-#define CPU_LOG_TB_OUT_ASM (1 << 0)
-#define CPU_LOG_TB_IN_ASM (1 << 1)
-#define CPU_LOG_TB_OP (1 << 2)
-#define CPU_LOG_TB_OP_OPT (1 << 3)
-#define CPU_LOG_INT (1 << 4)
-#define CPU_LOG_EXEC (1 << 5)
-#define CPU_LOG_PCALL (1 << 6)
-#define CPU_LOG_IOPORT (1 << 7)
-#define CPU_LOG_TB_CPU (1 << 8)
-#define CPU_LOG_RESET (1 << 9)
-
-/* define log items */
-typedef struct CPULogItem {
- int mask;
- const char *name;
- const char *help;
-} CPULogItem;
-
-extern const CPULogItem cpu_log_items[];
-
-void cpu_set_log(int log_flags);
-void cpu_set_log_filename(const char *filename);
-int cpu_str_to_log_mask(const char *str);
-
#if !defined(CONFIG_USER_ONLY)
/* Return the physical page corresponding to a virtual one. Use it
* Authors:
* Wen Congyang <wency@cn.fujitsu.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
*
*/
* Authors:
* Wen Congyang <wency@cn.fujitsu.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
*
*/
* Authors:
* Wen Congyang <wency@cn.fujitsu.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
*
*/
static MemoryRegion io_mem_watch;
#endif
-/* log support */
-#ifdef WIN32
-static const char *logfilename = "qemu.log";
-#else
-static const char *logfilename = "/tmp/qemu.log";
-#endif
-FILE *logfile;
-int loglevel;
-static int log_append = 0;
-
/* statistics */
static int tb_flush_count;
static int tb_phys_invalidate_count;
#endif
}
-/* enable or disable low levels log */
-void cpu_set_log(int log_flags)
-{
- loglevel = log_flags;
- if (loglevel && !logfile) {
- logfile = fopen(logfilename, log_append ? "a" : "w");
- if (!logfile) {
- perror(logfilename);
- _exit(1);
- }
-#if !defined(CONFIG_SOFTMMU)
- /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
- {
- static char logfile_buf[4096];
- setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
- }
-#elif defined(_WIN32)
- /* Win32 doesn't support line-buffering, so use unbuffered output. */
- setvbuf(logfile, NULL, _IONBF, 0);
-#else
- setvbuf(logfile, NULL, _IOLBF, 0);
-#endif
- log_append = 1;
- }
- if (!loglevel && logfile) {
- fclose(logfile);
- logfile = NULL;
- }
-}
-
-void cpu_set_log_filename(const char *filename)
-{
- logfilename = strdup(filename);
- if (logfile) {
- fclose(logfile);
- logfile = NULL;
- }
- cpu_set_log(loglevel);
-}
-
static void cpu_unlink_tb(CPUArchState *env)
{
/* FIXME: TB unchaining isn't SMP safe. For now just ignore the
cpu_unlink_tb(env);
}
-const CPULogItem cpu_log_items[] = {
- { CPU_LOG_TB_OUT_ASM, "out_asm",
- "show generated host assembly code for each compiled TB" },
- { CPU_LOG_TB_IN_ASM, "in_asm",
- "show target assembly code for each compiled TB" },
- { CPU_LOG_TB_OP, "op",
- "show micro ops for each compiled TB" },
- { CPU_LOG_TB_OP_OPT, "op_opt",
- "show micro ops "
-#ifdef TARGET_I386
- "before eflags optimization and "
-#endif
- "after liveness analysis" },
- { CPU_LOG_INT, "int",
- "show interrupts/exceptions in short format" },
- { CPU_LOG_EXEC, "exec",
- "show trace before each executed TB (lots of logs)" },
- { CPU_LOG_TB_CPU, "cpu",
- "show CPU state before block translation" },
-#ifdef TARGET_I386
- { CPU_LOG_PCALL, "pcall",
- "show protected mode far calls/returns/exceptions" },
- { CPU_LOG_RESET, "cpu_reset",
- "show CPU state before CPU resets" },
-#endif
-#ifdef DEBUG_IOPORT
- { CPU_LOG_IOPORT, "ioport",
- "show all i/o ports accesses" },
-#endif
- { 0, NULL, NULL },
-};
-
-static int cmp1(const char *s1, int n, const char *s2)
-{
- if (strlen(s2) != n)
- return 0;
- return memcmp(s1, s2, n) == 0;
-}
-
-/* takes a comma separated list of log masks. Return 0 if error. */
-int cpu_str_to_log_mask(const char *str)
-{
- const CPULogItem *item;
- int mask;
- const char *p, *p1;
-
- p = str;
- mask = 0;
- for(;;) {
- p1 = strchr(p, ',');
- if (!p1)
- p1 = p + strlen(p);
- if(cmp1(p,p1-p,"all")) {
- for(item = cpu_log_items; item->mask != 0; item++) {
- mask |= item->mask;
- }
- } else {
- for(item = cpu_log_items; item->mask != 0; item++) {
- if (cmp1(p, p1 - p, item->name))
- goto found;
- }
- return 0;
- }
- found:
- mask |= item->mask;
- if (*p1 != ',')
- break;
- p = p1 + 1;
- }
- return mask;
-}
-
void cpu_abort(CPUArchState *env, const char *fmt, ...)
{
va_list ap;
assert(new_block);
assert(!new_block->idstr[0]);
- if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
- char *id = dev->parent_bus->info->get_dev_path(dev);
+ if (dev) {
+ char *id = qdev_get_dev_path(dev);
if (id) {
snprintf(new_block->idstr, sizeof(new_block->idstr), "%s/", id);
g_free(id);
#include "qemu-option.h"
#include "qemu-timer.h"
#include "qmp-commands.h"
+#include "monitor.h"
static void hmp_handle_error(Monitor *mon, Error **errp)
{
s->gic = qdev_create(NULL, "arm_gic");
qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
+ qdev_prop_set_uint32(s->gic, "revision", 2);
qdev_init_nofail(s->gic);
busdev = sysbus_from_qdev(s->gic);
break;
default:
fprintf(stderr, "Invalid size %u in write to a9 scu register %x\n",
- size, offset);
+ size, (unsigned)offset);
return;
}
qemu_register_wakeup_notifier(&ar->wakeup);
}
-void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val)
+void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val, char s4)
{
ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
qemu_system_suspend_request();
break;
default:
+ if (sus_typ == s4) { /* S4 request */
+ qemu_system_shutdown_request();
+ }
break;
}
}
/* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */
void acpi_pm1_cnt_init(ACPIREGS *ar);
-void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val);
+void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val, char s4);
void acpi_pm1_cnt_update(ACPIREGS *ar,
bool sci_enable, bool sci_disable);
void acpi_pm1_cnt_reset(ACPIREGS *ar);
#include "sysemu.h"
#include "range.h"
#include "ioport.h"
+#include "fw_cfg.h"
//#define DEBUG
struct pci_status pci0_status;
uint32_t pci0_hotplug_enable;
uint32_t pci0_slot_device_present;
+
+ uint8_t disable_s3;
+ uint8_t disable_s4;
+ uint8_t s4_val;
} PIIX4PMState;
static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s);
pm_update_sci(s);
break;
case 0x04:
- acpi_pm1_cnt_write(&s->ar, val);
+ acpi_pm1_cnt_write(&s->ar, val, s->s4_val);
break;
default:
break;
static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
{
- DeviceState *qdev, *next;
+ BusChild *kid, *next;
BusState *bus = qdev_get_parent_bus(&s->dev.qdev);
int slot = ffs(slots) - 1;
bool slot_free = true;
/* Mark request as complete */
s->pci0_status.down &= ~(1U << slot);
- QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
+ QTAILQ_FOREACH_SAFE(kid, &bus->children, sibling, next) {
+ DeviceState *qdev = kid->child;
PCIDevice *dev = PCI_DEVICE(qdev);
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
if (PCI_SLOT(dev->devfn) == slot) {
{
PCIDevice *dev = &s->dev;
BusState *bus = qdev_get_parent_bus(&dev->qdev);
- DeviceState *qdev, *next;
+ BusChild *kid, *next;
/* Execute any pending removes during reset */
while (s->pci0_status.down) {
s->pci0_hotplug_enable = ~0;
s->pci0_slot_device_present = 0;
- QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
+ QTAILQ_FOREACH_SAFE(kid, &bus->children, sibling, next) {
+ DeviceState *qdev = kid->child;
PCIDevice *pdev = PCI_DEVICE(qdev);
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pdev);
int slot = PCI_SLOT(pdev->devfn);
i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
qemu_irq sci_irq, qemu_irq smi_irq,
- int kvm_enabled)
+ int kvm_enabled, void *fw_cfg)
{
PCIDevice *dev;
PIIX4PMState *s;
qdev_init_nofail(&dev->qdev);
+ if (fw_cfg) {
+ uint8_t suspend[6] = {128, 0, 0, 129, 128, 128};
+ suspend[3] = 1 | ((!s->disable_s3) << 7);
+ suspend[4] = s->s4_val | ((!s->disable_s4) << 7);
+
+ fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);
+ }
+
return s->smb.smbus;
}
static Property piix4_pm_properties[] = {
DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
+ DEFINE_PROP_UINT8("disable_s3", PIIX4PMState, disable_s3, 0),
+ DEFINE_PROP_UINT8("disable_s4", PIIX4PMState, disable_s4, 0),
+ DEFINE_PROP_UINT8("s4_val", PIIX4PMState, s4_val, 2),
DEFINE_PROP_END_OF_LIST(),
};
/* multicore boards that use the default secondary core boot functions
* can ignore these two function calls. If the default functions won't
* work, then write_secondary_boot() should write a suitable blob of
- * code mimicing the secondary CPU startup process used by the board's
+ * code mimicking the secondary CPU startup process used by the board's
* boot loader/boot ROM code, and secondary_cpu_reset_hook() should
- * perform any necessary CPU reset handling and set the PC for thei
+ * perform any necessary CPU reset handling and set the PC for the
* secondary CPUs to point at this boot blob.
*/
void (*write_secondary_boot)(ARMCPU *cpu,
obj-y += cadence_ttc.o
obj-y += cadence_gem.o
obj-y += xilinx_zynq.o zynq_slcr.o
-obj-y += arm_gic.o
+obj-y += arm_gic.o arm_gic_common.o
obj-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
obj-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o
obj-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o
s->gic = qdev_create(NULL, "arm_gic");
qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
+ /* Request the legacy 11MPCore GIC behaviour: */
+ qdev_prop_set_uint32(s->gic, "revision", 0);
qdev_init_nofail(s->gic);
/* Pass through outbound IRQ lines from the GIC */
fprintf(stderr, "couldn't set /memory/reg\n");
}
- rc = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
- binfo->kernel_cmdline);
- if (rc < 0) {
- fprintf(stderr, "couldn't set /chosen/bootargs\n");
+ if (binfo->kernel_cmdline && *binfo->kernel_cmdline) {
+ rc = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
+ binfo->kernel_cmdline);
+ if (rc < 0) {
+ fprintf(stderr, "couldn't set /chosen/bootargs\n");
+ }
}
if (binfo->initrd_size) {
*/
#include "sysbus.h"
-
-/* Maximum number of possible interrupts, determined by the GIC architecture */
-#define GIC_MAXIRQ 1020
-/* First 32 are private to each CPU (SGIs and PPIs). */
-#define GIC_INTERNAL 32
-/* Maximum number of possible CPU interfaces, determined by GIC architecture */
-#ifdef NVIC
-#define NCPU 1
-#else
-#define NCPU 8
-#endif
+#include "arm_gic_internal.h"
//#define DEBUG_GIC
#define DPRINTF(fmt, ...) do {} while(0)
#endif
-#ifdef NVIC
-static const uint8_t gic_id[] =
-{ 0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1 };
-/* The NVIC has 16 internal vectors. However these are not exposed
- through the normal GIC interface. */
-#define GIC_BASE_IRQ 32
-#else
-static const uint8_t gic_id[] =
-{ 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
-#define GIC_BASE_IRQ 0
-#endif
-
-#define FROM_SYSBUSGIC(type, dev) \
- DO_UPCAST(type, gic, FROM_SYSBUS(gic_state, dev))
+static const uint8_t gic_id[] = {
+ 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1
+};
-typedef struct gic_irq_state
-{
- /* The enable bits are only banked for per-cpu interrupts. */
- unsigned enabled:NCPU;
- unsigned pending:NCPU;
- unsigned active:NCPU;
- unsigned level:NCPU;
- unsigned model:1; /* 0 = N:N, 1 = 1:N */
- unsigned trigger:1; /* nonzero = edge triggered. */
-} gic_irq_state;
-
-#define ALL_CPU_MASK ((unsigned)(((1 << NCPU) - 1)))
-#if NCPU > 1
#define NUM_CPU(s) ((s)->num_cpu)
-#else
-#define NUM_CPU(s) 1
-#endif
-
-#define GIC_SET_ENABLED(irq, cm) s->irq_state[irq].enabled |= (cm)
-#define GIC_CLEAR_ENABLED(irq, cm) s->irq_state[irq].enabled &= ~(cm)
-#define GIC_TEST_ENABLED(irq, cm) ((s->irq_state[irq].enabled & (cm)) != 0)
-#define GIC_SET_PENDING(irq, cm) s->irq_state[irq].pending |= (cm)
-#define GIC_CLEAR_PENDING(irq, cm) s->irq_state[irq].pending &= ~(cm)
-#define GIC_TEST_PENDING(irq, cm) ((s->irq_state[irq].pending & (cm)) != 0)
-#define GIC_SET_ACTIVE(irq, cm) s->irq_state[irq].active |= (cm)
-#define GIC_CLEAR_ACTIVE(irq, cm) s->irq_state[irq].active &= ~(cm)
-#define GIC_TEST_ACTIVE(irq, cm) ((s->irq_state[irq].active & (cm)) != 0)
-#define GIC_SET_MODEL(irq) s->irq_state[irq].model = 1
-#define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = 0
-#define GIC_TEST_MODEL(irq) s->irq_state[irq].model
-#define GIC_SET_LEVEL(irq, cm) s->irq_state[irq].level = (cm)
-#define GIC_CLEAR_LEVEL(irq, cm) s->irq_state[irq].level &= ~(cm)
-#define GIC_TEST_LEVEL(irq, cm) ((s->irq_state[irq].level & (cm)) != 0)
-#define GIC_SET_TRIGGER(irq) s->irq_state[irq].trigger = 1
-#define GIC_CLEAR_TRIGGER(irq) s->irq_state[irq].trigger = 0
-#define GIC_TEST_TRIGGER(irq) s->irq_state[irq].trigger
-#define GIC_GET_PRIORITY(irq, cpu) (((irq) < GIC_INTERNAL) ? \
- s->priority1[irq][cpu] : \
- s->priority2[(irq) - GIC_INTERNAL])
-#ifdef NVIC
-#define GIC_TARGET(irq) 1
-#else
-#define GIC_TARGET(irq) s->irq_target[irq]
-#endif
-
-typedef struct gic_state
-{
- SysBusDevice busdev;
- qemu_irq parent_irq[NCPU];
- int enabled;
- int cpu_enabled[NCPU];
-
- gic_irq_state irq_state[GIC_MAXIRQ];
-#ifndef NVIC
- int irq_target[GIC_MAXIRQ];
-#endif
- int priority1[GIC_INTERNAL][NCPU];
- int priority2[GIC_MAXIRQ - GIC_INTERNAL];
- int last_active[GIC_MAXIRQ][NCPU];
-
- int priority_mask[NCPU];
- int running_irq[NCPU];
- int running_priority[NCPU];
- int current_pending[NCPU];
-
-#if NCPU > 1
- uint32_t num_cpu;
-#endif
-
- MemoryRegion iomem; /* Distributor */
-#ifndef NVIC
- /* This is just so we can have an opaque pointer which identifies
- * both this GIC and which CPU interface we should be accessing.
- */
- struct gic_state *backref[NCPU];
- MemoryRegion cpuiomem[NCPU+1]; /* CPU interfaces */
-#endif
- uint32_t num_irq;
-} gic_state;
static inline int gic_get_current_cpu(gic_state *s)
{
-#if NCPU > 1
if (s->num_cpu > 1) {
return cpu_single_env->cpu_index;
}
-#endif
return 0;
}
/* TODO: Many places that call this routine could be optimized. */
/* Update interrupt status after enabled or pending bits have been changed. */
-static void gic_update(gic_state *s)
+void gic_update(gic_state *s)
{
int best_irq;
int best_prio;
}
}
-#ifdef NVIC
-static void gic_set_pending_private(gic_state *s, int cpu, int irq)
+void gic_set_pending_private(gic_state *s, int cpu, int irq)
{
int cm = 1 << cpu;
GIC_SET_PENDING(irq, cm);
gic_update(s);
}
-#endif
/* Process a change in an external IRQ input. */
static void gic_set_irq(void *opaque, int irq, int level)
gic_update(s);
}
-static uint32_t gic_acknowledge_irq(gic_state *s, int cpu)
+uint32_t gic_acknowledge_irq(gic_state *s, int cpu)
{
int new_irq;
int cm = 1 << cpu;
return new_irq;
}
-static void gic_complete_irq(gic_state * s, int cpu, int irq)
+void gic_complete_irq(gic_state *s, int cpu, int irq)
{
int update = 0;
int cm = 1 << cpu;
cpu = gic_get_current_cpu(s);
cm = 1 << cpu;
if (offset < 0x100) {
-#ifndef NVIC
if (offset == 0)
return s->enabled;
if (offset == 4)
/* Interrupt Security , RAZ/WI */
return 0;
}
-#endif
goto bad_reg;
} else if (offset < 0x200) {
/* Interrupt Set/Clear Enable. */
if (irq >= s->num_irq)
goto bad_reg;
res = GIC_GET_PRIORITY(irq, cpu);
-#ifndef NVIC
} else if (offset < 0xc00) {
/* Interrupt CPU Target. */
- irq = (offset - 0x800) + GIC_BASE_IRQ;
- if (irq >= s->num_irq)
- goto bad_reg;
- if (irq >= 29 && irq <= 31) {
- res = cm;
+ if (s->num_cpu == 1 && s->revision != REV_11MPCORE) {
+ /* For uniprocessor GICs these RAZ/WI */
+ res = 0;
} else {
- res = GIC_TARGET(irq);
+ irq = (offset - 0x800) + GIC_BASE_IRQ;
+ if (irq >= s->num_irq) {
+ goto bad_reg;
+ }
+ if (irq >= 29 && irq <= 31) {
+ res = cm;
+ } else {
+ res = GIC_TARGET(irq);
+ }
}
} else if (offset < 0xf00) {
/* Interrupt Configuration. */
if (GIC_TEST_TRIGGER(irq + i))
res |= (2 << (i * 2));
}
-#endif
} else if (offset < 0xfe0) {
goto bad_reg;
} else /* offset >= 0xfe0 */ {
static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset)
{
uint32_t val;
-#ifdef NVIC
- gic_state *s = (gic_state *)opaque;
- uint32_t addr;
- addr = offset;
- if (addr < 0x100 || addr > 0xd00)
- return nvic_readl(s, addr);
-#endif
val = gic_dist_readw(opaque, offset);
val |= gic_dist_readw(opaque, offset + 2) << 16;
return val;
cpu = gic_get_current_cpu(s);
if (offset < 0x100) {
-#ifdef NVIC
- goto bad_reg;
-#else
if (offset == 0) {
s->enabled = (value & 1);
DPRINTF("Distribution %sabled\n", s->enabled ? "En" : "Dis");
} else {
goto bad_reg;
}
-#endif
} else if (offset < 0x180) {
/* Interrupt Set Enable. */
irq = (offset - 0x100) * 8 + GIC_BASE_IRQ;
} else {
s->priority2[irq - GIC_INTERNAL] = value;
}
-#ifndef NVIC
} else if (offset < 0xc00) {
- /* Interrupt CPU Target. */
- irq = (offset - 0x800) + GIC_BASE_IRQ;
- if (irq >= s->num_irq)
- goto bad_reg;
- if (irq < 29)
- value = 0;
- else if (irq < GIC_INTERNAL)
- value = ALL_CPU_MASK;
- s->irq_target[irq] = value & ALL_CPU_MASK;
+ /* Interrupt CPU Target. RAZ/WI on uniprocessor GICs, with the
+ * annoying exception of the 11MPCore's GIC.
+ */
+ if (s->num_cpu != 1 || s->revision == REV_11MPCORE) {
+ irq = (offset - 0x800) + GIC_BASE_IRQ;
+ if (irq >= s->num_irq) {
+ goto bad_reg;
+ }
+ if (irq < 29) {
+ value = 0;
+ } else if (irq < GIC_INTERNAL) {
+ value = ALL_CPU_MASK;
+ }
+ s->irq_target[irq] = value & ALL_CPU_MASK;
+ }
} else if (offset < 0xf00) {
/* Interrupt Configuration. */
irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
GIC_CLEAR_TRIGGER(irq + i);
}
}
-#endif
} else {
/* 0xf00 is only handled for 32-bit writes. */
goto bad_reg;
uint32_t value)
{
gic_state *s = (gic_state *)opaque;
-#ifdef NVIC
- uint32_t addr;
- addr = offset;
- if (addr < 0x100 || (addr > 0xd00 && addr != 0xf00)) {
- nvic_writel(s, addr, value);
- return;
- }
-#endif
if (offset == 0xf00) {
int cpu;
int irq;
.endianness = DEVICE_NATIVE_ENDIAN,
};
-#ifndef NVIC
static uint32_t gic_cpu_read(gic_state *s, int cpu, int offset)
{
switch (offset) {
.write = gic_do_cpu_write,
.endianness = DEVICE_NATIVE_ENDIAN,
};
-#endif
-
-static void gic_reset(DeviceState *dev)
-{
- gic_state *s = FROM_SYSBUS(gic_state, sysbus_from_qdev(dev));
- int i;
- memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state));
- for (i = 0 ; i < NUM_CPU(s); i++) {
- s->priority_mask[i] = 0xf0;
- s->current_pending[i] = 1023;
- s->running_irq[i] = 1023;
- s->running_priority[i] = 0x100;
-#ifdef NVIC
- /* The NVIC doesn't have per-cpu interfaces, so enable by default. */
- s->cpu_enabled[i] = 1;
-#else
- s->cpu_enabled[i] = 0;
-#endif
- }
- for (i = 0; i < 16; i++) {
- GIC_SET_ENABLED(i, ALL_CPU_MASK);
- GIC_SET_TRIGGER(i);
- }
-#ifdef NVIC
- /* The NVIC is always enabled. */
- s->enabled = 1;
-#else
- s->enabled = 0;
-#endif
-}
-static void gic_save(QEMUFile *f, void *opaque)
-{
- gic_state *s = (gic_state *)opaque;
- int i;
- int j;
-
- qemu_put_be32(f, s->enabled);
- for (i = 0; i < NUM_CPU(s); i++) {
- qemu_put_be32(f, s->cpu_enabled[i]);
- for (j = 0; j < GIC_INTERNAL; j++)
- qemu_put_be32(f, s->priority1[j][i]);
- for (j = 0; j < s->num_irq; j++)
- qemu_put_be32(f, s->last_active[j][i]);
- qemu_put_be32(f, s->priority_mask[i]);
- qemu_put_be32(f, s->running_irq[i]);
- qemu_put_be32(f, s->running_priority[i]);
- qemu_put_be32(f, s->current_pending[i]);
- }
- for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) {
- qemu_put_be32(f, s->priority2[i]);
- }
- for (i = 0; i < s->num_irq; i++) {
-#ifndef NVIC
- qemu_put_be32(f, s->irq_target[i]);
-#endif
- qemu_put_byte(f, s->irq_state[i].enabled);
- qemu_put_byte(f, s->irq_state[i].pending);
- qemu_put_byte(f, s->irq_state[i].active);
- qemu_put_byte(f, s->irq_state[i].level);
- qemu_put_byte(f, s->irq_state[i].model);
- qemu_put_byte(f, s->irq_state[i].trigger);
- }
-}
-
-static int gic_load(QEMUFile *f, void *opaque, int version_id)
-{
- gic_state *s = (gic_state *)opaque;
- int i;
- int j;
-
- if (version_id != 2)
- return -EINVAL;
-
- s->enabled = qemu_get_be32(f);
- for (i = 0; i < NUM_CPU(s); i++) {
- s->cpu_enabled[i] = qemu_get_be32(f);
- for (j = 0; j < GIC_INTERNAL; j++)
- s->priority1[j][i] = qemu_get_be32(f);
- for (j = 0; j < s->num_irq; j++)
- s->last_active[j][i] = qemu_get_be32(f);
- s->priority_mask[i] = qemu_get_be32(f);
- s->running_irq[i] = qemu_get_be32(f);
- s->running_priority[i] = qemu_get_be32(f);
- s->current_pending[i] = qemu_get_be32(f);
- }
- for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) {
- s->priority2[i] = qemu_get_be32(f);
- }
- for (i = 0; i < s->num_irq; i++) {
-#ifndef NVIC
- s->irq_target[i] = qemu_get_be32(f);
-#endif
- s->irq_state[i].enabled = qemu_get_byte(f);
- s->irq_state[i].pending = qemu_get_byte(f);
- s->irq_state[i].active = qemu_get_byte(f);
- s->irq_state[i].level = qemu_get_byte(f);
- s->irq_state[i].model = qemu_get_byte(f);
- s->irq_state[i].trigger = qemu_get_byte(f);
- }
-
- return 0;
-}
-
-#if NCPU > 1
-static void gic_init(gic_state *s, int num_cpu, int num_irq)
-#else
-static void gic_init(gic_state *s, int num_irq)
-#endif
+void gic_init_irqs_and_distributor(gic_state *s, int num_irq)
{
int i;
-#if NCPU > 1
- s->num_cpu = num_cpu;
- if (s->num_cpu > NCPU) {
- hw_error("requested %u CPUs exceeds GIC maximum %d\n",
- num_cpu, NCPU);
- }
-#endif
- s->num_irq = num_irq + GIC_BASE_IRQ;
- if (s->num_irq > GIC_MAXIRQ) {
- hw_error("requested %u interrupt lines exceeds GIC maximum %d\n",
- num_irq, GIC_MAXIRQ);
- }
- /* ITLinesNumber is represented as (N / 32) - 1 (see
- * gic_dist_readb) so this is an implementation imposed
- * restriction, not an architectural one:
- */
- if (s->num_irq < 32 || (s->num_irq % 32)) {
- hw_error("%d interrupt lines unsupported: not divisible by 32\n",
- num_irq);
- }
-
i = s->num_irq - GIC_INTERNAL;
-#ifndef NVIC
/* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
* GPIO array layout is thus:
* [0..N-1] SPIs
* [N+32..N+63] PPIs for CPU 1
* ...
*/
- i += (GIC_INTERNAL * num_cpu);
-#endif
+ if (s->revision != REV_NVIC) {
+ i += (GIC_INTERNAL * s->num_cpu);
+ }
qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, i);
for (i = 0; i < NUM_CPU(s); i++) {
sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
}
memory_region_init_io(&s->iomem, &gic_dist_ops, s, "gic_dist", 0x1000);
-#ifndef NVIC
+}
+
+static int arm_gic_init(SysBusDevice *dev)
+{
+ /* Device instance init function for the GIC sysbus device */
+ int i;
+ gic_state *s = FROM_SYSBUS(gic_state, dev);
+ ARMGICClass *agc = ARM_GIC_GET_CLASS(s);
+
+ agc->parent_init(dev);
+
+ gic_init_irqs_and_distributor(s, s->num_irq);
+
/* Memory regions for the CPU interfaces (NVIC doesn't have these):
* a region for "CPU interface for this core", then a region for
* "CPU interface for core 0", "for core 1", ...
memory_region_init_io(&s->cpuiomem[i+1], &gic_cpu_ops, &s->backref[i],
"gic_cpu", 0x100);
}
-#endif
-
- register_savevm(NULL, "arm_gic", -1, 2, gic_save, gic_load, s);
-}
-
-#ifndef NVIC
-
-static int arm_gic_init(SysBusDevice *dev)
-{
- /* Device instance init function for the GIC sysbus device */
- int i;
- gic_state *s = FROM_SYSBUS(gic_state, dev);
- gic_init(s, s->num_cpu, s->num_irq);
/* Distributor */
sysbus_init_mmio(dev, &s->iomem);
/* cpu interfaces (one for "current cpu" plus one per cpu) */
return 0;
}
-static Property arm_gic_properties[] = {
- DEFINE_PROP_UINT32("num-cpu", gic_state, num_cpu, 1),
- DEFINE_PROP_UINT32("num-irq", gic_state, num_irq, 32),
- DEFINE_PROP_END_OF_LIST(),
-};
-
static void arm_gic_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+ ARMGICClass *agc = ARM_GIC_CLASS(klass);
+ agc->parent_init = sbc->init;
sbc->init = arm_gic_init;
- dc->props = arm_gic_properties;
- dc->reset = gic_reset;
dc->no_user = 1;
}
static TypeInfo arm_gic_info = {
- .name = "arm_gic",
- .parent = TYPE_SYS_BUS_DEVICE,
+ .name = TYPE_ARM_GIC,
+ .parent = TYPE_ARM_GIC_COMMON,
.instance_size = sizeof(gic_state),
.class_init = arm_gic_class_init,
};
}
type_init(arm_gic_register_types)
-
-#endif
--- /dev/null
+/*
+ * ARM GIC support - common bits of emulated and KVM kernel model
+ *
+ * Copyright (c) 2012 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "arm_gic_internal.h"
+
+static void gic_save(QEMUFile *f, void *opaque)
+{
+ gic_state *s = (gic_state *)opaque;
+ int i;
+ int j;
+
+ qemu_put_be32(f, s->enabled);
+ for (i = 0; i < s->num_cpu; i++) {
+ qemu_put_be32(f, s->cpu_enabled[i]);
+ for (j = 0; j < GIC_INTERNAL; j++) {
+ qemu_put_be32(f, s->priority1[j][i]);
+ }
+ for (j = 0; j < s->num_irq; j++) {
+ qemu_put_be32(f, s->last_active[j][i]);
+ }
+ qemu_put_be32(f, s->priority_mask[i]);
+ qemu_put_be32(f, s->running_irq[i]);
+ qemu_put_be32(f, s->running_priority[i]);
+ qemu_put_be32(f, s->current_pending[i]);
+ }
+ for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) {
+ qemu_put_be32(f, s->priority2[i]);
+ }
+ for (i = 0; i < s->num_irq; i++) {
+ qemu_put_be32(f, s->irq_target[i]);
+ qemu_put_byte(f, s->irq_state[i].enabled);
+ qemu_put_byte(f, s->irq_state[i].pending);
+ qemu_put_byte(f, s->irq_state[i].active);
+ qemu_put_byte(f, s->irq_state[i].level);
+ qemu_put_byte(f, s->irq_state[i].model);
+ qemu_put_byte(f, s->irq_state[i].trigger);
+ }
+}
+
+static int gic_load(QEMUFile *f, void *opaque, int version_id)
+{
+ gic_state *s = (gic_state *)opaque;
+ int i;
+ int j;
+
+ if (version_id != 3) {
+ return -EINVAL;
+ }
+
+ s->enabled = qemu_get_be32(f);
+ for (i = 0; i < s->num_cpu; i++) {
+ s->cpu_enabled[i] = qemu_get_be32(f);
+ for (j = 0; j < GIC_INTERNAL; j++) {
+ s->priority1[j][i] = qemu_get_be32(f);
+ }
+ for (j = 0; j < s->num_irq; j++) {
+ s->last_active[j][i] = qemu_get_be32(f);
+ }
+ s->priority_mask[i] = qemu_get_be32(f);
+ s->running_irq[i] = qemu_get_be32(f);
+ s->running_priority[i] = qemu_get_be32(f);
+ s->current_pending[i] = qemu_get_be32(f);
+ }
+ for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) {
+ s->priority2[i] = qemu_get_be32(f);
+ }
+ for (i = 0; i < s->num_irq; i++) {
+ s->irq_target[i] = qemu_get_be32(f);
+ s->irq_state[i].enabled = qemu_get_byte(f);
+ s->irq_state[i].pending = qemu_get_byte(f);
+ s->irq_state[i].active = qemu_get_byte(f);
+ s->irq_state[i].level = qemu_get_byte(f);
+ s->irq_state[i].model = qemu_get_byte(f);
+ s->irq_state[i].trigger = qemu_get_byte(f);
+ }
+
+ return 0;
+}
+
+static int arm_gic_common_init(SysBusDevice *dev)
+{
+ gic_state *s = FROM_SYSBUS(gic_state, dev);
+ int num_irq = s->num_irq;
+
+ if (s->num_cpu > NCPU) {
+ hw_error("requested %u CPUs exceeds GIC maximum %d\n",
+ s->num_cpu, NCPU);
+ }
+ s->num_irq += GIC_BASE_IRQ;
+ if (s->num_irq > GIC_MAXIRQ) {
+ hw_error("requested %u interrupt lines exceeds GIC maximum %d\n",
+ num_irq, GIC_MAXIRQ);
+ }
+ /* ITLinesNumber is represented as (N / 32) - 1 (see
+ * gic_dist_readb) so this is an implementation imposed
+ * restriction, not an architectural one:
+ */
+ if (s->num_irq < 32 || (s->num_irq % 32)) {
+ hw_error("%d interrupt lines unsupported: not divisible by 32\n",
+ num_irq);
+ }
+
+ register_savevm(NULL, "arm_gic", -1, 3, gic_save, gic_load, s);
+ return 0;
+}
+
+static void arm_gic_common_reset(DeviceState *dev)
+{
+ gic_state *s = FROM_SYSBUS(gic_state, sysbus_from_qdev(dev));
+ int i;
+ memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state));
+ for (i = 0 ; i < s->num_cpu; i++) {
+ s->priority_mask[i] = 0xf0;
+ s->current_pending[i] = 1023;
+ s->running_irq[i] = 1023;
+ s->running_priority[i] = 0x100;
+ s->cpu_enabled[i] = 0;
+ }
+ for (i = 0; i < 16; i++) {
+ GIC_SET_ENABLED(i, ALL_CPU_MASK);
+ GIC_SET_TRIGGER(i);
+ }
+ if (s->num_cpu == 1) {
+ /* For uniprocessor GICs all interrupts always target the sole CPU */
+ for (i = 0; i < GIC_MAXIRQ; i++) {
+ s->irq_target[i] = 1;
+ }
+ }
+ s->enabled = 0;
+}
+
+static Property arm_gic_common_properties[] = {
+ DEFINE_PROP_UINT32("num-cpu", gic_state, num_cpu, 1),
+ DEFINE_PROP_UINT32("num-irq", gic_state, num_irq, 32),
+ /* Revision can be 1 or 2 for GIC architecture specification
+ * versions 1 or 2, or 0 to indicate the legacy 11MPCore GIC.
+ * (Internally, 0xffffffff also indicates "not a GIC but an NVIC".)
+ */
+ DEFINE_PROP_UINT32("revision", gic_state, revision, 1),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void arm_gic_common_class_init(ObjectClass *klass, void *data)
+{
+ SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ dc->reset = arm_gic_common_reset;
+ dc->props = arm_gic_common_properties;
+ dc->no_user = 1;
+ sc->init = arm_gic_common_init;
+}
+
+static TypeInfo arm_gic_common_type = {
+ .name = TYPE_ARM_GIC_COMMON,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(gic_state),
+ .class_size = sizeof(ARMGICCommonClass),
+ .class_init = arm_gic_common_class_init,
+ .abstract = true,
+};
+
+static void register_types(void)
+{
+ type_register_static(&arm_gic_common_type);
+}
+
+type_init(register_types)
--- /dev/null
+/*
+ * ARM GIC support - internal interfaces
+ *
+ * Copyright (c) 2012 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QEMU_ARM_GIC_INTERNAL_H
+#define QEMU_ARM_GIC_INTERNAL_H
+
+#include "sysbus.h"
+
+/* Maximum number of possible interrupts, determined by the GIC architecture */
+#define GIC_MAXIRQ 1020
+/* First 32 are private to each CPU (SGIs and PPIs). */
+#define GIC_INTERNAL 32
+/* Maximum number of possible CPU interfaces, determined by GIC architecture */
+#define NCPU 8
+
+#define ALL_CPU_MASK ((unsigned)(((1 << NCPU) - 1)))
+
+/* The NVIC has 16 internal vectors. However these are not exposed
+ through the normal GIC interface. */
+#define GIC_BASE_IRQ ((s->revision == REV_NVIC) ? 32 : 0)
+
+#define GIC_SET_ENABLED(irq, cm) s->irq_state[irq].enabled |= (cm)
+#define GIC_CLEAR_ENABLED(irq, cm) s->irq_state[irq].enabled &= ~(cm)
+#define GIC_TEST_ENABLED(irq, cm) ((s->irq_state[irq].enabled & (cm)) != 0)
+#define GIC_SET_PENDING(irq, cm) s->irq_state[irq].pending |= (cm)
+#define GIC_CLEAR_PENDING(irq, cm) s->irq_state[irq].pending &= ~(cm)
+#define GIC_TEST_PENDING(irq, cm) ((s->irq_state[irq].pending & (cm)) != 0)
+#define GIC_SET_ACTIVE(irq, cm) s->irq_state[irq].active |= (cm)
+#define GIC_CLEAR_ACTIVE(irq, cm) s->irq_state[irq].active &= ~(cm)
+#define GIC_TEST_ACTIVE(irq, cm) ((s->irq_state[irq].active & (cm)) != 0)
+#define GIC_SET_MODEL(irq) s->irq_state[irq].model = 1
+#define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = 0
+#define GIC_TEST_MODEL(irq) s->irq_state[irq].model
+#define GIC_SET_LEVEL(irq, cm) s->irq_state[irq].level = (cm)
+#define GIC_CLEAR_LEVEL(irq, cm) s->irq_state[irq].level &= ~(cm)
+#define GIC_TEST_LEVEL(irq, cm) ((s->irq_state[irq].level & (cm)) != 0)
+#define GIC_SET_TRIGGER(irq) s->irq_state[irq].trigger = 1
+#define GIC_CLEAR_TRIGGER(irq) s->irq_state[irq].trigger = 0
+#define GIC_TEST_TRIGGER(irq) s->irq_state[irq].trigger
+#define GIC_GET_PRIORITY(irq, cpu) (((irq) < GIC_INTERNAL) ? \
+ s->priority1[irq][cpu] : \
+ s->priority2[(irq) - GIC_INTERNAL])
+#define GIC_TARGET(irq) s->irq_target[irq]
+
+typedef struct gic_irq_state {
+ /* The enable bits are only banked for per-cpu interrupts. */
+ unsigned enabled:NCPU;
+ unsigned pending:NCPU;
+ unsigned active:NCPU;
+ unsigned level:NCPU;
+ unsigned model:1; /* 0 = N:N, 1 = 1:N */
+ unsigned trigger:1; /* nonzero = edge triggered. */
+} gic_irq_state;
+
+typedef struct gic_state {
+ SysBusDevice busdev;
+ qemu_irq parent_irq[NCPU];
+ int enabled;
+ int cpu_enabled[NCPU];
+
+ gic_irq_state irq_state[GIC_MAXIRQ];
+ int irq_target[GIC_MAXIRQ];
+ int priority1[GIC_INTERNAL][NCPU];
+ int priority2[GIC_MAXIRQ - GIC_INTERNAL];
+ int last_active[GIC_MAXIRQ][NCPU];
+
+ int priority_mask[NCPU];
+ int running_irq[NCPU];
+ int running_priority[NCPU];
+ int current_pending[NCPU];
+
+ uint32_t num_cpu;
+
+ MemoryRegion iomem; /* Distributor */
+ /* This is just so we can have an opaque pointer which identifies
+ * both this GIC and which CPU interface we should be accessing.
+ */
+ struct gic_state *backref[NCPU];
+ MemoryRegion cpuiomem[NCPU+1]; /* CPU interfaces */
+ uint32_t num_irq;
+ uint32_t revision;
+} gic_state;
+
+/* The special cases for the revision property: */
+#define REV_11MPCORE 0
+#define REV_NVIC 0xffffffff
+
+void gic_set_pending_private(gic_state *s, int cpu, int irq);
+uint32_t gic_acknowledge_irq(gic_state *s, int cpu);
+void gic_complete_irq(gic_state *s, int cpu, int irq);
+void gic_update(gic_state *s);
+void gic_init_irqs_and_distributor(gic_state *s, int num_irq);
+
+#define TYPE_ARM_GIC_COMMON "arm_gic_common"
+#define ARM_GIC_COMMON(obj) \
+ OBJECT_CHECK(gic_state, (obj), TYPE_ARM_GIC_COMMON)
+#define ARM_GIC_COMMON_CLASS(klass) \
+ OBJECT_CLASS_CHECK(ARMGICCommonClass, (klass), TYPE_ARM_GIC_COMMON)
+#define ARM_GIC_COMMON_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(ARMGICCommonClass, (obj), TYPE_ARM_GIC_COMMON)
+
+typedef struct ARMGICCommonClass {
+ SysBusDeviceClass parent_class;
+} ARMGICCommonClass;
+
+#define TYPE_ARM_GIC "arm_gic"
+#define ARM_GIC(obj) \
+ OBJECT_CHECK(gic_state, (obj), TYPE_ARM_GIC)
+#define ARM_GIC_CLASS(klass) \
+ OBJECT_CLASS_CHECK(ARMGICClass, (klass), TYPE_ARM_GIC)
+#define ARM_GIC_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(ARMGICClass, (obj), TYPE_ARM_GIC)
+
+typedef struct ARMGICClass {
+ ARMGICCommonClass parent_class;
+ int (*parent_init)(SysBusDevice *dev);
+} ARMGICClass;
+
+#endif /* !QEMU_ARM_GIC_INTERNAL_H */
}
static Property l2x0_properties[] = {
- DEFINE_PROP_UINT32("type", l2x0_state, cache_type, 0x1c100100),
+ DEFINE_PROP_UINT32("cache-type", l2x0_state, cache_type, 0x1c100100),
DEFINE_PROP_END_OF_LIST(),
};
#include "qemu-timer.h"
#include "arm-misc.h"
#include "exec-memory.h"
-
-#define NVIC 1
-
-static uint32_t nvic_readl(void *opaque, uint32_t offset);
-static void nvic_writel(void *opaque, uint32_t offset, uint32_t value);
-
-#include "arm_gic.c"
+#include "arm_gic_internal.h"
typedef struct {
gic_state gic;
int64_t tick;
QEMUTimer *timer;
} systick;
+ MemoryRegion sysregmem;
+ MemoryRegion gic_iomem_alias;
+ MemoryRegion container;
uint32_t num_irq;
} nvic_state;
+#define TYPE_NVIC "armv7m_nvic"
+/**
+ * NVICClass:
+ * @parent_reset: the parent class' reset handler.
+ *
+ * A model of the v7M NVIC and System Controller
+ */
+typedef struct NVICClass {
+ /*< private >*/
+ ARMGICClass parent_class;
+ /*< public >*/
+ int (*parent_init)(SysBusDevice *dev);
+ void (*parent_reset)(DeviceState *dev);
+} NVICClass;
+
+#define NVIC_CLASS(klass) \
+ OBJECT_CLASS_CHECK(NVICClass, (klass), TYPE_NVIC)
+#define NVIC_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(NVICClass, (obj), TYPE_NVIC)
+#define NVIC(obj) \
+ OBJECT_CHECK(nvic_state, (obj), TYPE_NVIC)
+
+static const uint8_t nvic_id[] = {
+ 0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1
+};
+
/* qemu timers run at 1GHz. We want something closer to 1MHz. */
#define SYSTICK_SCALE 1000ULL
case 0xd38: /* Bus Fault Address. */
case 0xd3c: /* Aux Fault Status. */
goto bad_reg;
+ case 0xf00: /* Software Triggered Interrupt Register */
+ if ((value & 0x1ff) < s->num_irq) {
+ gic_set_pending_private(&s->gic, 0, value & 0x1ff);
+ }
+ break;
default:
bad_reg:
hw_error("NVIC: Bad write offset 0x%x\n", offset);
}
}
+static uint64_t nvic_sysreg_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
+{
+ /* At the moment we only support the ID registers for byte/word access.
+ * This is not strictly correct as a few of the other registers also
+ * allow byte access.
+ */
+ uint32_t offset = addr;
+ if (offset >= 0xfe0) {
+ if (offset & 3) {
+ return 0;
+ }
+ return nvic_id[(offset - 0xfe0) >> 2];
+ }
+ if (size == 4) {
+ return nvic_readl(opaque, offset);
+ }
+ hw_error("NVIC: Bad read of size %d at offset 0x%x\n", size, offset);
+}
+
+static void nvic_sysreg_write(void *opaque, target_phys_addr_t addr,
+ uint64_t value, unsigned size)
+{
+ uint32_t offset = addr;
+ if (size == 4) {
+ nvic_writel(opaque, offset, value);
+ return;
+ }
+ hw_error("NVIC: Bad write of size %d at offset 0x%x\n", size, offset);
+}
+
+static const MemoryRegionOps nvic_sysreg_ops = {
+ .read = nvic_sysreg_read,
+ .write = nvic_sysreg_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
static const VMStateDescription vmstate_nvic = {
.name = "armv7m_nvic",
.version_id = 1,
static void armv7m_nvic_reset(DeviceState *dev)
{
- nvic_state *s = FROM_SYSBUSGIC(nvic_state, sysbus_from_qdev(dev));
- gic_reset(&s->gic.busdev.qdev);
+ nvic_state *s = NVIC(dev);
+ NVICClass *nc = NVIC_GET_CLASS(s);
+ nc->parent_reset(dev);
+ /* Common GIC reset resets to disabled; the NVIC doesn't have
+ * per-CPU interfaces so mark our non-existent CPU interface
+ * as enabled by default.
+ */
+ s->gic.cpu_enabled[0] = 1;
+ /* The NVIC as a whole is always enabled. */
+ s->gic.enabled = 1;
systick_reset(s);
}
static int armv7m_nvic_init(SysBusDevice *dev)
{
- nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev);
+ nvic_state *s = NVIC(dev);
+ NVICClass *nc = NVIC_GET_CLASS(s);
- /* note that for the M profile gic_init() takes the number of external
- * interrupt lines only.
- */
- gic_init(&s->gic, s->num_irq);
- memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->gic.iomem);
+ /* The NVIC always has only one CPU */
+ s->gic.num_cpu = 1;
+ /* Tell the common code we're an NVIC */
+ s->gic.revision = 0xffffffff;
+ s->gic.num_irq = s->num_irq;
+ nc->parent_init(dev);
+ gic_init_irqs_and_distributor(&s->gic, s->num_irq);
+ /* The NVIC and system controller register area looks like this:
+ * 0..0xff : system control registers, including systick
+ * 0x100..0xcff : GIC-like registers
+ * 0xd00..0xfff : system control registers
+ * We use overlaying to put the GIC like registers
+ * over the top of the system control register region.
+ */
+ memory_region_init(&s->container, "nvic", 0x1000);
+ /* The system register region goes at the bottom of the priority
+ * stack as it covers the whole page.
+ */
+ memory_region_init_io(&s->sysregmem, &nvic_sysreg_ops, s,
+ "nvic_sysregs", 0x1000);
+ memory_region_add_subregion(&s->container, 0, &s->sysregmem);
+ /* Alias the GIC region so we can get only the section of it
+ * we need, and layer it on top of the system register region.
+ */
+ 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);
+ /* Map the whole thing into system memory at the location required
+ * by the v7M architecture.
+ */
+ memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->container);
s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s);
return 0;
}
static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
{
+ NVICClass *nc = NVIC_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+ nc->parent_reset = dc->reset;
+ nc->parent_init = sdc->init;
sdc->init = armv7m_nvic_init;
dc->vmsd = &vmstate_nvic;
dc->reset = armv7m_nvic_reset;
}
static TypeInfo armv7m_nvic_info = {
- .name = "armv7m_nvic",
- .parent = TYPE_SYS_BUS_DEVICE,
+ .name = TYPE_NVIC,
+ .parent = TYPE_ARM_GIC_COMMON,
.instance_size = sizeof(nvic_state),
.class_init = armv7m_nvic_class_init,
+ .class_size = sizeof(NVICClass),
};
static void armv7m_nvic_register_types(void)
const char *default_machine_opts;
GlobalProperty *compat_props;
struct QEMUMachine *next;
+ const char *hw_version;
} QEMUMachine;
int qemu_register_machine(QEMUMachine *m);
ATTRIBUTE(DOC_URL, URL("http://bellard.org/qemu/user-doc.html"))
ATTRIBUTE(SVCNAME_PRIMARY, STRING("QEMU Bluetooth HID"))
ATTRIBUTE(SVCDESC_PRIMARY, STRING("QEMU Keyboard/Mouse"))
- ATTRIBUTE(SVCPROV_PRIMARY, STRING("QEMU " QEMU_VERSION))
+ ATTRIBUTE(SVCPROV_PRIMARY, STRING("QEMU"))
/* Profile specific */
ATTRIBUTE(DEVICE_RELEASE_NUMBER, UINT16(0x0091)) /* Deprecated, remove */
LIST(UUID128(SDP_SERVER_PROFILE_ID) UINT16(0x0100))
))
ATTRIBUTE(DOC_URL, URL("http://bellard.org/qemu/user-doc.html"))
- ATTRIBUTE(SVCPROV_PRIMARY, STRING("QEMU " QEMU_VERSION))
+ ATTRIBUTE(SVCPROV_PRIMARY, STRING("QEMU"))
/* Profile specific */
ATTRIBUTE(VERSION_NUM_LIST, LIST(UINT16(0x0100)))
LIST(UUID128(PNP_INFO_PROFILE_ID) UINT16(0x0100))
))
ATTRIBUTE(DOC_URL, URL("http://bellard.org/qemu/user-doc.html"))
- ATTRIBUTE(SVCPROV_PRIMARY, STRING("QEMU " QEMU_VERSION))
+ ATTRIBUTE(SVCPROV_PRIMARY, STRING("QEMU"))
/* Profile specific */
ATTRIBUTE(SPECIFICATION_ID, UINT16(0x0100))
*/
memcpy(rxbuf, buf, size);
- memset(rxbuf + size, 0, sizeof(rxbuf - size));
+ memset(rxbuf + size, 0, sizeof(rxbuf) - size);
rxbuf_ptr = rxbuf;
crc_val = cpu_to_le32(crc32(0, rxbuf, MAX(size, 60)));
if (size < 60) {
int i;
for (i = 0; i < 3; ++i) {
- cadence_timer_init(2500000, &s->timer[i]);
+ cadence_timer_init(133000000, &s->timer[i]);
sysbus_init_irq(dev, &s->timer[i].irq);
}
Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
unsigned long ram_size)
{
- qemu_irq cpu_irq[4];
- int n;
+ qemu_irq cpu_irq[EXYNOS4210_NCPUS];
+ int i, n;
Exynos4210State *s = g_new(Exynos4210State, 1);
qemu_irq *irqp;
- qemu_irq gate_irq[EXYNOS4210_IRQ_GATE_NINPUTS];
+ qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
unsigned long mem_size;
DeviceState *dev;
SysBusDevice *busdev;
s->irq_table = exynos4210_init_irq(&s->irqs);
/* IRQ Gate */
- dev = qdev_create(NULL, "exynos4210.irq_gate");
- qdev_init_nofail(dev);
- /* Get IRQ Gate input in gate_irq */
- for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
- gate_irq[n] = qdev_get_gpio_in(dev, n);
- }
- busdev = sysbus_from_qdev(dev);
- /* Connect IRQ Gate output to cpu_irq */
- for (n = 0; n < EXYNOS4210_NCPUS; n++) {
- sysbus_connect_irq(busdev, n, cpu_irq[n]);
+ for (i = 0; i < EXYNOS4210_NCPUS; i++) {
+ dev = qdev_create(NULL, "exynos4210.irq_gate");
+ qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
+ qdev_init_nofail(dev);
+ /* Get IRQ Gate input in gate_irq */
+ for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
+ gate_irq[i][n] = qdev_get_gpio_in(dev, n);
+ }
+ busdev = sysbus_from_qdev(dev);
+
+ /* Connect IRQ Gate output to cpu_irq */
+ sysbus_connect_irq(busdev, 0, cpu_irq[i]);
}
/* Private memory region and Internal GIC */
busdev = sysbus_from_qdev(dev);
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
- sysbus_connect_irq(busdev, n, gate_irq[n * 2]);
+ sysbus_connect_irq(busdev, n, gate_irq[n][0]);
}
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
/* Map Distributer interface */
sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
- sysbus_connect_irq(busdev, n, gate_irq[n * 2 + 1]);
+ sysbus_connect_irq(busdev, n, gate_irq[n][1]);
}
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
/*
* exynos4210 IRQ subsystem stub definitions.
*/
-#define EXYNOS4210_IRQ_GATE_NINPUTS 8
+#define EXYNOS4210_IRQ_GATE_NINPUTS 2 /* Internal and External GIC */
#define EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ 64
#define EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ 16
type_init(exynos4210_gic_register_types)
-/*
- * IRQGate struct.
- * IRQ Gate represents OR gate between GICs to pass IRQ to PIC.
+/* IRQ OR Gate struct.
+ *
+ * This device models an OR gate. There are n_in input qdev gpio lines and one
+ * output sysbus IRQ line. The output IRQ level is formed as OR between all
+ * gpio inputs.
*/
typedef struct {
SysBusDevice busdev;
- qemu_irq pic_irq[EXYNOS4210_NCPUS]; /* output IRQs to PICs */
- uint32_t gpio_level[EXYNOS4210_IRQ_GATE_NINPUTS]; /* Input levels */
+ uint32_t n_in; /* inputs amount */
+ uint32_t *level; /* input levels */
+ qemu_irq out; /* output IRQ */
} Exynos4210IRQGateState;
+static Property exynos4210_irq_gate_properties[] = {
+ DEFINE_PROP_UINT32("n_in", Exynos4210IRQGateState, n_in, 1),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static const VMStateDescription vmstate_exynos4210_irq_gate = {
.name = "exynos4210.irq_gate",
- .version_id = 1,
- .minimum_version_id = 1,
- .minimum_version_id_old = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
+ .minimum_version_id_old = 2,
.fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(gpio_level, Exynos4210IRQGateState,
- EXYNOS4210_IRQ_GATE_NINPUTS),
+ VMSTATE_VBUFFER_UINT32(level, Exynos4210IRQGateState, 1, NULL, 0, n_in),
VMSTATE_END_OF_LIST()
}
};
-/* Process a change in an external IRQ input. */
+/* Process a change in IRQ input. */
static void exynos4210_irq_gate_handler(void *opaque, int irq, int level)
{
- Exynos4210IRQGateState *s =
- (Exynos4210IRQGateState *)opaque;
- uint32_t odd, even;
-
- if (irq & 1) {
- odd = irq;
- even = irq & ~1;
- } else {
- even = irq;
- odd = irq | 1;
- }
+ Exynos4210IRQGateState *s = (Exynos4210IRQGateState *)opaque;
+ uint32_t i;
- assert(irq < EXYNOS4210_IRQ_GATE_NINPUTS);
- s->gpio_level[irq] = level;
+ assert(irq < s->n_in);
- if (s->gpio_level[odd] >= 1 || s->gpio_level[even] >= 1) {
- qemu_irq_raise(s->pic_irq[even >> 1]);
- } else {
- qemu_irq_lower(s->pic_irq[even >> 1]);
+ s->level[irq] = level;
+
+ for (i = 0; i < s->n_in; i++) {
+ if (s->level[i] >= 1) {
+ qemu_irq_raise(s->out);
+ return;
+ }
}
+ qemu_irq_lower(s->out);
+
return;
}
static void exynos4210_irq_gate_reset(DeviceState *d)
{
- Exynos4210IRQGateState *s = (Exynos4210IRQGateState *)d;
+ Exynos4210IRQGateState *s =
+ DO_UPCAST(Exynos4210IRQGateState, busdev.qdev, d);
- memset(&s->gpio_level, 0, sizeof(s->gpio_level));
+ memset(s->level, 0, s->n_in * sizeof(*s->level));
}
/*
*/
static int exynos4210_irq_gate_init(SysBusDevice *dev)
{
- unsigned int i;
- Exynos4210IRQGateState *s =
- FROM_SYSBUS(Exynos4210IRQGateState, dev);
+ Exynos4210IRQGateState *s = FROM_SYSBUS(Exynos4210IRQGateState, dev);
/* Allocate general purpose input signals and connect a handler to each of
* them */
- qdev_init_gpio_in(&s->busdev.qdev, exynos4210_irq_gate_handler,
- EXYNOS4210_IRQ_GATE_NINPUTS);
+ qdev_init_gpio_in(&s->busdev.qdev, exynos4210_irq_gate_handler, s->n_in);
- /* Connect SysBusDev irqs to device specific irqs */
- for (i = 0; i < EXYNOS4210_NCPUS; i++) {
- sysbus_init_irq(dev, &s->pic_irq[i]);
- }
+ s->level = g_malloc0(s->n_in * sizeof(*s->level));
+
+ sysbus_init_irq(dev, &s->out);
return 0;
}
k->init = exynos4210_irq_gate_init;
dc->reset = exynos4210_irq_gate_reset;
dc->vmsd = &vmstate_exynos4210_irq_gate;
+ dc->props = exynos4210_irq_gate_properties;
}
static TypeInfo exynos4210_irq_gate_info = {
#include "qdev-addr.h"
#include "blockdev.h"
#include "sysemu.h"
+#include "qemu-log.h"
/********************************************************/
/* debug Floppy devices */
#define FLOPPY_DPRINTF(fmt, ...)
#endif
-#define FLOPPY_ERROR(fmt, ...) \
- do { printf("FLOPPY ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } while (0)
-
/********************************************************/
/* Floppy drive emulation */
if (sector != fd_sector(drv)) {
#if 0
if (!enable_seek) {
- FLOPPY_ERROR("no implicit seek %d %02x %02x (max=%d %02x %02x)\n",
- head, track, sect, 1, drv->max_track, drv->last_sect);
+ FLOPPY_DPRINTF("error: no implicit seek %d %02x %02x"
+ " (max=%d %02x %02x)\n",
+ head, track, sect, 1, drv->max_track,
+ drv->last_sect);
return 4;
}
#endif
drv->sect = sect;
}
+ if (drv->bs == NULL || !bdrv_is_inserted(drv->bs)) {
+ ret = 2;
+ }
+
return ret;
}
/* Set an error: unimplemented/unknown command */
static void fdctrl_unimplemented(FDCtrl *fdctrl, int direction)
{
- FLOPPY_ERROR("unimplemented command 0x%02x\n", fdctrl->fifo[0]);
+ qemu_log_mask(LOG_UNIMP, "fdc: unimplemented command 0x%02x\n",
+ fdctrl->fifo[0]);
fdctrl->fifo[0] = FD_SR0_INVCMD;
fdctrl_set_fifo(fdctrl, 1, 0);
}
DMA_schedule(fdctrl->dma_chann);
return;
} else {
- FLOPPY_ERROR("dma_mode=%d direction=%d\n", dma_mode, direction);
+ FLOPPY_DPRINTF("bad dma_mode=%d direction=%d\n", dma_mode,
+ direction);
}
}
FLOPPY_DPRINTF("start non-DMA transfer\n");
/* Prepare a transfer of deleted data */
static void fdctrl_start_transfer_del(FDCtrl *fdctrl, int direction)
{
- FLOPPY_ERROR("fdctrl_start_transfer_del() unimplemented\n");
+ qemu_log_mask(LOG_UNIMP, "fdctrl_start_transfer_del() unimplemented\n");
/* We don't handle deleted data,
* so we don't return *ANYTHING*
fdctrl->data_pos, len);
if (bdrv_write(cur_drv->bs, fd_sector(cur_drv),
fdctrl->fifo, 1) < 0) {
- FLOPPY_ERROR("writing sector %d\n", fd_sector(cur_drv));
+ FLOPPY_DPRINTF("error writing sector %d\n",
+ fd_sector(cur_drv));
fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
goto transfer_error;
}
cur_drv = get_cur_drv(fdctrl);
fdctrl->dsr &= ~FD_DSR_PWRDOWN;
if (!(fdctrl->msr & FD_MSR_RQM) || !(fdctrl->msr & FD_MSR_DIO)) {
- FLOPPY_ERROR("controller not ready for reading\n");
+ FLOPPY_DPRINTF("error: controller not ready for reading\n");
return 0;
}
pos = fdctrl->data_pos;
memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
if (cur_drv->bs == NULL ||
bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
- FLOPPY_ERROR("formatting sector %d\n", fd_sector(cur_drv));
+ FLOPPY_DPRINTF("error formatting sector %d\n", fd_sector(cur_drv));
fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
} else {
if (cur_drv->sect == cur_drv->last_sect) {
return;
}
if (!(fdctrl->msr & FD_MSR_RQM) || (fdctrl->msr & FD_MSR_DIO)) {
- FLOPPY_ERROR("controller not ready for writing\n");
+ FLOPPY_DPRINTF("error: controller not ready for writing\n");
return;
}
fdctrl->dsr &= ~FD_DSR_PWRDOWN;
fdctrl->data_pos == fdctrl->data_len) {
cur_drv = get_cur_drv(fdctrl);
if (bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
- FLOPPY_ERROR("writing sector %d\n", fd_sector(cur_drv));
+ FLOPPY_DPRINTF("error writing sector %d\n",
+ fd_sector(cur_drv));
return;
}
if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
return 0;
}
+ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds)
+{
+ ISADevice *dev;
+
+ dev = isa_try_create(bus, "isa-fdc");
+ if (!dev) {
+ return NULL;
+ }
+
+ if (fds[0]) {
+ qdev_prop_set_drive_nofail(&dev->qdev, "driveA", fds[0]->bdrv);
+ }
+ if (fds[1]) {
+ qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv);
+ }
+ qdev_init_nofail(&dev->qdev);
+
+ return dev;
+}
+
void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
target_phys_addr_t mmio_base, DriveInfo **fds)
{
#ifndef HW_FDC_H
#define HW_FDC_H
-#include "isa.h"
-#include "blockdev.h"
+#include "qemu-common.h"
/* fdc.c */
#define MAX_FD 2
-static inline ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds)
-{
- ISADevice *dev;
-
- dev = isa_try_create(bus, "isa-fdc");
- if (!dev) {
- return NULL;
- }
-
- if (fds[0]) {
- qdev_prop_set_drive_nofail(&dev->qdev, "driveA", fds[0]->bdrv);
- }
- if (fds[1]) {
- qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv);
- }
- qdev_init_nofail(&dev->qdev);
-
- return dev;
-}
-
+ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds);
void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
target_phys_addr_t mmio_base, DriveInfo **fds);
void sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t io_base,
uint8_t saved_address;
};
-static struct BusInfo i2c_bus_info = {
- .name = "I2C",
- .size = sizeof(i2c_bus),
- .props = (Property[]) {
- DEFINE_PROP_UINT8("address", struct I2CSlave, address, 0),
- DEFINE_PROP_END_OF_LIST(),
- }
+static Property i2c_props[] = {
+ DEFINE_PROP_UINT8("address", struct I2CSlave, address, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+#define TYPE_I2C_BUS "i2c-bus"
+#define I2C_BUS(obj) OBJECT_CHECK(i2c_bus, (obj), TYPE_I2C_BUS)
+
+static const TypeInfo i2c_bus_info = {
+ .name = TYPE_I2C_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(i2c_bus),
};
static void i2c_bus_pre_save(void *opaque)
{
i2c_bus *bus;
- bus = FROM_QBUS(i2c_bus, qbus_create(&i2c_bus_info, parent, name));
+ bus = FROM_QBUS(i2c_bus, qbus_create(TYPE_I2C_BUS, parent, name));
vmstate_register(NULL, -1, &vmstate_i2c_bus, bus);
return bus;
}
/* TODO: Make this handle multiple masters. */
int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv)
{
- DeviceState *qdev;
+ BusChild *kid;
I2CSlave *slave = NULL;
I2CSlaveClass *sc;
- QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) {
+ QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
+ DeviceState *qdev = kid->child;
I2CSlave *candidate = I2C_SLAVE_FROM_QDEV(qdev);
if (candidate->address == address) {
slave = candidate;
{
DeviceClass *k = DEVICE_CLASS(klass);
k->init = i2c_slave_qdev_init;
- k->bus_info = &i2c_bus_info;
+ k->bus_type = TYPE_I2C_BUS;
+ k->props = i2c_props;
}
static TypeInfo i2c_slave_type_info = {
static void i2c_slave_register_types(void)
{
+ type_register_static(&i2c_bus_info);
type_register_static(&i2c_slave_type_info);
}
obj-y += pc_piix.o
obj-y += pc_sysfw.o
obj-$(CONFIG_XEN) += xen_platform.o xen_apic.o
-obj-$(CONFIG_KVM) += kvm/clock.o kvm/apic.o kvm/i8259.o kvm/ioapic.o kvm/i8254.o
+obj-y += kvm/
obj-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o
obj-y := $(addprefix ../,$(obj-y))
case HOST_CTL: /* R/W */
if (val & HOST_CTL_RESET) {
DPRINTF(-1, "HBA Reset\n");
- ahci_reset(container_of(s, AHCIPCIState, ahci));
+ ahci_reset(s);
} else {
s->control_regs.ghc = (val & 0x3) | HOST_CTL_AHCI_EN;
ahci_check_irq(s);
g_free(s->dev);
}
-void ahci_reset(void *opaque)
+void ahci_reset(AHCIState *s)
{
- struct AHCIPCIState *d = opaque;
AHCIPortRegs *pr;
int i;
- d->ahci.control_regs.irqstatus = 0;
- d->ahci.control_regs.ghc = 0;
+ s->control_regs.irqstatus = 0;
+ s->control_regs.ghc = 0;
- for (i = 0; i < d->ahci.ports; i++) {
- pr = &d->ahci.dev[i].port_regs;
+ for (i = 0; i < s->ports; i++) {
+ pr = &s->dev[i].port_regs;
pr->irq_stat = 0;
pr->irq_mask = 0;
pr->scr_ctl = 0;
- ahci_reset_port(&d->ahci, i);
+ ahci_reset_port(s, i);
}
}
.unmigratable = 1,
};
+static void sysbus_ahci_reset(DeviceState *dev)
+{
+ SysbusAHCIState *s = DO_UPCAST(SysbusAHCIState, busdev.qdev, dev);
+
+ ahci_reset(&s->ahci);
+}
+
static int sysbus_ahci_init(SysBusDevice *dev)
{
SysbusAHCIState *s = FROM_SYSBUS(SysbusAHCIState, dev);
sysbus_init_mmio(dev, &s->ahci.mem);
sysbus_init_irq(dev, &s->ahci.irq);
-
- qemu_register_reset(ahci_reset, &s->ahci);
return 0;
}
sbc->init = sysbus_ahci_init;
dc->vmsd = &vmstate_sysbus_ahci;
dc->props = sysbus_ahci_properties;
+ dc->reset = sysbus_ahci_reset;
}
static TypeInfo sysbus_ahci_info = {
void ahci_init(AHCIState *s, DeviceState *qdev, int ports);
void ahci_uninit(AHCIState *s);
-void ahci_reset(void *opaque);
+void ahci_reset(AHCIState *s);
#endif /* HW_IDE_AHCI_H */
void ide_exec_cmd(IDEBus *bus, uint32_t val)
{
+ uint16_t *identify_data;
IDEState *s;
int n;
int lba48 = 0;
goto abort_cmd;
/* XXX: valid for CDROM ? */
switch(s->feature) {
- case 0xcc: /* reverting to power-on defaults enable */
- case 0x66: /* reverting to power-on defaults disable */
case 0x02: /* write cache enable */
+ bdrv_set_enable_write_cache(s->bs, true);
+ identify_data = (uint16_t *)s->identify_data;
+ put_le16(identify_data + 85, (1 << 14) | (1 << 5) | 1);
+ s->status = READY_STAT | SEEK_STAT;
+ ide_set_irq(s->bus);
+ break;
case 0x82: /* write cache disable */
+ bdrv_set_enable_write_cache(s->bs, false);
+ identify_data = (uint16_t *)s->identify_data;
+ put_le16(identify_data + 85, (1 << 14) | 1);
+ ide_flush_cache(s);
+ break;
+ case 0xcc: /* reverting to power-on defaults enable */
+ case 0x66: /* reverting to power-on defaults disable */
case 0xaa: /* read look-ahead enable */
case 0x55: /* read look-ahead disable */
case 0x05: /* set advanced power management mode */
break;
case 0x03: { /* set transfer mode */
uint8_t val = s->nsector & 0x07;
- uint16_t *identify_data = (uint16_t *)s->identify_data;
+ identify_data = (uint16_t *)s->identify_data;
switch (s->nsector >> 3) {
case 0x00: /* pio default */
if (version) {
pstrcpy(s->version, sizeof(s->version), version);
} else {
- pstrcpy(s->version, sizeof(s->version), QEMU_VERSION);
+ pstrcpy(s->version, sizeof(s->version), qemu_get_version());
}
ide_reset(s);
s->cdrom_changed = 1;
}
}
+ if (s->identify_set) {
+ bdrv_set_enable_write_cache(s->bs, !!(s->identify_data[85] & (1 << 5)));
+ }
return 0;
}
.unmigratable = 1,
};
+static void pci_ich9_reset(DeviceState *dev)
+{
+ struct AHCIPCIState *d = DO_UPCAST(struct AHCIPCIState, card.qdev, dev);
+
+ ahci_reset(&d->ahci);
+}
+
static int pci_ich9_ahci_init(PCIDevice *dev)
{
struct AHCIPCIState *d;
/* XXX Software should program this register */
d->card.config[0x90] = 1 << 6; /* Address Map Register - AHCI mode */
- qemu_register_reset(ahci_reset, d);
-
msi_init(dev, 0x50, 1, true, false);
d->ahci.irq = d->card.irq[0];
d = DO_UPCAST(struct AHCIPCIState, card, dev);
msi_uninit(dev);
- qemu_unregister_reset(ahci_reset, d);
ahci_uninit(&d->ahci);
return 0;
}
-static void pci_ich9_write_config(PCIDevice *pci, uint32_t addr,
- uint32_t val, int len)
-{
- pci_default_write_config(pci, addr, val, len);
- msi_write_config(pci, addr, val, len);
-}
-
static void ich_ahci_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = pci_ich9_ahci_init;
k->exit = pci_ich9_uninit;
- k->config_write = pci_ich9_write_config;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82801IR;
k->revision = 0x02;
k->class_id = PCI_CLASS_STORAGE_SATA;
dc->vmsd = &vmstate_ahci;
+ dc->reset = pci_ich9_reset;
}
static TypeInfo ich_ahci_info = {
typedef struct IDEDMA IDEDMA;
typedef struct IDEDMAOps IDEDMAOps;
+#define TYPE_IDE_BUS "IDE"
+#define IDE_BUS(obj) OBJECT_CHECK(IDEBus, (obj), TYPE_IDE_BUS)
+
/* Bits of HD_STATUS */
#define ERR_STAT 0x01
#define INDEX_STAT 0x02
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+
#include <hw/hw.h>
#include <hw/pc.h>
#include <hw/pci.h>
#include <hw/isa.h>
-#include "block.h"
+#include "blockdev.h"
#include "sysemu.h"
#include "dma.h"
static char *idebus_get_fw_dev_path(DeviceState *dev);
-static struct BusInfo ide_bus_info = {
- .name = "IDE",
- .size = sizeof(IDEBus),
- .get_fw_dev_path = idebus_get_fw_dev_path,
- .props = (Property[]) {
- DEFINE_PROP_UINT32("unit", IDEDevice, unit, -1),
- DEFINE_PROP_END_OF_LIST(),
- },
+static Property ide_props[] = {
+ DEFINE_PROP_UINT32("unit", IDEDevice, unit, -1),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ide_bus_class_init(ObjectClass *klass, void *data)
+{
+ BusClass *k = BUS_CLASS(klass);
+
+ k->get_fw_dev_path = idebus_get_fw_dev_path;
+}
+
+static const TypeInfo ide_bus_info = {
+ .name = TYPE_IDE_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(IDEBus),
+ .class_init = ide_bus_class_init,
};
void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id)
{
- qbus_create_inplace(&idebus->qbus, &ide_bus_info, dev, NULL);
+ qbus_create_inplace(&idebus->qbus, TYPE_IDE_BUS, dev, NULL);
idebus->bus_id = bus_id;
}
{
DeviceClass *k = DEVICE_CLASS(klass);
k->init = ide_qdev_init;
- k->bus_info = &ide_bus_info;
+ k->bus_type = TYPE_IDE_BUS;
+ k->props = ide_props;
}
static TypeInfo ide_device_type_info = {
static void ide_register_types(void)
{
+ type_register_static(&ide_bus_info);
type_register_static(&ide_hd_info);
type_register_static(&ide_cd_info);
type_register_static(&ide_drive_info);
/* --------------------------------------------------------------------- */
/* hda bus */
-static struct BusInfo hda_codec_bus_info = {
- .name = "HDA",
- .size = sizeof(HDACodecBus),
- .props = (Property[]) {
- DEFINE_PROP_UINT32("cad", HDACodecDevice, cad, -1),
- DEFINE_PROP_END_OF_LIST()
- }
+static Property hda_props[] = {
+ DEFINE_PROP_UINT32("cad", HDACodecDevice, cad, -1),
+ DEFINE_PROP_END_OF_LIST()
+};
+
+static const TypeInfo hda_codec_bus_info = {
+ .name = TYPE_HDA_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(HDACodecBus),
};
void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus,
hda_codec_response_func response,
hda_codec_xfer_func xfer)
{
- qbus_create_inplace(&bus->qbus, &hda_codec_bus_info, dev, NULL);
+ qbus_create_inplace(&bus->qbus, TYPE_HDA_BUS, dev, NULL);
bus->response = response;
bus->xfer = xfer;
}
HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad)
{
- DeviceState *qdev;
+ BusChild *kid;
HDACodecDevice *cdev;
- QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) {
+ QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
+ DeviceState *qdev = kid->child;
cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
if (cdev->cad == cad) {
return cdev;
static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool running, bool output)
{
- DeviceState *qdev;
+ BusChild *kid;
HDACodecDevice *cdev;
- QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
+ QTAILQ_FOREACH(kid, &d->codecs.qbus.children, sibling) {
+ DeviceState *qdev = kid->child;
HDACodecDeviceClass *cdc;
cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
static void intel_hda_reset(DeviceState *dev)
{
+ BusChild *kid;
IntelHDAState *d = DO_UPCAST(IntelHDAState, pci.qdev, dev);
- DeviceState *qdev;
HDACodecDevice *cdev;
intel_hda_regs_reset(d);
d->wall_base_ns = qemu_get_clock_ns(vm_clock);
/* reset codecs */
- QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
+ QTAILQ_FOREACH(kid, &d->codecs.qbus.children, sibling) {
+ DeviceState *qdev = kid->child;
cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
device_reset(DEVICE(cdev));
d->state_sts |= (1 << cdev->cad);
return 0;
}
-static void intel_hda_write_config(PCIDevice *pci, uint32_t addr,
- uint32_t val, int len)
-{
- IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci);
-
- pci_default_write_config(pci, addr, val, len);
- if (d->msi) {
- msi_write_config(pci, addr, val, len);
- }
-}
-
static int intel_hda_post_load(void *opaque, int version)
{
IntelHDAState* d = opaque;
k->init = intel_hda_init;
k->exit = intel_hda_exit;
- k->config_write = intel_hda_write_config;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = 0x2668;
k->revision = 1;
DeviceClass *k = DEVICE_CLASS(klass);
k->init = hda_codec_dev_init;
k->exit = hda_codec_dev_exit;
- k->bus_info = &hda_codec_bus_info;
+ k->bus_type = TYPE_HDA_BUS;
+ k->props = hda_props;
}
static TypeInfo hda_codec_device_type_info = {
static void intel_hda_register_types(void)
{
+ type_register_static(&hda_codec_bus_info);
type_register_static(&intel_hda_info);
type_register_static(&hda_codec_device_type_info);
}
#define HDA_CODEC_DEVICE_GET_CLASS(obj) \
OBJECT_GET_CLASS(HDACodecDeviceClass, (obj), TYPE_HDA_CODEC_DEVICE)
+#define TYPE_HDA_BUS "HDA"
+#define HDA_BUS(obj) OBJECT_CHECK(HDACodecBus, (obj), TYPE_HDA_BUS)
+
typedef struct HDACodecBus HDACodecBus;
typedef struct HDACodecDevice HDACodecDevice;
pci_get_long(d->config + d->exp.aer_cap + PCI_ERR_ROOT_COMMAND);
pci_bridge_write_config(d, address, val, len);
- msi_write_config(d, address, val, len);
ioh3420_aer_vector_update(d);
pcie_cap_slot_write_config(d, address, val, len);
pcie_aer_write_config(d, address, val, len);
static void ioh3420_reset(DeviceState *qdev)
{
PCIDevice *d = PCI_DEVICE(qdev);
- msi_reset(d);
+
ioh3420_aer_vector_update(d);
pcie_cap_root_reset(d);
pcie_cap_deverr_reset(d);
static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent);
static char *isabus_get_fw_dev_path(DeviceState *dev);
-static struct BusInfo isa_bus_info = {
- .name = "ISA",
- .size = sizeof(ISABus),
- .print_dev = isabus_dev_print,
- .get_fw_dev_path = isabus_get_fw_dev_path,
+static void isa_bus_class_init(ObjectClass *klass, void *data)
+{
+ BusClass *k = BUS_CLASS(klass);
+
+ k->print_dev = isabus_dev_print;
+ k->get_fw_dev_path = isabus_get_fw_dev_path;
+}
+
+static const TypeInfo isa_bus_info = {
+ .name = TYPE_ISA_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(ISABus),
+ .class_init = isa_bus_class_init,
};
ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io)
qdev_init_nofail(dev);
}
- isabus = FROM_QBUS(ISABus, qbus_create(&isa_bus_info, dev, NULL));
+ isabus = FROM_QBUS(ISABus, qbus_create(TYPE_ISA_BUS, dev, NULL));
isabus->address_space_io = address_space_io;
return isabus;
}
{
DeviceClass *k = DEVICE_CLASS(klass);
k->init = isa_qdev_init;
- k->bus_info = &isa_bus_info;
+ k->bus_type = TYPE_ISA_BUS;
}
static TypeInfo isa_device_type_info = {
static void isabus_register_types(void)
{
+ type_register_static(&isa_bus_info);
type_register_static(&isabus_bridge_info);
type_register_static(&isa_device_type_info);
}
#define ISA_NUM_IRQS 16
-typedef struct ISADevice ISADevice;
-
#define TYPE_ISA_DEVICE "isa-device"
#define ISA_DEVICE(obj) \
OBJECT_CHECK(ISADevice, (obj), TYPE_ISA_DEVICE)
#define ISA_DEVICE_GET_CLASS(obj) \
OBJECT_GET_CLASS(ISADeviceClass, (obj), TYPE_ISA_DEVICE)
+#define TYPE_ISA_BUS "ISA"
+#define ISA_BUS(obj) OBJECT_CHECK(ISABus, (obj), TYPE_ISA_BUS)
+
typedef struct ISADeviceClass {
DeviceClass parent_class;
int (*init)(ISADevice *dev);
IVShmemState *s = DO_UPCAST(IVShmemState, dev.qdev, d);
s->intrstatus = 0;
- msix_reset(&s->dev);
ivshmem_use_msix(s);
return;
}
--- /dev/null
+obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o
}
if (val & LSI_SCNTL1_RST) {
if (!(s->sstat0 & LSI_SSTAT0_RST)) {
- DeviceState *dev;
+ BusChild *kid;
- QTAILQ_FOREACH(dev, &s->bus.qbus.children, sibling) {
+ QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
+ DeviceState *dev = kid->child;
device_reset(dev);
}
s->sstat0 |= LSI_SSTAT0_RST;
/* NVRAM storage */
uint8_t *buffer;
/* Model parameters */
- uint32_t type; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
+ uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
/* NVRAM storage */
uint16_t addr;
uint8_t lock;
NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, addr, val);
/* check for NVRAM access */
- if ((NVRAM->type == 2 && addr < 0x7f8) ||
- (NVRAM->type == 8 && addr < 0x1ff8) ||
- (NVRAM->type == 59 && addr < 0x1ff0))
+ if ((NVRAM->model == 2 && addr < 0x7f8) ||
+ (NVRAM->model == 8 && addr < 0x1ff8) ||
+ (NVRAM->model == 59 && addr < 0x1ff0)) {
goto do_write;
+ }
/* TOD access */
switch (addr) {
tmp = from_bcd(val);
if (tmp >= 0 && tmp <= 99) {
get_time(NVRAM, &tm);
- if (NVRAM->type == 8)
+ if (NVRAM->model == 8) {
tm.tm_year = from_bcd(val) + 68; // Base year is 1968
- else
+ } else {
tm.tm_year = from_bcd(val);
+ }
set_time(NVRAM, &tm);
}
break;
uint32_t retval = 0xFF;
/* check for NVRAM access */
- if ((NVRAM->type == 2 && addr < 0x078f) ||
- (NVRAM->type == 8 && addr < 0x1ff8) ||
- (NVRAM->type == 59 && addr < 0x1ff0))
+ if ((NVRAM->model == 2 && addr < 0x078f) ||
+ (NVRAM->model == 8 && addr < 0x1ff8) ||
+ (NVRAM->model == 59 && addr < 0x1ff0)) {
goto do_read;
+ }
/* TOD access */
switch (addr) {
case 0x07FF:
/* year */
get_time(NVRAM, &tm);
- if (NVRAM->type == 8)
+ if (NVRAM->model == 8) {
retval = to_bcd(tm.tm_year - 68); // Base year is 1968
- else
+ } else {
retval = to_bcd(tm.tm_year);
+ }
break;
default:
/* Check lock registers state */
/* Initialisation routine */
M48t59State *m48t59_init(qemu_irq IRQ, target_phys_addr_t mem_base,
- uint32_t io_base, uint16_t size, int type)
+ uint32_t io_base, uint16_t size, int model)
{
DeviceState *dev;
SysBusDevice *s;
M48t59State *state;
dev = qdev_create(NULL, "m48t59");
- qdev_prop_set_uint32(dev, "type", type);
+ qdev_prop_set_uint32(dev, "model", model);
qdev_prop_set_uint32(dev, "size", size);
qdev_prop_set_uint32(dev, "io_base", io_base);
qdev_init_nofail(dev);
}
M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
- int type)
+ int model)
{
M48t59ISAState *d;
ISADevice *dev;
M48t59State *s;
dev = isa_create(bus, "m48t59_isa");
- qdev_prop_set_uint32(&dev->qdev, "type", type);
+ qdev_prop_set_uint32(&dev->qdev, "model", model);
qdev_prop_set_uint32(&dev->qdev, "size", size);
qdev_prop_set_uint32(&dev->qdev, "io_base", io_base);
qdev_init_nofail(&dev->qdev);
static void m48t59_init_common(M48t59State *s)
{
s->buffer = g_malloc0(s->size);
- if (s->type == 59) {
+ if (s->model == 59) {
s->alrm_timer = qemu_new_timer_ns(rtc_clock, &alarm_cb, s);
s->wd_timer = qemu_new_timer_ns(vm_clock, &watchdog_cb, s);
}
static Property m48t59_isa_properties[] = {
DEFINE_PROP_UINT32("size", M48t59ISAState, state.size, -1),
- DEFINE_PROP_UINT32("type", M48t59ISAState, state.type, -1),
+ DEFINE_PROP_UINT32("model", M48t59ISAState, state.model, -1),
DEFINE_PROP_HEX32( "io_base", M48t59ISAState, state.io_base, 0),
DEFINE_PROP_END_OF_LIST(),
};
static Property m48t59_properties[] = {
DEFINE_PROP_UINT32("size", M48t59SysBusState, state.size, -1),
- DEFINE_PROP_UINT32("type", M48t59SysBusState, state.type, -1),
+ DEFINE_PROP_UINT32("model", M48t59SysBusState, state.model, -1),
DEFINE_PROP_HEX32( "io_base", M48t59SysBusState, state.io_base, 0),
DEFINE_PROP_END_OF_LIST(),
};
pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci");
smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
- isa_get_irq(NULL, 9), NULL, 0);
+ isa_get_irq(NULL, 9), NULL, 0, NULL);
/* TODO: Populate SPD eeprom data. */
smbus_eeprom_init(smbus, 8, NULL, 0);
pit = pit_init(isa_bus, 0x40, 0, NULL);
uint16_t flags;
uint8_t cap_size;
- if (!(dev->cap_present & QEMU_PCI_CAP_MSI)) {
+ if (!msi_present(dev)) {
return;
}
flags = pci_get_word(dev->config + msi_flags_off(dev));
uint16_t flags;
bool msi64bit;
+ if (!msi_present(dev)) {
+ return;
+ }
+
flags = pci_get_word(dev->config + msi_flags_off(dev));
flags &= ~(PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE);
msi64bit = flags & PCI_MSI_FLAGS_64BIT;
stl_le_phys(address, data);
}
-/* call this function after updating configs by pci_default_write_config(). */
+/* Normally called by pci_default_write_config(). */
void msi_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int len)
{
uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
unsigned int vector;
uint32_t pending;
- if (!ranges_overlap(addr, len, dev->msi_cap, msi_cap_sizeof(flags))) {
+ if (!msi_present(dev) ||
+ !ranges_overlap(addr, len, dev->msi_cap, msi_cap_sizeof(flags))) {
return;
}
int vector;
bool was_masked;
- if (!range_covers_byte(addr, len, enable_pos)) {
+ if (!msix_present(dev) || !range_covers_byte(addr, len, enable_pos)) {
return;
}
/* Clean up resources for the device. */
int msix_uninit(PCIDevice *dev, MemoryRegion *bar)
{
- if (!(dev->cap_present & QEMU_PCI_CAP_MSIX))
+ if (!msix_present(dev)) {
return 0;
+ }
pci_del_capability(dev, PCI_CAP_ID_MSIX, MSIX_CAP_LENGTH);
dev->msix_cap = 0;
msix_free_irq_entries(dev);
{
unsigned n = dev->msix_entries_nr;
- if (!(dev->cap_present & QEMU_PCI_CAP_MSIX)) {
+ if (!msix_present(dev)) {
return;
}
unsigned n = dev->msix_entries_nr;
unsigned int vector;
- if (!(dev->cap_present & QEMU_PCI_CAP_MSIX)) {
+ if (!msix_present(dev)) {
return;
}
void msix_reset(PCIDevice *dev)
{
- if (!(dev->cap_present & QEMU_PCI_CAP_MSIX))
+ if (!msix_present(dev)) {
return;
+ }
msix_free_irq_entries(dev);
dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
void msix_unuse_all_vectors(PCIDevice *dev)
{
- if (!(dev->cap_present & QEMU_PCI_CAP_MSIX))
+ if (!msix_present(dev)) {
return;
+ }
msix_free_irq_entries(dev);
}
stw_raw(w ++, 24); /* u16 len */
strcpy((void *) w, "hw-build"); /* char component[12] */
w += 6;
- strcpy((void *) w, "QEMU " QEMU_VERSION); /* char version[12] */
+ strcpy((void *) w, "QEMU ");
+ pstrcat((void *) w, 12, qemu_get_version()); /* char version[12] */
w += 6;
tag = (model == 810) ? "1.1.10-qemu" : "1.1.6-qemu";
#define OMAP_GPIOSW_OUTPUT 0x0002
# define TCMI_VERBOSE 1
-//# define MEM_VERBOSE 1
# ifdef TCMI_VERBOSE
# define OMAP_8B_REG(paddr) \
# define OMAP_MPUI_REG_MASK 0x000007ff
-# ifdef MEM_VERBOSE
-struct io_fn {
- CPUReadMemoryFunc * const *mem_read;
- CPUWriteMemoryFunc * const *mem_write;
- void *opaque;
- int in;
-};
-
-static uint32_t io_readb(void *opaque, target_phys_addr_t addr)
-{
- struct io_fn *s = opaque;
- uint32_t ret;
-
- s->in ++;
- ret = s->mem_read[0](s->opaque, addr);
- s->in --;
- if (!s->in)
- fprintf(stderr, "%08x ---> %02x\n", (uint32_t) addr, ret);
- return ret;
-}
-static uint32_t io_readh(void *opaque, target_phys_addr_t addr)
-{
- struct io_fn *s = opaque;
- uint32_t ret;
-
- s->in ++;
- ret = s->mem_read[1](s->opaque, addr);
- s->in --;
- if (!s->in)
- fprintf(stderr, "%08x ---> %04x\n", (uint32_t) addr, ret);
- return ret;
-}
-static uint32_t io_readw(void *opaque, target_phys_addr_t addr)
-{
- struct io_fn *s = opaque;
- uint32_t ret;
-
- s->in ++;
- ret = s->mem_read[2](s->opaque, addr);
- s->in --;
- if (!s->in)
- fprintf(stderr, "%08x ---> %08x\n", (uint32_t) addr, ret);
- return ret;
-}
-static void io_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- struct io_fn *s = opaque;
-
- if (!s->in)
- fprintf(stderr, "%08x <--- %02x\n", (uint32_t) addr, value);
- s->in ++;
- s->mem_write[0](s->opaque, addr, value);
- s->in --;
-}
-static void io_writeh(void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- struct io_fn *s = opaque;
-
- if (!s->in)
- fprintf(stderr, "%08x <--- %04x\n", (uint32_t) addr, value);
- s->in ++;
- s->mem_write[1](s->opaque, addr, value);
- s->in --;
-}
-static void io_writew(void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- struct io_fn *s = opaque;
-
- if (!s->in)
- fprintf(stderr, "%08x <--- %08x\n", (uint32_t) addr, value);
- s->in ++;
- s->mem_write[2](s->opaque, addr, value);
- s->in --;
-}
-
-static CPUReadMemoryFunc * const io_readfn[] = { io_readb, io_readh, io_readw, };
-static CPUWriteMemoryFunc * const io_writefn[] = { io_writeb, io_writeh, io_writew, };
-
-inline static int debug_register_io_memory(CPUReadMemoryFunc * const *mem_read,
- CPUWriteMemoryFunc * const *mem_write,
- void *opaque)
-{
- struct io_fn *s = g_malloc(sizeof(struct io_fn));
-
- s->mem_read = mem_read;
- s->mem_write = mem_write;
- s->opaque = opaque;
- s->in = 0;
- return cpu_register_io_memory(io_readfn, io_writefn, s,
- DEVICE_NATIVE_ENDIAN);
-}
-# define cpu_register_io_memory debug_register_io_memory
-# endif
-
#endif /* hw_omap_h */
}
}
-void pc_memory_init(MemoryRegion *system_memory,
+void *pc_memory_init(MemoryRegion *system_memory,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
for (i = 0; i < nb_option_roms; i++) {
rom_add_option(option_rom[i].name, option_rom[i].bootindex);
}
+ return fw_cfg;
}
qemu_irq *pc_allocate_cpu_irq(void)
void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
void pc_cpus_init(const char *cpu_model);
-void pc_memory_init(MemoryRegion *system_memory,
+void *pc_memory_init(MemoryRegion *system_memory,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
qemu_irq sci_irq, qemu_irq smi_irq,
- int kvm_enabled);
+ int kvm_enabled, void *fw_cfg);
void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
/* hpet.c */
#include "apic.h"
#include "pci.h"
#include "pci_ids.h"
+#include "usb.h"
#include "net.h"
#include "boards.h"
#include "ide.h"
MemoryRegion *ram_memory;
MemoryRegion *pci_memory;
MemoryRegion *rom_memory;
+ void *fw_cfg = NULL;
pc_cpus_init(cpu_model);
/* allocate ram and load rom/bios */
if (!xen_enabled()) {
- pc_memory_init(system_memory,
+ fw_cfg = pc_memory_init(system_memory,
kernel_filename, kernel_cmdline, initrd_filename,
below_4g_mem_size, above_4g_mem_size,
pci_enabled ? rom_memory : system_memory, &ram_memory);
/* TODO: Populate SPD eeprom data. */
smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
gsi[9], *smi_irq,
- kvm_enabled());
+ kvm_enabled(), fw_cfg);
smbus_eeprom_init(smbus, 8, NULL, 0);
}
.property = "vapic",\
.value = "off",\
},{\
- .driver = "USB",\
+ .driver = TYPE_USB_DEVICE,\
.property = "full-path",\
.value = "no",\
}
PC_COMPAT_1_0,
{ /* end of list */ }
},
+ .hw_version = "1.0",
};
#define PC_COMPAT_0_15 \
PC_COMPAT_0_15,
{ /* end of list */ }
},
+ .hw_version = "0.15",
};
#define PC_COMPAT_0_14 \
},
{ /* end of list */ }
},
+ .hw_version = "0.14",
};
#define PC_COMPAT_0_13 \
PC_COMPAT_0_14,\
{\
- .driver = "PCI",\
+ .driver = TYPE_PCI_DEVICE,\
.property = "command_serr_enable",\
.value = "off",\
},{\
},
{ /* end of list */ }
},
+ .hw_version = "0.13",
};
#define PC_COMPAT_0_12 \
.value = stringify(0),
},
{ /* end of list */ }
- }
+ },
+ .hw_version = "0.12",
};
#define PC_COMPAT_0_11 \
.property = "vectors",\
.value = stringify(0),\
},{\
- .driver = "PCI",\
+ .driver = TYPE_PCI_DEVICE,\
.property = "rombar",\
.value = stringify(0),\
}
.value = "0.11",
},
{ /* end of list */ }
- }
+ },
+ .hw_version = "0.11",
};
static QEMUMachine pc_machine_v0_10 = {
},
{ /* end of list */ }
},
+ .hw_version = "0.10",
};
static QEMUMachine isapc_machine = {
* THE SOFTWARE.
*/
+#include "blockdev.h"
#include "sysbus.h"
#include "hw.h"
#include "pc.h"
SCSIBus *scsibus;
SCSIDevice *scsidev;
- scsibus = DO_UPCAST(SCSIBus, qbus, QLIST_FIRST(&adapter->child_bus));
- if (!scsibus || strcmp(scsibus->qbus.info->name, "SCSI") != 0) {
- error_report("Device is not a SCSI adapter");
- return -1;
- }
+ scsibus = SCSI_BUS(QLIST_FIRST(&adapter->child_bus));
/*
* drive_init() tries to find a default for dinfo->unit. Doesn't
#include "loader.h"
#include "range.h"
#include "qmp-commands.h"
+#include "msi.h"
+#include "msix.h"
//#define DEBUG_PCI
#ifdef DEBUG_PCI
static char *pcibus_get_fw_dev_path(DeviceState *dev);
static int pcibus_reset(BusState *qbus);
-struct BusInfo pci_bus_info = {
- .name = "PCI",
- .size = sizeof(PCIBus),
- .print_dev = pcibus_dev_print,
- .get_dev_path = pcibus_get_dev_path,
- .get_fw_dev_path = pcibus_get_fw_dev_path,
- .reset = pcibus_reset,
- .props = (Property[]) {
- DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
- DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
- DEFINE_PROP_UINT32("rombar", PCIDevice, rom_bar, 1),
- DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present,
- QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false),
- DEFINE_PROP_BIT("command_serr_enable", PCIDevice, cap_present,
- QEMU_PCI_CAP_SERR_BITNR, true),
- DEFINE_PROP_END_OF_LIST()
- }
+static Property pci_props[] = {
+ DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
+ DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
+ DEFINE_PROP_UINT32("rombar", PCIDevice, rom_bar, 1),
+ DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present,
+ QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false),
+ DEFINE_PROP_BIT("command_serr_enable", PCIDevice, cap_present,
+ QEMU_PCI_CAP_SERR_BITNR, true),
+ DEFINE_PROP_END_OF_LIST()
+};
+
+static void pci_bus_class_init(ObjectClass *klass, void *data)
+{
+ BusClass *k = BUS_CLASS(klass);
+
+ k->print_dev = pcibus_dev_print;
+ k->get_dev_path = pcibus_get_dev_path;
+ k->get_fw_dev_path = pcibus_get_fw_dev_path;
+ k->reset = pcibus_reset;
+}
+
+static const TypeInfo pci_bus_info = {
+ .name = TYPE_PCI_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(PCIBus),
+ .class_init = pci_bus_class_init,
};
static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
}
}
pci_update_mappings(dev);
+
+ msi_reset(dev);
+ msix_reset(dev);
}
/*
MemoryRegion *address_space_io,
uint8_t devfn_min)
{
- qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
+ qbus_create_inplace(&bus->qbus, TYPE_PCI_BUS, parent, name);
assert(PCI_FUNC(devfn_min) == 0);
bus->devfn_min = devfn_min;
bus->address_space_mem = address_space_mem;
PCIBus *bus;
bus = g_malloc0(sizeof(*bus));
- bus->qbus.qdev_allocated = 1;
+ bus->qbus.glib_allocated = true;
pci_bus_new_inplace(bus, parent, name, address_space_mem,
address_space_io, devfn_min);
return bus;
if (range_covers_byte(addr, l, PCI_COMMAND))
pci_update_irq_disabled(d, was_irq_disabled);
+
+ msi_write_config(d, addr, val, l);
+ msix_write_config(d, addr, val, l);
}
/***********************************************************/
k->init = pci_qdev_init;
k->unplug = pci_unplug_device;
k->exit = pci_unregister_device;
- k->bus_info = &pci_bus_info;
+ k->bus_type = TYPE_PCI_BUS;
+ k->props = pci_props;
}
static TypeInfo pci_device_type_info = {
static void pci_register_types(void)
{
+ type_register_static(&pci_bus_info);
type_register_static(&pci_device_type_info);
}
}
/* reset bridge specific configuration registers */
-void pci_bridge_reset_reg(PCIDevice *dev)
+void pci_bridge_reset(DeviceState *qdev)
{
+ PCIDevice *dev = PCI_DEVICE(qdev);
uint8_t *conf = dev->config;
conf[PCI_PRIMARY_BUS] = 0;
pci_set_word(conf + PCI_BRIDGE_CONTROL, 0);
}
-/* default reset function for PCI-to-PCI bridge */
-void pci_bridge_reset(DeviceState *qdev)
-{
- PCIDevice *dev = PCI_DEVICE(qdev);
- pci_bridge_reset_reg(dev);
-}
-
/* default qdev initialization function for PCI-to-PCI bridge */
int pci_bridge_initfn(PCIDevice *dev)
{
br->bus_name = dev->qdev.id;
}
- qbus_create_inplace(&sec_bus->qbus, &pci_bus_info, &dev->qdev,
+ qbus_create_inplace(&sec_bus->qbus, TYPE_PCI_BUS, &dev->qdev,
br->bus_name);
sec_bus->parent_dev = dev;
sec_bus->map_irq = br->map_irq;
{
PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev);
PCIBridgeDev *bridge_dev = DO_UPCAST(PCIBridgeDev, bridge, br);
- int err;
+ int err, ret;
pci_bridge_map_irq(br, NULL, pci_bridge_dev_map_irq_fn);
err = pci_bridge_initfn(dev);
if (err) {
shpc_cleanup(dev, &bridge_dev->bar);
shpc_error:
memory_region_destroy(&bridge_dev->bar);
+ ret = pci_bridge_exitfn(dev);
+ assert(!ret);
bridge_error:
return err;
}
static void qdev_pci_bridge_dev_reset(DeviceState *qdev)
{
PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);
+
pci_bridge_reset(qdev);
- if (msi_present(dev)) {
- msi_reset(dev);
- }
shpc_reset(dev);
}
* Use accessor function in pci.h, pci_bridge.h
*/
-extern struct BusInfo pci_bus_info;
+#define TYPE_PCI_BUS "PCI"
+#define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
struct PCIBus {
BusState qbus;
}
error_printf("name \"%s\"", object_class_get_name(klass));
- if (dc->bus_info) {
- error_printf(", bus %s", dc->bus_info->name);
+ if (dc->bus_type) {
+ error_printf(", bus %s", dc->bus_type);
}
if (qdev_class_has_alias(dc)) {
error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
const char *driver;
Property *prop;
ObjectClass *klass;
- DeviceClass *info;
driver = qemu_opt_get(opts, "driver");
if (driver && !strcmp(driver, "?")) {
if (!klass) {
return 0;
}
- info = DEVICE_CLASS(klass);
-
- for (prop = info->props; prop && prop->name; prop++) {
- /*
- * TODO Properties without a parser are just for dirty hacks.
- * qdev_prop_ptr is the only such PropertyInfo. It's marked
- * for removal. This conditional should be removed along with
- * it.
- */
- if (!prop->info->set) {
- continue; /* no way to set it, don't show */
- }
- error_printf("%s.%s=%s\n", driver, prop->name,
- prop->info->legacy_name ?: prop->info->name);
- }
- if (info->bus_info) {
- for (prop = info->bus_info->props; prop && prop->name; prop++) {
+ do {
+ for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) {
+ /*
+ * TODO Properties without a parser are just for dirty hacks.
+ * qdev_prop_ptr is the only such PropertyInfo. It's marked
+ * for removal. This conditional should be removed along with
+ * it.
+ */
if (!prop->info->set) {
continue; /* no way to set it, don't show */
}
error_printf("%s.%s=%s\n", driver, prop->name,
prop->info->legacy_name ?: prop->info->name);
}
- }
+ klass = object_class_get_parent(klass);
+ } while (klass != object_class_by_name(TYPE_DEVICE));
return 1;
}
static void qbus_list_dev(BusState *bus)
{
- DeviceState *dev;
+ BusChild *kid;
const char *sep = " ";
error_printf("devices at \"%s\":", bus->name);
- QTAILQ_FOREACH(dev, &bus->children, sibling) {
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ DeviceState *dev = kid->child;
error_printf("%s\"%s\"", sep, object_get_typename(OBJECT(dev)));
if (dev->id)
error_printf("/\"%s\"", dev->id);
static DeviceState *qbus_find_dev(BusState *bus, char *elem)
{
- DeviceState *dev;
+ BusChild *kid;
/*
* try to match in order:
* (2) driver name
* (3) driver alias, if present
*/
- QTAILQ_FOREACH(dev, &bus->children, sibling) {
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ DeviceState *dev = kid->child;
if (dev->id && strcmp(dev->id, elem) == 0) {
return dev;
}
}
- QTAILQ_FOREACH(dev, &bus->children, sibling) {
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ DeviceState *dev = kid->child;
if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) {
return dev;
}
}
- QTAILQ_FOREACH(dev, &bus->children, sibling) {
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ DeviceState *dev = kid->child;
DeviceClass *dc = DEVICE_GET_CLASS(dev);
if (qdev_class_has_alias(dc) &&
}
static BusState *qbus_find_recursive(BusState *bus, const char *name,
- const BusInfo *info)
+ const char *bus_typename)
{
- DeviceState *dev;
+ BusChild *kid;
BusState *child, *ret;
int match = 1;
if (name && (strcmp(bus->name, name) != 0)) {
match = 0;
}
- if (info && (bus->info != info)) {
+ if (bus_typename &&
+ (strcmp(object_get_typename(OBJECT(bus)), bus_typename) != 0)) {
match = 0;
}
if (match) {
return bus;
}
- QTAILQ_FOREACH(dev, &bus->children, sibling) {
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ DeviceState *dev = kid->child;
QLIST_FOREACH(child, &dev->child_bus, sibling) {
- ret = qbus_find_recursive(child, name, info);
+ ret = qbus_find_recursive(child, name, bus_typename);
if (ret) {
return ret;
}
if (!bus) {
return NULL;
}
- if (bus->info != k->bus_info) {
+ if (strcmp(object_get_typename(OBJECT(bus)), k->bus_type) != 0) {
qerror_report(QERR_BAD_BUS_FOR_DEVICE,
- driver, bus->info->name);
+ driver, object_get_typename(OBJECT(bus)));
return NULL;
}
} else {
- bus = qbus_find_recursive(sysbus_get_default(), NULL, k->bus_info);
+ bus = qbus_find_recursive(sysbus_get_default(), NULL, k->bus_type);
if (!bus) {
qerror_report(QERR_NO_BUS_FOR_DEVICE,
- driver, k->bus_info->name);
+ driver, k->bus_type);
return NULL;
}
}
/* create device, set properties */
qdev = DEVICE(object_new(driver));
qdev_set_parent_bus(qdev, bus);
- qdev_prop_set_globals(qdev);
id = qemu_opts_id(opts);
if (id) {
static void qbus_print(Monitor *mon, BusState *bus, int indent);
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
- const char *prefix, int indent)
+ int indent)
{
if (!props)
return;
error_free(err);
continue;
}
- qdev_printf("%s-prop: %s = %s\n", prefix, props->name,
+ qdev_printf("%s = %s\n", props->name,
value && *value ? value : "<null>");
g_free(value);
}
}
+static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int indent)
+{
+ BusClass *bc = BUS_GET_CLASS(bus);
+
+ if (bc->print_dev) {
+ bc->print_dev(mon, dev, indent);
+ }
+}
+
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
{
+ ObjectClass *class;
BusState *child;
qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
dev->id ? dev->id : "");
if (dev->num_gpio_out) {
qdev_printf("gpio-out %d\n", dev->num_gpio_out);
}
- qdev_print_props(mon, dev, qdev_get_props(dev), "dev", indent);
- qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
- if (dev->parent_bus->info->print_dev)
- dev->parent_bus->info->print_dev(mon, dev, indent);
+ class = object_get_class(OBJECT(dev));
+ do {
+ qdev_print_props(mon, dev, DEVICE_CLASS(class)->props, indent);
+ class = object_class_get_parent(class);
+ } while (class != object_class_by_name(TYPE_DEVICE));
+ bus_print_dev(dev->parent_bus, mon, dev, indent + 2);
QLIST_FOREACH(child, &dev->child_bus, sibling) {
qbus_print(mon, child, indent);
}
static void qbus_print(Monitor *mon, BusState *bus, int indent)
{
- struct DeviceState *dev;
+ BusChild *kid;
qdev_printf("bus: %s\n", bus->name);
indent += 2;
- qdev_printf("type %s\n", bus->info->name);
- QTAILQ_FOREACH(dev, &bus->children, sibling) {
+ qdev_printf("type %s\n", object_get_typename(OBJECT(bus)));
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ DeviceState *dev = kid->child;
qdev_print(mon, dev, indent);
}
}
static Property *qdev_prop_find(DeviceState *dev, const char *name)
{
+ ObjectClass *class;
Property *prop;
/* device properties */
- prop = qdev_prop_walk(qdev_get_props(dev), name);
- if (prop)
- return prop;
-
- /* bus properties */
- prop = qdev_prop_walk(dev->parent_bus->info->props, name);
- if (prop)
- return prop;
+ class = object_get_class(OBJECT(dev));
+ do {
+ prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
+ if (prop) {
+ return prop;
+ }
+ class = object_class_get_parent(class);
+ } while (class != object_class_by_name(TYPE_DEVICE));
return NULL;
}
-int qdev_prop_exists(DeviceState *dev, const char *name)
-{
- return qdev_prop_find(dev, name) ? true : false;
-}
-
void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
Property *prop, const char *value)
{
*ptr = value;
}
-void qdev_prop_set_defaults(DeviceState *dev, Property *props)
-{
- Object *obj = OBJECT(dev);
- if (!props)
- return;
- for (; props->name; props++) {
- Error *errp = NULL;
- if (props->qtype == QTYPE_NONE) {
- continue;
- }
- if (props->qtype == QTYPE_QBOOL) {
- object_property_set_bool(obj, props->defval, props->name, &errp);
- } else if (props->info->enum_table) {
- object_property_set_str(obj, props->info->enum_table[props->defval],
- props->name, &errp);
- } else if (props->qtype == QTYPE_QINT) {
- object_property_set_int(obj, props->defval, props->name, &errp);
- }
- assert_no_error(errp);
- }
-}
-
static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
static void qdev_prop_register_global(GlobalProperty *prop)
void qdev_prop_set_globals(DeviceState *dev)
{
- GlobalProperty *prop;
-
- QTAILQ_FOREACH(prop, &global_props, next) {
- if (strcmp(object_get_typename(OBJECT(dev)), prop->driver) != 0 &&
- strcmp(qdev_get_bus_info(dev)->name, prop->driver) != 0) {
- continue;
+ ObjectClass *class = object_get_class(OBJECT(dev));
+
+ do {
+ GlobalProperty *prop;
+ QTAILQ_FOREACH(prop, &global_props, next) {
+ if (strcmp(object_class_get_name(class), prop->driver) != 0) {
+ continue;
+ }
+ if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
+ exit(1);
+ }
}
- if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
- exit(1);
- }
- }
+ class = object_class_get_parent(class);
+ } while (class);
}
static int qdev_add_one_global(QemuOpts *opts, void *opaque)
static bool qdev_hot_added = false;
static bool qdev_hot_removed = false;
-/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
-static BusState *main_system_bus;
-static void main_system_bus_create(void);
-
/* Register a new device type. */
const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
{
return dc->vmsd;
}
-BusInfo *qdev_get_bus_info(DeviceState *dev)
-{
- DeviceClass *dc = DEVICE_GET_CLASS(dev);
- return dc->bus_info;
-}
-
-Property *qdev_get_props(DeviceState *dev)
-{
- DeviceClass *dc = DEVICE_GET_CLASS(dev);
- return dc->props;
-}
-
const char *qdev_fw_name(DeviceState *dev)
{
DeviceClass *dc = DEVICE_GET_CLASS(dev);
static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
Error **errp);
-void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
+static void bus_remove_child(BusState *bus, DeviceState *child)
{
- Property *prop;
+ BusChild *kid;
+
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ if (kid->child == child) {
+ char name[32];
+
+ snprintf(name, sizeof(name), "child[%d]", kid->index);
+ QTAILQ_REMOVE(&bus->children, kid, sibling);
+ object_property_del(OBJECT(bus), name, NULL);
+ g_free(kid);
+ return;
+ }
+ }
+}
+
+static void bus_add_child(BusState *bus, DeviceState *child)
+{
+ char name[32];
+ BusChild *kid = g_malloc0(sizeof(*kid));
if (qdev_hotplug) {
assert(bus->allow_hotplug);
}
- dev->parent_bus = bus;
- QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
+ kid->index = bus->max_index++;
+ kid->child = child;
- for (prop = qdev_get_bus_info(dev)->props; prop && prop->name; prop++) {
- qdev_property_add_legacy(dev, prop, NULL);
- qdev_property_add_static(dev, prop, NULL);
- }
- qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
+ QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
+
+ snprintf(name, sizeof(name), "child[%d]", kid->index);
+ object_property_add_link(OBJECT(bus), name,
+ object_get_typename(OBJECT(child)),
+ (Object **)&kid->child,
+ NULL);
+}
+
+void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
+{
+ dev->parent_bus = bus;
+ bus_add_child(bus, dev);
}
/* Create a new device. This only initializes the device state structure
if (!dev) {
if (bus) {
hw_error("Unknown device '%s' for bus '%s'\n", name,
- bus->info->name);
+ object_get_typename(OBJECT(bus)));
} else {
hw_error("Unknown device '%s' for default sysbus\n", name);
}
}
qdev_set_parent_bus(dev, bus);
- qdev_prop_set_globals(dev);
return dev;
}
rc = dc->init(dev);
if (rc < 0) {
+ object_unparent(OBJECT(dev));
qdev_free(dev);
return rc;
}
return 0;
}
-BusState *sysbus_get_default(void)
-{
- if (!main_system_bus) {
- main_system_bus_create();
- }
- return main_system_bus;
-}
-
static int qbus_reset_one(BusState *bus, void *opaque)
{
- if (bus->info->reset) {
- return bus->info->reset(bus);
+ BusClass *bc = BUS_GET_CLASS(bus);
+ if (bc->reset) {
+ return bc->reset(bus);
}
return 0;
}
if (nd->netdev)
qdev_prop_set_netdev(dev, "netdev", nd->netdev);
if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
- qdev_prop_exists(dev, "vectors")) {
+ object_property_find(OBJECT(dev), "vectors", NULL)) {
qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
}
nd->instantiated = 1;
int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
qbus_walkerfn *busfn, void *opaque)
{
- DeviceState *dev;
+ BusChild *kid;
int err;
if (busfn) {
}
}
- QTAILQ_FOREACH(dev, &bus->children, sibling) {
- err = qdev_walk_children(dev, devfn, busfn, opaque);
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ err = qdev_walk_children(kid->child, devfn, busfn, opaque);
if (err < 0) {
return err;
}
DeviceState *qdev_find_recursive(BusState *bus, const char *id)
{
- DeviceState *dev, *ret;
+ BusChild *kid;
+ DeviceState *ret;
BusState *child;
- QTAILQ_FOREACH(dev, &bus->children, sibling) {
- if (dev->id && strcmp(dev->id, id) == 0)
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ DeviceState *dev = kid->child;
+
+ if (dev->id && strcmp(dev->id, id) == 0) {
return dev;
+ }
+
QLIST_FOREACH(child, &dev->child_bus, sibling) {
ret = qdev_find_recursive(child, id);
if (ret) {
return NULL;
}
-void qbus_create_inplace(BusState *bus, BusInfo *info,
- DeviceState *parent, const char *name)
+static void qbus_realize(BusState *bus)
{
+ const char *typename = object_get_typename(OBJECT(bus));
char *buf;
int i,len;
- bus->info = info;
- bus->parent = parent;
-
- if (name) {
+ if (bus->name) {
/* use supplied name */
- bus->name = g_strdup(name);
- } else if (parent && parent->id) {
+ } else if (bus->parent && bus->parent->id) {
/* parent device has id -> use it for bus name */
- len = strlen(parent->id) + 16;
+ len = strlen(bus->parent->id) + 16;
buf = g_malloc(len);
- snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
+ snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
bus->name = buf;
} else {
/* no id -> use lowercase bus type for bus name */
- len = strlen(info->name) + 16;
+ len = strlen(typename) + 16;
buf = g_malloc(len);
- len = snprintf(buf, len, "%s.%d", info->name,
- parent ? parent->num_child_bus : 0);
+ len = snprintf(buf, len, "%s.%d", typename,
+ bus->parent ? bus->parent->num_child_bus : 0);
for (i = 0; i < len; i++)
buf[i] = qemu_tolower(buf[i]);
bus->name = buf;
}
- QTAILQ_INIT(&bus->children);
- if (parent) {
- QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
- parent->num_child_bus++;
- } else if (bus != main_system_bus) {
+ if (bus->parent) {
+ QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
+ bus->parent->num_child_bus++;
+ object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
+ } else if (bus != sysbus_get_default()) {
/* TODO: once all bus devices are qdevified,
only reset handler for main_system_bus should be registered here. */
qemu_register_reset(qbus_reset_all_fn, bus);
}
}
-BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
+void qbus_create_inplace(BusState *bus, const char *typename,
+ DeviceState *parent, const char *name)
{
- BusState *bus;
+ object_initialize(bus, typename);
- bus = g_malloc0(info->size);
- bus->qdev_allocated = 1;
- qbus_create_inplace(bus, info, parent, name);
- return bus;
+ bus->parent = parent;
+ bus->name = name ? g_strdup(name) : NULL;
+ qbus_realize(bus);
}
-static void main_system_bus_create(void)
+BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
{
- /* assign main_system_bus before qbus_create_inplace()
- * in order to make "if (bus != main_system_bus)" work */
- main_system_bus = g_malloc0(system_bus_info.size);
- main_system_bus->qdev_allocated = 1;
- qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
- "main-system-bus");
+ BusState *bus;
+
+ bus = BUS(object_new(typename));
+ bus->qom_allocated = true;
+
+ bus->parent = parent;
+ bus->name = name ? g_strdup(name) : NULL;
+ qbus_realize(bus);
+
+ return bus;
}
void qbus_free(BusState *bus)
{
- DeviceState *dev;
-
- while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
- qdev_free(dev);
- }
- if (bus->parent) {
- QLIST_REMOVE(bus, sibling);
- bus->parent->num_child_bus--;
+ if (bus->qom_allocated) {
+ object_delete(OBJECT(bus));
} else {
- assert(bus != main_system_bus); /* main_system_bus is never freed */
- qemu_unregister_reset(qbus_reset_all_fn, bus);
+ object_finalize(OBJECT(bus));
+ if (bus->glib_allocated) {
+ g_free(bus);
+ }
}
- g_free((void*)bus->name);
- if (bus->qdev_allocated) {
- g_free(bus);
+}
+
+static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
+{
+ BusClass *bc = BUS_GET_CLASS(bus);
+
+ if (bc->get_fw_dev_path) {
+ return bc->get_fw_dev_path(dev);
}
+
+ return NULL;
}
static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
if (dev && dev->parent_bus) {
char *d;
l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
- if (dev->parent_bus->info->get_fw_dev_path) {
- d = dev->parent_bus->info->get_fw_dev_path(dev);
+ d = bus_get_fw_dev_path(dev->parent_bus, dev);
+ if (d) {
l += snprintf(p + l, size - l, "%s", d);
g_free(d);
} else {
return strdup(path);
}
-static char *qdev_get_type(Object *obj, Error **errp)
+char *qdev_get_dev_path(DeviceState *dev)
{
- return g_strdup(object_get_typename(obj));
+ BusClass *bc;
+
+ if (!dev || !dev->parent_bus) {
+ return NULL;
+ }
+
+ bc = BUS_GET_CLASS(dev->parent_bus);
+ if (bc->get_dev_path) {
+ return bc->get_dev_path(dev);
+ }
+
+ return NULL;
}
/**
void qdev_property_add_static(DeviceState *dev, Property *prop,
Error **errp)
{
+ Error *local_err = NULL;
+ Object *obj = OBJECT(dev);
+
/*
* TODO qdev_prop_ptr does not have getters or setters. It must
* go now that it can be replaced with links. The test should be
return;
}
- object_property_add(OBJECT(dev), prop->name, prop->info->name,
+ object_property_add(obj, prop->name, prop->info->name,
prop->info->get, prop->info->set,
prop->info->release,
- prop, errp);
+ prop, &local_err);
+
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ if (prop->qtype == QTYPE_NONE) {
+ return;
+ }
+
+ if (prop->qtype == QTYPE_QBOOL) {
+ object_property_set_bool(obj, prop->defval, prop->name, &local_err);
+ } else if (prop->info->enum_table) {
+ object_property_set_str(obj, prop->info->enum_table[prop->defval],
+ prop->name, &local_err);
+ } else if (prop->qtype == QTYPE_QINT) {
+ object_property_set_int(obj, prop->defval, prop->name, &local_err);
+ }
+ assert_no_error(local_err);
}
static void device_initfn(Object *obj)
{
DeviceState *dev = DEVICE(obj);
+ ObjectClass *class;
Property *prop;
if (qdev_hotplug) {
dev->instance_id_alias = -1;
dev->state = DEV_STATE_CREATED;
- for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
- qdev_property_add_legacy(dev, prop, NULL);
- qdev_property_add_static(dev, prop, NULL);
- }
+ class = object_get_class(OBJECT(dev));
+ do {
+ for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
+ qdev_property_add_legacy(dev, prop, NULL);
+ qdev_property_add_static(dev, prop, NULL);
+ }
+ class = object_class_get_parent(class);
+ } while (class != object_class_by_name(TYPE_DEVICE));
+ qdev_prop_set_globals(dev);
- object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL);
- qdev_prop_set_defaults(dev, qdev_get_props(dev));
+ object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
+ (Object **)&dev->parent_bus, NULL);
}
/* Unlink device from bus and free the structure. */
qemu_opts_del(dev->opts);
}
}
- QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
+ if (dev->parent_bus) {
+ bus_remove_child(dev->parent_bus, dev);
+ }
+}
+
+static void device_class_base_init(ObjectClass *class, void *data)
+{
+ DeviceClass *klass = DEVICE_CLASS(class);
+
+ /* We explicitly look up properties in the superclasses,
+ * so do not propagate them to the subclasses.
+ */
+ klass->props = NULL;
}
void device_reset(DeviceState *dev)
.instance_size = sizeof(DeviceState),
.instance_init = device_initfn,
.instance_finalize = device_finalize,
+ .class_base_init = device_class_base_init,
.abstract = true,
.class_size = sizeof(DeviceClass),
};
+static void qbus_initfn(Object *obj)
+{
+ BusState *bus = BUS(obj);
+
+ QTAILQ_INIT(&bus->children);
+}
+
+static void qbus_finalize(Object *obj)
+{
+ BusState *bus = BUS(obj);
+ BusChild *kid;
+
+ while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
+ DeviceState *dev = kid->child;
+ qdev_free(dev);
+ }
+ if (bus->parent) {
+ QLIST_REMOVE(bus, sibling);
+ bus->parent->num_child_bus--;
+ } else {
+ assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
+ qemu_unregister_reset(qbus_reset_all_fn, bus);
+ }
+ g_free((char *)bus->name);
+}
+
+static const TypeInfo bus_info = {
+ .name = TYPE_BUS,
+ .parent = TYPE_OBJECT,
+ .instance_size = sizeof(BusState),
+ .abstract = true,
+ .class_size = sizeof(BusClass),
+ .instance_init = qbus_initfn,
+ .instance_finalize = qbus_finalize,
+};
+
static void qdev_register_types(void)
{
+ type_register_static(&bus_info);
type_register_static(&device_type_info);
}
typedef struct BusState BusState;
-typedef struct BusInfo BusInfo;
+typedef struct BusClass BusClass;
enum DevState {
DEV_STATE_CREATED = 1,
qdev_initfn init;
qdev_event unplug;
qdev_event exit;
- BusInfo *bus_info;
+ const char *bus_type;
} DeviceClass;
/* This structure should not be accessed directly. We declare it here
qemu_irq *gpio_in;
QLIST_HEAD(, BusState) child_bus;
int num_child_bus;
- QTAILQ_ENTRY(DeviceState) sibling;
int instance_id_alias;
int alias_required_for_version;
};
-typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent);
-typedef char *(*bus_get_dev_path)(DeviceState *dev);
/*
* This callback is used to create Open Firmware device path in accordance with
* OF spec http://forthworks.com/standards/of1275.pdf. Indicidual bus bindings
* can be found here http://playground.sun.com/1275/bindings/.
*/
-typedef char *(*bus_get_fw_dev_path)(DeviceState *dev);
-typedef int (qbus_resetfn)(BusState *bus);
-struct BusInfo {
- const char *name;
- size_t size;
- bus_dev_printfn print_dev;
- bus_get_dev_path get_dev_path;
- bus_get_fw_dev_path get_fw_dev_path;
- qbus_resetfn *reset;
- Property *props;
+#define TYPE_BUS "bus"
+#define BUS(obj) OBJECT_CHECK(BusState, (obj), TYPE_BUS)
+#define BUS_CLASS(klass) OBJECT_CLASS_CHECK(BusClass, (klass), TYPE_BUS)
+#define BUS_GET_CLASS(obj) OBJECT_GET_CLASS(BusClass, (obj), TYPE_BUS)
+
+struct BusClass {
+ ObjectClass parent_class;
+
+ /* FIXME first arg should be BusState */
+ void (*print_dev)(Monitor *mon, DeviceState *dev, int indent);
+ char *(*get_dev_path)(DeviceState *dev);
+ char *(*get_fw_dev_path)(DeviceState *dev);
+ int (*reset)(BusState *bus);
};
+typedef struct BusChild {
+ DeviceState *child;
+ int index;
+ QTAILQ_ENTRY(BusChild) sibling;
+} BusChild;
+
+/**
+ * BusState:
+ * @qom_allocated: Indicates whether the object was allocated by QOM.
+ * @glib_allocated: Indicates whether the object was initialized in-place
+ * yet is expected to be freed with g_free().
+ */
struct BusState {
+ Object obj;
DeviceState *parent;
- BusInfo *info;
const char *name;
int allow_hotplug;
- int qdev_allocated;
- QTAILQ_HEAD(ChildrenHead, DeviceState) children;
+ bool qom_allocated;
+ bool glib_allocated;
+ int max_index;
+ QTAILQ_HEAD(ChildrenHead, BusChild) children;
QLIST_ENTRY(BusState) sibling;
};
typedef int (qbus_walkerfn)(BusState *bus, void *opaque);
typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque);
-void qbus_create_inplace(BusState *bus, BusInfo *info,
+void qbus_create_inplace(BusState *bus, const char *typename,
DeviceState *parent, const char *name);
-BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name);
+BusState *qbus_create(const char *typename, DeviceState *parent, const char *name);
/* Returns > 0 if either devfn or busfn skip walk somewhere in cursion,
* < 0 if either devfn or busfn terminate walk somewhere in cursion,
* 0 otherwise. */
/* Set properties between creation and init. */
void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
-int qdev_prop_exists(DeviceState *dev, const char *name);
int qdev_prop_parse(DeviceState *dev, const char *name, const char *value);
void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value);
void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value);
void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
/* FIXME: Remove opaque pointer properties. */
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
-void qdev_prop_set_defaults(DeviceState *dev, Property *props);
void qdev_prop_register_global_list(GlobalProperty *props);
void qdev_prop_set_globals(DeviceState *dev);
char *qdev_get_fw_dev_path(DeviceState *dev);
-/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
-extern struct BusInfo system_bus_info;
-
/**
* @qdev_property_add_static - add a @Property to a device referencing a
* field in a struct.
const char *qdev_fw_name(DeviceState *dev);
-BusInfo *qdev_get_bus_info(DeviceState *dev);
-
-Property *qdev_get_props(DeviceState *dev);
-
Object *qdev_get_machine(void);
/* FIXME: make this a link<> */
extern int qdev_hotplug;
+char *qdev_get_dev_path(DeviceState *dev);
+
#endif
} else {
avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr,
s->RxBufferSize);
- return (avail == 0 || avail >= 1514);
+ return (avail == 0 || avail >= 1514 || (s->IntrMask & RxOverflow));
}
}
#define VIRTIO_EXT_CODE 0x2603
-struct BusInfo s390_virtio_bus_info = {
- .name = "s390-virtio",
- .size = sizeof(VirtIOS390Bus),
+static const TypeInfo s390_virtio_bus_info = {
+ .name = TYPE_S390_VIRTIO_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(VirtIOS390Bus),
};
static const VirtIOBindings virtio_s390_bindings;
/* Create bus on bridge device */
- _bus = qbus_create(&s390_virtio_bus_info, dev, "s390-virtio");
+ _bus = qbus_create(TYPE_S390_VIRTIO_BUS, dev, "s390-virtio");
bus = DO_UPCAST(VirtIOS390Bus, bus, _bus);
bus->dev_page = *ram_size;
ram_addr_t mem,
int *vq_num)
{
- VirtIOS390Device *_dev;
- DeviceState *dev;
+ BusChild *kid;
int i;
- QTAILQ_FOREACH(dev, &bus->bus.children, sibling) {
- _dev = (VirtIOS390Device *)dev;
+ QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
+ VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
+
for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
- if (!virtio_queue_get_addr(_dev->vdev, i))
+ if (!virtio_queue_get_addr(dev->vdev, i))
break;
- if (virtio_queue_get_addr(_dev->vdev, i) == mem) {
+ if (virtio_queue_get_addr(dev->vdev, i) == mem) {
if (vq_num) {
*vq_num = i;
}
- return _dev;
+ return dev;
}
}
}
/* Find a device by device descriptor location */
VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem)
{
- VirtIOS390Device *_dev;
- DeviceState *dev;
+ BusChild *kid;
- QTAILQ_FOREACH(dev, &bus->bus.children, sibling) {
- _dev = (VirtIOS390Device *)dev;
- if (_dev->dev_offs == mem) {
- return _dev;
+ QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
+ VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
+ if (dev->dev_offs == mem) {
+ return dev;
}
}
DeviceClass *dc = DEVICE_CLASS(klass);
dc->init = s390_virtio_busdev_init;
- dc->bus_info = &s390_virtio_bus_info;
+ dc->bus_type = TYPE_S390_VIRTIO_BUS;
dc->unplug = qdev_simple_unplug_cb;
}
static void s390_virtio_register_types(void)
{
+ type_register_static(&s390_virtio_bus_info);
type_register_static(&virtio_s390_device_info);
type_register_static(&s390_virtio_serial);
type_register_static(&s390_virtio_blk);
#define VIRTIO_S390_DEVICE_GET_CLASS(obj) \
OBJECT_GET_CLASS(VirtIOS390DeviceClass, (obj), TYPE_VIRTIO_S390_DEVICE)
+#define TYPE_S390_VIRTIO_BUS "s390-virtio-bus"
+#define S390_VIRTIO_BUS(obj) \
+ OBJECT_CHECK(VirtIOS390Bus, (obj), TYPE_S390_VIRTIO_BUS)
+
typedef struct VirtIOS390Device VirtIOS390Device;
typedef struct VirtIOS390DeviceClass {
static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
static void scsi_req_dequeue(SCSIRequest *req);
-static struct BusInfo scsi_bus_info = {
- .name = "SCSI",
- .size = sizeof(SCSIBus),
- .get_dev_path = scsibus_get_dev_path,
- .get_fw_dev_path = scsibus_get_fw_dev_path,
- .props = (Property[]) {
- DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0),
- DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1),
- DEFINE_PROP_UINT32("lun", SCSIDevice, lun, -1),
- DEFINE_PROP_END_OF_LIST(),
- },
+static Property scsi_props[] = {
+ DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0),
+ DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1),
+ DEFINE_PROP_UINT32("lun", SCSIDevice, lun, -1),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void scsi_bus_class_init(ObjectClass *klass, void *data)
+{
+ BusClass *k = BUS_CLASS(klass);
+
+ k->get_dev_path = scsibus_get_dev_path;
+ k->get_fw_dev_path = scsibus_get_fw_dev_path;
+}
+
+static const TypeInfo scsi_bus_info = {
+ .name = TYPE_SCSI_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(SCSIBus),
+ .class_init = scsi_bus_class_init,
};
static int next_scsi_bus;
/* Create a scsi bus, and attach devices to it. */
void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info)
{
- qbus_create_inplace(&bus->qbus, &scsi_bus_info, host, NULL);
+ qbus_create_inplace(&bus->qbus, TYPE_SCSI_BUS, host, NULL);
bus->busnr = next_scsi_bus++;
bus->info = info;
bus->qbus.allow_hotplug = 1;
if (bootindex >= 0) {
qdev_prop_set_int32(dev, "bootindex", bootindex);
}
- if (qdev_prop_exists(dev, "removable")) {
+ if (object_property_find(OBJECT(dev), "removable", NULL)) {
qdev_prop_set_bit(dev, "removable", removable);
}
if (qdev_prop_set_drive(dev, "drive", bdrv) < 0) {
static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
{
- DeviceState *qdev;
+ BusChild *kid;
int i, len, n;
int channel, id;
bool found_lun0;
id = r->req.dev->id;
found_lun0 = false;
n = 0;
- QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) {
+ QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) {
+ DeviceState *qdev = kid->child;
SCSIDevice *dev = SCSI_DEVICE(qdev);
if (dev->channel == channel && dev->id == id) {
memset(r->buf, 0, len);
stl_be_p(&r->buf, n);
i = found_lun0 ? 8 : 16;
- QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) {
+ QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) {
+ DeviceState *qdev = kid->child;
SCSIDevice *dev = SCSI_DEVICE(qdev);
if (dev->channel == channel && dev->id == id) {
r->buf[7] = 0x10 | (r->req.bus->info->tcq ? 0x02 : 0); /* Sync, TCQ. */
memcpy(&r->buf[8], "QEMU ", 8);
memcpy(&r->buf[16], "QEMU TARGET ", 16);
- strncpy((char *) &r->buf[32], QEMU_VERSION, 4);
+ pstrcpy((char *) &r->buf[32], 4, qemu_get_version());
}
return true;
}
{
SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev);
DeviceState *hba = dev->parent_bus->parent;
- char *id = NULL;
+ char *id;
char *path;
- if (hba && hba->parent_bus && hba->parent_bus->info->get_dev_path) {
- id = hba->parent_bus->info->get_dev_path(hba);
- }
+ id = qdev_get_dev_path(hba);
if (id) {
path = g_strdup_printf("%s/%d:%d:%d", id, d->channel, d->id, d->lun);
} else {
SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun)
{
- DeviceState *qdev;
+ BusChild *kid;
SCSIDevice *target_dev = NULL;
- QTAILQ_FOREACH_REVERSE(qdev, &bus->qbus.children, ChildrenHead, sibling) {
+ QTAILQ_FOREACH_REVERSE(kid, &bus->qbus.children, ChildrenHead, sibling) {
+ DeviceState *qdev = kid->child;
SCSIDevice *dev = SCSI_DEVICE(qdev);
if (dev->channel == channel && dev->id == id) {
static void scsi_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
- k->bus_info = &scsi_bus_info;
+ k->bus_type = TYPE_SCSI_BUS;
k->init = scsi_qdev_init;
k->unplug = qdev_simple_unplug_cb;
k->exit = scsi_qdev_exit;
+ k->props = scsi_props;
}
static TypeInfo scsi_device_type_info = {
static void scsi_register_types(void)
{
+ type_register_static(&scsi_bus_info);
type_register_static(&scsi_device_type_info);
}
#include "scsi-defs.h"
#include "sysemu.h"
#include "blockdev.h"
-#include "block_int.h"
#include "dma.h"
#ifdef __linux
}
if (!s->version) {
- s->version = g_strdup(QEMU_VERSION);
+ s->version = g_strdup(qemu_get_version());
}
if (bdrv_is_sg(s->qdev.conf.bs)) {
* ones (such as WRITE SAME or EXTENDED COPY, etc.). So, without
* O_DIRECT everything must go through SG_IO.
*/
- if (!(s->qdev.conf.bs->open_flags & BDRV_O_NOCACHE)) {
+ if (bdrv_get_flags(s->qdev.conf.bs) & BDRV_O_NOCACHE) {
break;
}
void *(*load_request)(QEMUFile *f, SCSIRequest *req);
};
+#define TYPE_SCSI_BUS "SCSI"
+#define SCSI_BUS(obj) OBJECT_CHECK(SCSIBus, (obj), TYPE_SCSI_BUS)
+
struct SCSIBus {
BusState qbus;
int busnr;
++devfn) {
PCIDevice *affected_dev = shpc->sec_bus->devices[devfn];
if (affected_dev) {
+ object_unparent(OBJECT(affected_dev));
qdev_free(&affected_dev->qdev);
}
}
static PCIDevice *find_dev(sPAPREnvironment *spapr,
uint64_t buid, uint32_t config_addr)
{
- DeviceState *qdev;
int devfn = (config_addr >> 8) & 0xFF;
sPAPRPHBState *phb;
QLIST_FOREACH(phb, &spapr->phbs, list) {
+ BusChild *kid;
+
if (phb->buid != buid) {
continue;
}
- QTAILQ_FOREACH(qdev, &phb->host_state.bus->qbus.children, sibling) {
- PCIDevice *dev = (PCIDevice *)qdev;
+ QTAILQ_FOREACH(kid, &phb->host_state.bus->qbus.children, sibling) {
+ PCIDevice *dev = (PCIDevice *)kid->child;
if (dev->devfn == devfn) {
return dev;
}
do { } while (0)
#endif
-static struct BusInfo spapr_vio_bus_info = {
- .name = "spapr-vio",
- .size = sizeof(VIOsPAPRBus),
- .props = (Property[]) {
- DEFINE_PROP_UINT32("irq", VIOsPAPRDevice, vio_irq_num, 0), \
- DEFINE_PROP_END_OF_LIST(),
- },
+static Property spapr_vio_props[] = {
+ DEFINE_PROP_UINT32("irq", VIOsPAPRDevice, vio_irq_num, 0), \
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static const TypeInfo spapr_vio_bus_info = {
+ .name = TYPE_SPAPR_VIO_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(VIOsPAPRBus),
};
VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
{
- DeviceState *qdev;
+ BusChild *kid;
VIOsPAPRDevice *dev = NULL;
- QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
- dev = (VIOsPAPRDevice *)qdev;
+ QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
+ dev = (VIOsPAPRDevice *)kid->child;
if (dev->reg == reg) {
return dev;
}
uint32_t nret, target_ulong rets)
{
VIOsPAPRBus *bus = spapr->vio_bus;
- DeviceState *qdev;
+ BusChild *kid;
VIOsPAPRDevice *dev = NULL;
if (nargs != 0) {
return;
}
- QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
- dev = (VIOsPAPRDevice *)qdev;
+ QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
+ dev = (VIOsPAPRDevice *)kid->child;
spapr_vio_quiesce_one(dev);
}
static VIOsPAPRDevice *reg_conflict(VIOsPAPRDevice *dev)
{
VIOsPAPRBus *bus = DO_UPCAST(VIOsPAPRBus, bus, dev->qdev.parent_bus);
- DeviceState *qdev;
+ BusChild *kid;
VIOsPAPRDevice *other;
/*
* using the requested address. We have to open code this because
* the given dev might already be in the list.
*/
- QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
- other = DO_UPCAST(VIOsPAPRDevice, qdev, qdev);
+ QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
+ other = DO_UPCAST(VIOsPAPRDevice, qdev, kid->child);
if (other != dev && other->reg == dev->reg) {
return other;
/* Create bus on bridge device */
- qbus = qbus_create(&spapr_vio_bus_info, dev, "spapr-vio");
+ qbus = qbus_create(TYPE_SPAPR_VIO_BUS, dev, "spapr-vio");
bus = DO_UPCAST(VIOsPAPRBus, bus, qbus);
bus->next_reg = 0x1000;
DeviceClass *k = DEVICE_CLASS(klass);
k->init = spapr_vio_busdev_init;
k->reset = spapr_vio_busdev_reset;
- k->bus_info = &spapr_vio_bus_info;
+ k->bus_type = TYPE_SPAPR_VIO_BUS;
+ k->props = spapr_vio_props;
}
static TypeInfo spapr_vio_type_info = {
static void spapr_vio_register_types(void)
{
+ type_register_static(&spapr_vio_bus_info);
type_register_static(&spapr_vio_bridge_info);
type_register_static(&spapr_vio_type_info);
}
int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt)
{
DeviceState *qdev, **qdevs;
+ BusChild *kid;
int i, num, ret = 0;
/* Count qdevs on the bus list */
num = 0;
- QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
+ QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
num++;
}
/* Copy out into an array of pointers */
qdevs = g_malloc(sizeof(qdev) * num);
num = 0;
- QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
- qdevs[num++] = qdev;
+ QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
+ qdevs[num++] = kid->child;
}
/* Sort the array */
#define VIO_SPAPR_DEVICE_GET_CLASS(obj) \
OBJECT_GET_CLASS(VIOsPAPRDeviceClass, (obj), TYPE_VIO_SPAPR_DEVICE)
+#define TYPE_SPAPR_VIO_BUS "spapr-vio-bus"
+#define SPAPR_VIO_BUS(obj) OBJECT_CHECK(VIOsPAPRBus, (obj), TYPE_SPAPR_VIO_BUS)
+
struct VIOsPAPRDevice;
typedef struct VIOsPAPR_RTCE {
VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
{
VIOsPAPRDevice *sdev, *selected;
- DeviceState *iter;
+ BusChild *kid;
/*
* To avoid the console bouncing around we want one VTY to be
*/
selected = NULL;
- QTAILQ_FOREACH(iter, &bus->bus.children, sibling) {
+ QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
+ DeviceState *iter = kid->child;
+
/* Only look at VTY devices */
if (!object_dynamic_cast(OBJECT(iter), "spapr-vty")) {
continue;
BusState qbus;
};
-static struct BusInfo ssi_bus_info = {
- .name = "SSI",
- .size = sizeof(SSIBus),
+#define TYPE_SSI_BUS "SSI"
+#define SSI_BUS(obj) OBJECT_CHECK(SSIBus, (obj), TYPE_SSI_BUS)
+
+static const TypeInfo ssi_bus_info = {
+ .name = TYPE_SSI_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(SSIBus),
};
static int ssi_slave_init(DeviceState *dev)
SSISlave *s = SSI_SLAVE(dev);
SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s);
SSIBus *bus;
+ BusChild *kid;
bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev));
- if (QTAILQ_FIRST(&bus->qbus.children) != dev
- || QTAILQ_NEXT(dev, sibling) != NULL) {
+ kid = QTAILQ_FIRST(&bus->qbus.children);
+ if (kid->child != dev || QTAILQ_NEXT(kid, sibling) != NULL) {
hw_error("Too many devices on SSI bus");
}
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->init = ssi_slave_init;
- dc->bus_info = &ssi_bus_info;
+ dc->bus_type = TYPE_SSI_BUS;
}
static TypeInfo ssi_slave_info = {
SSIBus *ssi_create_bus(DeviceState *parent, const char *name)
{
BusState *bus;
- bus = qbus_create(&ssi_bus_info, parent, name);
+ bus = qbus_create(TYPE_SSI_BUS, parent, name);
return FROM_QBUS(SSIBus, bus);
}
uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
{
- DeviceState *dev;
+ BusChild *kid;
SSISlave *slave;
SSISlaveClass *ssc;
- dev = QTAILQ_FIRST(&bus->qbus.children);
- if (!dev) {
+
+ kid = QTAILQ_FIRST(&bus->qbus.children);
+ if (!kid) {
return 0;
}
- slave = SSI_SLAVE(dev);
+ slave = SSI_SLAVE(kid->child);
ssc = SSI_SLAVE_GET_CLASS(slave);
return ssc->transfer(slave, val);
}
static void ssi_slave_register_types(void)
{
+ type_register_static(&ssi_bus_info);
type_register_static(&ssi_slave_info);
}
static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
static char *sysbus_get_fw_dev_path(DeviceState *dev);
-struct BusInfo system_bus_info = {
- .name = "System",
- .size = sizeof(BusState),
- .print_dev = sysbus_dev_print,
- .get_fw_dev_path = sysbus_get_fw_dev_path,
+static void system_bus_class_init(ObjectClass *klass, void *data)
+{
+ BusClass *k = BUS_CLASS(klass);
+
+ k->print_dev = sysbus_dev_print;
+ k->get_fw_dev_path = sysbus_get_fw_dev_path;
+}
+
+static const TypeInfo system_bus_info = {
+ .name = TYPE_SYSTEM_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(BusState),
+ .class_init = system_bus_class_init,
};
void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
{
DeviceClass *k = DEVICE_CLASS(klass);
k->init = sysbus_device_init;
- k->bus_info = &system_bus_info;
+ k->bus_type = TYPE_SYSTEM_BUS;
}
static TypeInfo sysbus_device_type_info = {
.class_init = sysbus_device_class_init,
};
+/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
+static BusState *main_system_bus;
+
+static void main_system_bus_create(void)
+{
+ /* assign main_system_bus before qbus_create_inplace()
+ * in order to make "if (bus != sysbus_get_default())" work */
+ main_system_bus = g_malloc0(system_bus_info.instance_size);
+ qbus_create_inplace(main_system_bus, TYPE_SYSTEM_BUS, NULL,
+ "main-system-bus");
+ main_system_bus->glib_allocated = true;
+ object_property_add_child(container_get(qdev_get_machine(),
+ "/unattached"),
+ "sysbus", OBJECT(main_system_bus), NULL);
+}
+
+BusState *sysbus_get_default(void)
+{
+ if (!main_system_bus) {
+ main_system_bus_create();
+ }
+ return main_system_bus;
+}
+
static void sysbus_register_types(void)
{
+ type_register_static(&system_bus_info);
type_register_static(&sysbus_device_type_info);
}
#define QDEV_MAX_PIO 32
#define QDEV_MAX_IRQ 512
+#define TYPE_SYSTEM_BUS "System"
+#define SYSTEM_BUS(obj) OBJECT_CHECK(IDEBus, (obj), TYPE_IDE_BUS)
+
typedef struct SysBusDevice SysBusDevice;
#define TYPE_SYS_BUS_DEVICE "sys-bus-device"
/* usb-bus.c */
+#define TYPE_USB_BUS "usb-bus"
+#define USB_BUS(obj) OBJECT_CHECK(USBBus, (obj), TYPE_USB_BUS)
+
struct USBBus {
BusState qbus;
USBBusOps *ops;
static char *usb_get_fw_dev_path(DeviceState *qdev);
static int usb_qdev_exit(DeviceState *qdev);
-static struct BusInfo usb_bus_info = {
- .name = "USB",
- .size = sizeof(USBBus),
- .print_dev = usb_bus_dev_print,
- .get_dev_path = usb_get_dev_path,
- .get_fw_dev_path = usb_get_fw_dev_path,
- .props = (Property[]) {
- DEFINE_PROP_STRING("port", USBDevice, port_path),
- DEFINE_PROP_BIT("full-path", USBDevice, flags,
- USB_DEV_FLAG_FULL_PATH, true),
- DEFINE_PROP_END_OF_LIST()
- },
+static Property usb_props[] = {
+ DEFINE_PROP_STRING("port", USBDevice, port_path),
+ DEFINE_PROP_BIT("full-path", USBDevice, flags,
+ USB_DEV_FLAG_FULL_PATH, true),
+ DEFINE_PROP_END_OF_LIST()
};
+
+static void usb_bus_class_init(ObjectClass *klass, void *data)
+{
+ BusClass *k = BUS_CLASS(klass);
+
+ k->print_dev = usb_bus_dev_print;
+ k->get_dev_path = usb_get_dev_path;
+ k->get_fw_dev_path = usb_get_fw_dev_path;
+}
+
+static const TypeInfo usb_bus_info = {
+ .name = TYPE_USB_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(USBBus),
+ .class_init = usb_bus_class_init,
+};
+
static int next_usb_bus = 0;
static QTAILQ_HEAD(, USBBus) busses = QTAILQ_HEAD_INITIALIZER(busses);
void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host)
{
- qbus_create_inplace(&bus->qbus, &usb_bus_info, host, NULL);
+ qbus_create_inplace(&bus->qbus, TYPE_USB_BUS, host, NULL);
bus->ops = ops;
bus->busnr = next_usb_bus++;
bus->qbus.allow_hotplug = 1; /* Yes, we can */
DeviceState *hcd = qdev->parent_bus->parent;
char *id = NULL;
- if ((dev->flags & (1 << USB_DEV_FLAG_FULL_PATH)) &&
- hcd && hcd->parent_bus && hcd->parent_bus->info->get_dev_path) {
- id = hcd->parent_bus->info->get_dev_path(hcd);
+ if (dev->flags & (1 << USB_DEV_FLAG_FULL_PATH)) {
+ id = qdev_get_dev_path(hcd);
}
if (id) {
char *ret = g_strdup_printf("%s/%s", id, dev->port->path);
static void usb_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
- k->bus_info = &usb_bus_info;
+ k->bus_type = TYPE_USB_BUS;
k->init = usb_qdev_init;
k->unplug = qdev_simple_unplug_cb;
k->exit = usb_qdev_exit;
+ k->props = usb_props;
}
static TypeInfo usb_device_type_info = {
static void usb_register_types(void)
{
+ type_register_static(&usb_bus_info);
type_register_static(&usb_device_type_info);
}
const USBDesc *desc = usb_device_get_usb_desc(dev);
int index = desc->id.iSerialNumber;
char serial[64];
+ char *path;
int dst;
assert(index != 0 && desc->str[index] != NULL);
dst = snprintf(serial, sizeof(serial), "%s", desc->str[index]);
- if (hcd && hcd->parent_bus && hcd->parent_bus->info->get_dev_path) {
- char *path = hcd->parent_bus->info->get_dev_path(hcd);
+ path = qdev_get_dev_path(hcd);
+ if (path) {
dst += snprintf(serial+dst, sizeof(serial)-dst, "-%s", path);
}
dst += snprintf(serial+dst, sizeof(serial)-dst, "-%s", dev->port->path);
};
static const USBDescStrings desc_strings = {
- [STR_MANUFACTURER] = "QEMU " QEMU_VERSION,
+ [STR_MANUFACTURER] = "QEMU",
[STR_SERIALNUMBER] = "1",
};
};
static const USBDescStrings desc_strings = {
- [STR_MANUFACTURER] = "QEMU " QEMU_VERSION,
+ [STR_MANUFACTURER] = "QEMU",
[STR_PRODUCT_MOUSE] = "QEMU USB Mouse",
[STR_PRODUCT_TABLET] = "QEMU USB Tablet",
[STR_PRODUCT_KEYBOARD] = "QEMU USB Keyboard",
};
static const USBDescStrings desc_strings = {
- [STR_MANUFACTURER] = "QEMU " QEMU_VERSION,
+ [STR_MANUFACTURER] = "QEMU",
[STR_PRODUCT] = "QEMU USB Hub",
[STR_SERIALNUMBER] = "314159",
};
};
static const USBDescStrings desc_strings = {
- [STR_MANUFACTURER] = "QEMU " QEMU_VERSION,
+ [STR_MANUFACTURER] = "QEMU",
[STR_PRODUCT_SERIAL] = "QEMU USB SERIAL",
[STR_PRODUCT_BRAILLE] = "QEMU USB BRAILLE",
[STR_SERIALNUMBER] = "1",
#define CCID_CONTROL_GET_DATA_RATES 0x3
#define CCID_PRODUCT_DESCRIPTION "QEMU USB CCID"
-#define CCID_VENDOR_DESCRIPTION "QEMU " QEMU_VERSION
+#define CCID_VENDOR_DESCRIPTION "QEMU"
#define CCID_INTERFACE_NAME "CCID Interface"
#define CCID_SERIAL_NUMBER_STRING "1"
/*
};
static const USBDescStrings desc_strings = {
- [STR_MANUFACTURER] = "QEMU " QEMU_VERSION,
+ [STR_MANUFACTURER] = "QEMU",
[STR_PRODUCT] = "QEMU USB CCID",
[STR_SERIALNUMBER] = "1",
[STR_INTERFACE] = "CCID Interface",
: &s->pending_answers[s->pending_answers_start % PENDING_ANSWERS_NUM];
}
-static struct BusInfo ccid_bus_info = {
- .name = "ccid-bus",
- .size = sizeof(CCIDBus),
- .props = (Property[]) {
- DEFINE_PROP_UINT32("slot", struct CCIDCardState, slot, 0),
- DEFINE_PROP_END_OF_LIST(),
- }
+static Property ccid_props[] = {
+ DEFINE_PROP_UINT32("slot", struct CCIDCardState, slot, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+#define TYPE_CCID_BUS "ccid-bus"
+#define CCID_BUS(obj) OBJECT_CHECK(CCIDBus, (obj), TYPE_CCID_BUS)
+
+static const TypeInfo ccid_bus_info = {
+ .name = TYPE_CCID_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(CCIDBus),
};
void ccid_card_send_apdu_to_guest(CCIDCardState *card,
usb_desc_create_serial(dev);
usb_desc_init(dev);
- qbus_create_inplace(&s->bus.qbus, &ccid_bus_info, &dev->qdev, NULL);
+ qbus_create_inplace(&s->bus.qbus, TYPE_CCID_BUS, &dev->qdev, NULL);
s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP);
s->bus.qbus.allow_hotplug = 1;
s->card = NULL;
static void ccid_card_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
- k->bus_info = &ccid_bus_info;
+ k->bus_type = TYPE_CCID_BUS;
k->init = ccid_card_init;
k->exit = ccid_card_exit;
+ k->props = ccid_props;
}
static TypeInfo ccid_card_type_info = {
static void ccid_register_types(void)
{
+ type_register_static(&ccid_bus_info);
type_register_static(&ccid_card_type_info);
type_register_static(&ccid_info);
usb_legacy_register(CCID_DEV_NAME, "ccid", NULL);
};
static const USBDescStrings desc_strings = {
- [STR_MANUFACTURER] = "QEMU " QEMU_VERSION,
+ [STR_MANUFACTURER] = "QEMU",
[STR_PRODUCT] = "QEMU USB HARDDRIVE",
[STR_SERIALNUMBER] = "1",
[STR_CONFIG_FULL] = "Full speed config (usb 1.1)",
};
static const USBDescStrings desc_strings = {
- [STR_MANUFACTURER] = "QEMU " QEMU_VERSION,
+ [STR_MANUFACTURER] = "QEMU",
[STR_PRODUCT] = "Wacom PenPartner",
[STR_SERIALNUMBER] = "1",
};
static int usbredir_handle_status(USBRedirDevice *dev,
int status, int actual_len);
-#define VERSION "qemu usb-redir guest " QEMU_VERSION
-
/*
* Logging stuff
*/
{
USBRedirDevice *dev = opaque;
uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
+ char version[32];
+
+ strcpy(version, "qemu usb-redir guest ");
+ pstrcat(version, sizeof(version), qemu_get_version());
usbredir_device_disconnect(dev);
usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
- usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, 0);
+ usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
usbredirparser_do_write(dev->parser);
}
}
{
VirtIOBalloon *dev = to_virtio_balloon(vdev);
struct virtio_balloon_config config;
+ uint32_t oldactual = dev->actual;
memcpy(&config, config_data, 8);
dev->actual = le32_to_cpu(config.actual);
+ if (dev->actual != oldactual) {
+ qemu_balloon_changed(ram_size -
+ (dev->actual << VIRTIO_BALLOON_PFN_SHIFT));
+ }
}
static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f)
VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
virtio_pci_stop_ioeventfd(proxy);
virtio_reset(proxy->vdev);
- msix_reset(&proxy->pci_dev);
proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
}
virtio_set_status(proxy->vdev,
proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
}
-
- msix_write_config(pci_dev, address, val, len);
}
static unsigned virtio_pci_get_features(void *opaque)
{
SCSIDevice *d = virtio_scsi_device_find(s, req->req.tmf->lun);
SCSIRequest *r, *next;
- DeviceState *qdev;
+ BusChild *kid;
int target;
/* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */
case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
target = req->req.tmf->lun[1];
s->resetting++;
- QTAILQ_FOREACH(qdev, &s->bus.qbus.children, sibling) {
- d = DO_UPCAST(SCSIDevice, qdev, qdev);
+ QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
+ d = DO_UPCAST(SCSIDevice, qdev, kid->child);
if (d->channel == 0 && d->id == target) {
qdev_reset_all(&d->qdev);
}
static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
-static struct BusInfo virtser_bus_info = {
- .name = "virtio-serial-bus",
- .size = sizeof(VirtIOSerialBus),
- .print_dev = virtser_bus_dev_print,
- .props = (Property[]) {
- DEFINE_PROP_UINT32("nr", VirtIOSerialPort, id, VIRTIO_CONSOLE_BAD_ID),
- DEFINE_PROP_STRING("name", VirtIOSerialPort, name),
- DEFINE_PROP_END_OF_LIST()
- }
+static Property virtser_props[] = {
+ DEFINE_PROP_UINT32("nr", VirtIOSerialPort, id, VIRTIO_CONSOLE_BAD_ID),
+ DEFINE_PROP_STRING("name", VirtIOSerialPort, name),
+ DEFINE_PROP_END_OF_LIST()
+};
+
+#define TYPE_VIRTIO_SERIAL_BUS "virtio-serial-bus"
+#define VIRTIO_SERIAL_BUS(obj) \
+ OBJECT_CHECK(VirtIOSerialBus, (obj), TYPE_VIRTIO_SERIAL_BUS)
+
+static void virtser_bus_class_init(ObjectClass *klass, void *data)
+{
+ BusClass *k = BUS_CLASS(klass);
+ k->print_dev = virtser_bus_dev_print;
+}
+
+static const TypeInfo virtser_bus_info = {
+ .name = TYPE_VIRTIO_SERIAL_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(VirtIOSerialBus),
+ .class_init = virtser_bus_class_init,
};
static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
/* Spawn a new virtio-serial bus on which the ports will ride as devices */
- qbus_create_inplace(&vser->bus.qbus, &virtser_bus_info, dev, NULL);
+ qbus_create_inplace(&vser->bus.qbus, TYPE_VIRTIO_SERIAL_BUS, dev, NULL);
vser->bus.qbus.allow_hotplug = 1;
vser->bus.vser = vser;
QTAILQ_INIT(&vser->ports);
{
DeviceClass *k = DEVICE_CLASS(klass);
k->init = virtser_port_qdev_init;
- k->bus_info = &virtser_bus_info;
+ k->bus_type = TYPE_VIRTIO_SERIAL_BUS;
k->exit = virtser_port_qdev_exit;
k->unplug = qdev_simple_unplug_cb;
+ k->props = virtser_props;
}
static TypeInfo virtio_serial_port_type_info = {
static void virtio_serial_register_types(void)
{
+ type_register_static(&virtser_bus_info);
type_register_static(&virtio_serial_port_type_info);
}
pm_update_sci(s);
break;
case 0x04:
- acpi_pm1_cnt_write(&s->ar, val);
+ acpi_pm1_cnt_write(&s->ar, val, 0);
break;
default:
break;
#include "xen_backend.h"
#include "blockdev.h"
-#include "block_int.h" /* XXX */
/* ------------------------------------------------------------- */
int xen_config_dev_blk(DriveInfo *disk)
{
- char fe[256], be[256];
+ char fe[256], be[256], device_name[32];
int vdev = 202 * 256 + 16 * disk->unit;
int cdrom = disk->media_cd;
const char *devtype = cdrom ? "cdrom" : "disk";
const char *mode = cdrom ? "r" : "w";
+ const char *filename = qemu_opt_get(disk->opts, "file");
- snprintf(disk->bdrv->device_name, sizeof(disk->bdrv->device_name),
- "xvd%c", 'a' + disk->unit);
+ snprintf(device_name, sizeof(device_name), "xvd%c", 'a' + disk->unit);
xen_be_printf(NULL, 1, "config disk %d [%s]: %s\n",
- disk->unit, disk->bdrv->device_name, disk->bdrv->filename);
+ disk->unit, device_name, filename);
xen_config_dev_dirs("vbd", "qdisk", vdev, fe, be, sizeof(fe));
/* frontend */
xenstore_write_str(fe, "device-type", devtype);
/* backend */
- xenstore_write_str(be, "dev", disk->bdrv->device_name);
+ xenstore_write_str(be, "dev", device_name);
xenstore_write_str(be, "type", "file");
- xenstore_write_str(be, "params", disk->bdrv->filename);
+ xenstore_write_str(be, "params", filename);
xenstore_write_str(be, "mode", mode);
/* common stuff */
#include <xen/io/xenbus.h>
#include "hw.h"
-#include "block_int.h"
#include "qemu-char.h"
#include "xen_blkif.h"
#include "xen_backend.h"
if (blkdev->file_size < 0) {
xen_be_printf(&blkdev->xendev, 1, "bdrv_getlength: %d (%s) | drv %s\n",
(int)blkdev->file_size, strerror(-blkdev->file_size),
- blkdev->bs->drv ? blkdev->bs->drv->format_name : "-");
+ bdrv_get_format_name(blkdev->bs) ?: "-");
blkdev->file_size = 0;
}
*/
#include "sysbus.h"
-#include "qemu-timer.h"
#include "ptimer.h"
#define D(x)
count = xt->regs[R_TLR];
else
count = ~0 - xt->regs[R_TLR];
- ptimer_set_count(xt->ptimer, count);
+ ptimer_set_limit(xt->ptimer, count, 1);
ptimer_run(xt->ptimer, 1);
}
pci_bridge_write_config(d, address, val, len);
pcie_cap_flr_write_config(d, address, val, len);
pcie_cap_slot_write_config(d, address, val, len);
- msi_write_config(d, address, val, len);
pcie_aer_write_config(d, address, val, len);
}
static void xio3130_downstream_reset(DeviceState *qdev)
{
PCIDevice *d = PCI_DEVICE(qdev);
- msi_reset(d);
+
pcie_cap_deverr_reset(d);
pcie_cap_slot_reset(d);
pcie_cap_ari_reset(d);
{
pci_bridge_write_config(d, address, val, len);
pcie_cap_flr_write_config(d, address, val, len);
- msi_write_config(d, address, val, len);
pcie_aer_write_config(d, address, val, len);
}
static void xio3130_upstream_reset(DeviceState *qdev)
{
PCIDevice *d = PCI_DEVICE(qdev);
- msi_reset(d);
+
pci_bridge_reset(qdev);
pcie_cap_deverr_reset(d);
}
#include "pc.h"
#include "sysbus.h"
#include "flash.h"
+#include "blockdev.h"
#include "xtensa_bootparam.h"
typedef struct LxBoardDesc {
typedef struct InterfaceClass InterfaceClass;
typedef struct InterfaceInfo InterfaceInfo;
-#define TYPE_OBJECT NULL
+#define TYPE_OBJECT "object"
/**
* SECTION:object.h
* has occurred to allow a class to set its default virtual method pointers.
* This is also the function to use to override virtual methods from a parent
* class.
+ * @class_base_init: This function is called for all base classes after all
+ * parent class initialization has occurred, but before the class itself
+ * is initialized. This is the function to use to undo the effects of
+ * memcpy from the parent class to the descendents.
* @class_finalize: This function is called during class destruction and is
* meant to release and dynamic parameters allocated by @class_init.
- * @class_data: Data to pass to the @class_init and @class_finalize functions.
- * This can be useful when building dynamic classes.
+ * @class_data: Data to pass to the @class_init, @class_base_init and
+ * @class_finalize functions. This can be useful when building dynamic
+ * classes.
* @interfaces: The list of interfaces associated with this type. This
* should point to a static array that's terminated with a zero filled
* element.
size_t class_size;
void (*class_init)(ObjectClass *klass, void *data);
+ void (*class_base_init)(ObjectClass *klass, void *data);
void (*class_finalize)(ObjectClass *klass, void *data);
void *class_data;
*/
Type type_register_static(const TypeInfo *info);
-#define type_register_static_alias(info, name) do { } while (0)
-
/**
* type_register:
* @info: The #TypeInfo of the new type
ObjectClass *object_class_dynamic_cast(ObjectClass *klass,
const char *typename);
+/**
+ * object_class_get_parent:
+ * @klass: The class to obtain the parent for.
+ *
+ * Returns: The parent for @klass or %NULL if none.
+ */
+ObjectClass *object_class_get_parent(ObjectClass *klass);
+
/**
* object_class_get_name:
* @klass: The class to obtain the QOM typename for.
void object_property_del(Object *obj, const char *name, struct Error **errp);
+/**
+ * object_property_find:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Look up a property for an object and return its #ObjectProperty if found.
+ */
+ObjectProperty *object_property_find(Object *obj, const char *name,
+ struct Error **errp);
+
void object_unparent(Object *obj);
/**
void (*set)(Object *, const char *, struct Error **),
struct Error **errp);
+/**
+ * object_child_foreach:
+ * @obj: the object whose children will be navigated
+ * @fn: the iterator function to be called
+ * @opaque: an opaque value that will be passed to the iterator
+ *
+ * Call @fn passing each child of @obj and @opaque to it, until @fn returns
+ * non-zero.
+ *
+ * Returns: The last value returned by @fn, or 0 if there is no child.
+ */
+int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
+ void *opaque);
+
/**
* container_get:
* @root: root of the #path, e.g., object_get_root()
--- /dev/null
+/*
+ * Ratelimiting calculations
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_RATELIMIT_H
+#define QEMU_RATELIMIT_H 1
+
+typedef struct {
+ int64_t next_slice_time;
+ uint64_t slice_quota;
+ uint64_t slice_ns;
+ uint64_t dispatched;
+} RateLimit;
+
+static inline int64_t ratelimit_calculate_delay(RateLimit *limit, uint64_t n)
+{
+ int64_t now = qemu_get_clock_ns(rt_clock);
+
+ if (limit->next_slice_time < now) {
+ limit->next_slice_time = now + limit->slice_ns;
+ limit->dispatched = 0;
+ }
+ if (limit->dispatched == 0 || limit->dispatched + n <= limit->slice_quota) {
+ limit->dispatched += n;
+ return 0;
+ } else {
+ limit->dispatched = n;
+ return limit->next_slice_time - now;
+ }
+}
+
+static inline void ratelimit_set_speed(RateLimit *limit, uint64_t speed,
+ uint64_t slice_ns)
+{
+ limit->slice_ns = slice_ns;
+ limit->slice_quota = ((double)speed * 1000000000ULL) / slice_ns;
+}
+
+#endif
#include "qemu-common.h"
#include "qemu-barrier.h"
+#include "qemu-option.h"
+#include "qemu-config.h"
#include "sysemu.h"
#include "hw/hw.h"
#include "hw/msi.h"
libcacard.lib-y=$(patsubst %.o,%.lo,$(libcacard-y))
clean:
- rm -f *.o */*.o *.d */*.d *.a */*.a *~ */*~ vscclient *.lo .libs/* *.la *.pc
- rm -Rf .libs
+ rm -f *.o */*.o *.d */*.d *.a */*.a *~ */*~ vscclient *.lo */*.lo .libs/* */.libs/* *.la */*.la *.pc
+ rm -Rf .libs */.libs
all: libcacard.la libcacard.pc
# Dummy command so that make thinks it has done something
libcacard_srcpath=$(SRC_PATH)/libcacard
libcacard.pc: $(libcacard_srcpath)/libcacard.pc.in
- sed -e 's|@LIBDIR@|$(libdir)|' \
+ $(call quiet-command,sed -e 's|@LIBDIR@|$(libdir)|' \
-e 's|@INCLUDEDIR@|$(libcacard_includedir)|' \
-e 's|@VERSION@|$(shell cat $(SRC_PATH)/VERSION)|' \
-e 's|@PREFIX@|$(prefix)|' \
- < $(libcacard_srcpath)/libcacard.pc.in > libcacard.pc
+ < $(libcacard_srcpath)/libcacard.pc.in > libcacard.pc,\
+ " GEN $@")
.PHONY: install-libcacard
fprintf(stderr, fmt , ## __VA_ARGS__); \
cpu_dump_state(env, stderr, fprintf, 0); \
qemu_log(fmt, ## __VA_ARGS__); \
- if (logfile) \
+ if (qemu_log_enabled()) { \
log_cpu_state(env, 0); \
+ } \
} while (0)
static int do_store_exclusive(CPUPPCState *env)
sigsegv:
unlock_user_struct(frame, frame_addr, 1);
- if (logfile)
- fprintf (logfile, "segfaulting from setup_frame\n");
+ qemu_log("segfaulting from setup_frame\n");
force_sig(TARGET_SIGSEGV);
}
sigsegv:
unlock_user_struct(rt_sf, rt_sf_addr, 1);
- if (logfile)
- fprintf (logfile, "segfaulting from setup_rt_frame\n");
+ qemu_log("segfaulting from setup_rt_frame\n");
force_sig(TARGET_SIGSEGV);
}
sigsegv:
unlock_user_struct(sr, sr_addr, 1);
unlock_user_struct(sc, sc_addr, 1);
- if (logfile)
- fprintf (logfile, "segfaulting from do_sigreturn\n");
+ qemu_log("segfaulting from do_sigreturn\n");
force_sig(TARGET_SIGSEGV);
return 0;
}
sigsegv:
unlock_user_struct(rt_sf, rt_sf_addr, 1);
- if (logfile)
- fprintf (logfile, "segfaulting from do_rt_sigreturn\n");
+ qemu_log("segfaulting from do_rt_sigreturn\n");
force_sig(TARGET_SIGSEGV);
return 0;
}
* Authors:
* Wen Congyang <wency@cn.fujitsu.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
*
*/
* Authors:
* Wen Congyang <wency@cn.fujitsu.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
*
*/
* Authors:
* Wen Congyang <wency@cn.fujitsu.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
*
*/
#include "memory.h"
#include "qmp-commands.h"
#include "hmp.h"
+#include "qemu-thread.h"
/* for pic/irq_info */
#if defined(TARGET_SPARC)
int command_mode;
} MonitorControl;
+/*
+ * To prevent flooding clients, events can be throttled. The
+ * throttling is calculated globally, rather than per-Monitor
+ * instance.
+ */
+typedef struct MonitorEventState {
+ MonitorEvent event; /* Event being tracked */
+ int64_t rate; /* Period over which to throttle. 0 to disable */
+ int64_t last; /* Time at which event was last emitted */
+ QEMUTimer *timer; /* Timer for handling delayed events */
+ QObject *data; /* Event pending delayed dispatch */
+} MonitorEventState;
+
struct Monitor {
CharDriverState *chr;
int mux_out;
[QEVENT_DEVICE_TRAY_MOVED] = "DEVICE_TRAY_MOVED",
[QEVENT_SUSPEND] = "SUSPEND",
[QEVENT_WAKEUP] = "WAKEUP",
+ [QEVENT_BALLOON_CHANGE] = "BALLOON_CHANGE",
};
QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX)
+MonitorEventState monitor_event_state[QEVENT_MAX];
+QemuMutex monitor_event_state_lock;
+
+/*
+ * Emits the event to every monitor instance
+ */
+static void
+monitor_protocol_event_emit(MonitorEvent event,
+ QObject *data)
+{
+ Monitor *mon;
+
+ trace_monitor_protocol_event_emit(event, data);
+ QLIST_FOREACH(mon, &mon_list, entry) {
+ if (monitor_ctrl_mode(mon) && qmp_cmd_mode(mon)) {
+ monitor_json_emitter(mon, data);
+ }
+ }
+}
+
+
+/*
+ * Queue a new event for emission to Monitor instances,
+ * applying any rate limiting if required.
+ */
+static void
+monitor_protocol_event_queue(MonitorEvent event,
+ QObject *data)
+{
+ MonitorEventState *evstate;
+ int64_t now = qemu_get_clock_ns(rt_clock);
+ assert(event < QEVENT_MAX);
+
+ qemu_mutex_lock(&monitor_event_state_lock);
+ evstate = &(monitor_event_state[event]);
+ trace_monitor_protocol_event_queue(event,
+ data,
+ evstate->rate,
+ evstate->last,
+ now);
+
+ /* Rate limit of 0 indicates no throttling */
+ if (!evstate->rate) {
+ monitor_protocol_event_emit(event, data);
+ evstate->last = now;
+ } else {
+ int64_t delta = now - evstate->last;
+ if (evstate->data ||
+ delta < evstate->rate) {
+ /* If there's an existing event pending, replace
+ * it with the new event, otherwise schedule a
+ * timer for delayed emission
+ */
+ if (evstate->data) {
+ qobject_decref(evstate->data);
+ } else {
+ int64_t then = evstate->last + evstate->rate;
+ qemu_mod_timer_ns(evstate->timer, then);
+ }
+ evstate->data = data;
+ qobject_incref(evstate->data);
+ } else {
+ monitor_protocol_event_emit(event, data);
+ evstate->last = now;
+ }
+ }
+ qemu_mutex_unlock(&monitor_event_state_lock);
+}
+
+
+/*
+ * The callback invoked by QemuTimer when a delayed
+ * event is ready to be emitted
+ */
+static void monitor_protocol_event_handler(void *opaque)
+{
+ MonitorEventState *evstate = opaque;
+ int64_t now = qemu_get_clock_ns(rt_clock);
+
+ qemu_mutex_lock(&monitor_event_state_lock);
+
+ trace_monitor_protocol_event_handler(evstate->event,
+ evstate->data,
+ evstate->last,
+ now);
+ if (evstate->data) {
+ monitor_protocol_event_emit(evstate->event, evstate->data);
+ qobject_decref(evstate->data);
+ evstate->data = NULL;
+ }
+ evstate->last = now;
+ qemu_mutex_unlock(&monitor_event_state_lock);
+}
+
+
+/*
+ * @event: the event ID to be limited
+ * @rate: the rate limit in milliseconds
+ *
+ * Sets a rate limit on a particular event, so no
+ * more than 1 event will be emitted within @rate
+ * milliseconds
+ */
+static void
+monitor_protocol_event_throttle(MonitorEvent event,
+ int64_t rate)
+{
+ MonitorEventState *evstate;
+ assert(event < QEVENT_MAX);
+
+ evstate = &(monitor_event_state[event]);
+
+ trace_monitor_protocol_event_throttle(event, rate);
+ evstate->event = event;
+ evstate->rate = rate * SCALE_MS;
+ evstate->timer = qemu_new_timer(rt_clock,
+ SCALE_MS,
+ monitor_protocol_event_handler,
+ evstate);
+ evstate->last = 0;
+ evstate->data = NULL;
+}
+
+
+/* Global, one-time initializer to configure the rate limiting
+ * and initialize state */
+static void monitor_protocol_event_init(void)
+{
+ qemu_mutex_init(&monitor_event_state_lock);
+ /* Limit RTC & BALLOON events to 1 per second */
+ monitor_protocol_event_throttle(QEVENT_RTC_CHANGE, 1000);
+ monitor_protocol_event_throttle(QEVENT_BALLOON_CHANGE, 1000);
+ monitor_protocol_event_throttle(QEVENT_WATCHDOG, 1000);
+}
+
/**
* monitor_protocol_event(): Generate a Monitor event
*
{
QDict *qmp;
const char *event_name;
- Monitor *mon;
assert(event < QEVENT_MAX);
qdict_put_obj(qmp, "data", data);
}
- QLIST_FOREACH(mon, &mon_list, entry) {
- if (monitor_ctrl_mode(mon) && qmp_cmd_mode(mon)) {
- monitor_json_emitter(mon, QOBJECT(qmp));
- }
- }
+ trace_monitor_protocol_event(event, event_name, qmp);
+ monitor_protocol_event_queue(event, QOBJECT(qmp));
QDECREF(qmp);
}
if (is_first_init) {
key_timer = qemu_new_timer_ns(vm_clock, release_keys, NULL);
+ monitor_protocol_event_init();
is_first_init = 0;
}
QEVENT_DEVICE_TRAY_MOVED,
QEVENT_SUSPEND,
QEVENT_WAKEUP,
+ QEVENT_BALLOON_CHANGE,
/* Add to 'monitor_event_names' array in monitor.c when
* defining new events here */
#include <net/if.h>
#include "net.h"
+#include "monitor.h"
#include "sysemu.h"
#include "qemu-char.h"
#include "qemu-common.h"
static BOOL WINAPI qemu_ctrl_handler(DWORD type)
{
- exit(STATUS_CONTROL_C_EXIT);
+ qemu_system_shutdown_request();
+ /* Windows 7 kills application when the function returns.
+ Sleep here to give QEMU a try for closing.
+ Sleep period is 10000ms because Windows kills the program
+ after 10 seconds anyway. */
+ Sleep(10000);
+
return TRUE;
}
#include "trace.h"
#include "qemu_socket.h"
+static const char *qemu_version = QEMU_VERSION;
+
int socket_set_cork(int fd, int v)
{
#if defined(SOL_TCP) && defined(TCP_CORK)
return total;
}
+void qemu_set_version(const char *version)
+{
+ qemu_version = version;
+}
+
+const char *qemu_get_version(void)
+{
+ return qemu_version;
+}
void qemu_set_cloexec(int fd);
+void qemu_set_version(const char *);
+const char *qemu_get_version(void);
+
#endif
#include "qemu-common.h"
#include "error.h"
-
-/* FIXME this is temporary until we remove middle mode */
-#include "monitor.h"
+#include "qerror.h"
#endif
typedef struct VLANClientState VLANClientState;
typedef struct i2c_bus i2c_bus;
typedef struct ISABus ISABus;
+typedef struct ISADevice ISADevice;
typedef struct SMBusDevice SMBusDevice;
typedef struct PCIHostState PCIHostState;
typedef struct PCIExpressHost PCIExpressHost;
ETEXI
DEF("check", img_check,
- "check [-f fmt] filename")
+ "check [-f fmt] [-r [leaks | all]] filename")
STEXI
-@item check [-f @var{fmt}] @var{filename}
+@item check [-f @var{fmt}] [-r [leaks | all]] @var{filename}
ETEXI
DEF("create", img_create,
" '-S' indicates the consecutive number of bytes that must contain only zeros\n"
" for qemu-img to create a sparse image during conversion\n"
"\n"
+ "Parameters to check subcommand:\n"
+ " '-r' tries to repair any inconsistencies that are found during the check.\n"
+ " '-r leaks' repairs only cluster leaks, whereas '-r all' fixes all\n"
+ " kinds of errors, with a higher risk of choosing the wrong fix or\n"
+ " hiding corruption that has already occured.\n"
+ "\n"
"Parameters to snapshot subcommand:\n"
" 'snapshot' is the name of the snapshot to create, apply or delete\n"
" '-a' applies a snapshot (revert disk to saved state)\n"
const char *filename, *fmt;
BlockDriverState *bs;
BdrvCheckResult result;
+ int fix = 0;
+ int flags = BDRV_O_FLAGS;
fmt = NULL;
for(;;) {
- c = getopt(argc, argv, "f:h");
+ c = getopt(argc, argv, "f:hr:");
if (c == -1) {
break;
}
case 'f':
fmt = optarg;
break;
+ case 'r':
+ flags |= BDRV_O_RDWR;
+
+ if (!strcmp(optarg, "leaks")) {
+ fix = BDRV_FIX_LEAKS;
+ } else if (!strcmp(optarg, "all")) {
+ fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;
+ } else {
+ help();
+ }
+ break;
}
}
if (optind >= argc) {
}
filename = argv[optind++];
- bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
+ bs = bdrv_new_open(filename, fmt, flags);
if (!bs) {
return 1;
}
- ret = bdrv_check(bs, &result);
+ ret = bdrv_check(bs, &result, fix);
if (ret == -ENOTSUP) {
error_report("This image format does not support checks");
return 1;
}
+ if (result.corruptions_fixed || result.leaks_fixed) {
+ printf("The following inconsistencies were found and repaired:\n\n"
+ " %d leaked clusters\n"
+ " %d corruptions\n\n"
+ "Double checking the fixed image now...\n",
+ result.leaks_fixed,
+ result.corruptions_fixed);
+ ret = bdrv_check(bs, &result, 0);
+ }
+
if (!(result.corruptions || result.leaks || result.check_errors)) {
printf("No errors were found on the image.\n");
} else {
int c;
const char *filename, *fmt;
BlockDriverState *bs;
- char fmt_name[128], size_buf[128], dsize_buf[128];
+ char size_buf[128], dsize_buf[128];
uint64_t total_sectors;
int64_t allocated_size;
char backing_filename[1024];
if (!bs) {
return 1;
}
- bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
bdrv_get_geometry(bs, &total_sectors);
get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
allocated_size = bdrv_get_allocated_file_size(bs);
"file format: %s\n"
"virtual size: %s (%" PRId64 " bytes)\n"
"disk size: %s\n",
- filename, fmt_name, size_buf,
+ filename, bdrv_get_format_name(bs), size_buf,
(total_sectors * 512),
dsize_buf);
if (bdrv_is_encrypted(bs)) {
Command description:
@table @option
-@item check [-f @var{fmt}] @var{filename}
+@item check [-f @var{fmt}] [-r [leaks | all]] @var{filename}
Perform a consistency check on the disk image @var{filename}.
+If @code{-r} is specified, qemu-img tries to repair any inconsistencies found
+during the check. @code{-r leaks} repairs only cluster leaks, whereas
+@code{-r all} fixes all kinds of errors, with a higher risk of choosing the
+wrong fix or hiding corruption that has already occured.
+
Only the formats @code{qcow2}, @code{qed} and @code{vdi} support
consistency checks.
@end table
+@item qed
+Image format with support for backing files and compact image files (when your
+filesystem or transport medium does not support holes). Good performance due
+to less metadata than the more featureful qcow2 format, especially with
+cache=writethrough or cache=directsync. Consider using qcow2 which will soon
+have a similar optimization and is most actively developed.
+
+Supported options:
+@table @code
+@item backing_file
+File name of a base image (see @option{create} subcommand).
+@item backing_fmt
+Image file format of backing file (optional). Useful if the format cannot be
+autodetected because it has no header, like some vhd/vpc files.
+@item cluster_size
+Changes the cluster size (must be power-of-2 between 4K and 64K). Smaller
+cluster sizes can improve the image file size whereas larger cluster sizes
+generally provide better performance.
+@item table_size
+Changes the number of clusters per L1/L2 table (must be power-of-2 between 1
+and 16). There is normally no need to change this value but this option can be
+used for performance benchmarking.
+@end table
@item qcow
Old QEMU image format. Left for compatibility.
--- /dev/null
+/*
+ * Logging support
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu-common.h"
+#include "qemu-log.h"
+
+#ifdef WIN32
+static const char *logfilename = "qemu.log";
+#else
+static const char *logfilename = "/tmp/qemu.log";
+#endif
+FILE *qemu_logfile;
+int qemu_loglevel;
+static int log_append = 0;
+
+void qemu_log(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (qemu_logfile) {
+ vfprintf(qemu_logfile, fmt, ap);
+ }
+ va_end(ap);
+}
+
+void qemu_log_mask(int mask, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ if ((qemu_loglevel & mask) && qemu_logfile) {
+ vfprintf(qemu_logfile, fmt, ap);
+ }
+ va_end(ap);
+}
+
+/* enable or disable low levels log */
+void cpu_set_log(int log_flags)
+{
+ qemu_loglevel = log_flags;
+ if (qemu_loglevel && !qemu_logfile) {
+ qemu_logfile = fopen(logfilename, log_append ? "a" : "w");
+ if (!qemu_logfile) {
+ perror(logfilename);
+ _exit(1);
+ }
+#if !defined(CONFIG_SOFTMMU)
+ /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
+ {
+ static char logfile_buf[4096];
+ setvbuf(qemu_logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
+ }
+#elif defined(_WIN32)
+ /* Win32 doesn't support line-buffering, so use unbuffered output. */
+ setvbuf(qemu_logfile, NULL, _IONBF, 0);
+#else
+ setvbuf(qemu_logfile, NULL, _IOLBF, 0);
+#endif
+ log_append = 1;
+ }
+ if (!qemu_loglevel && qemu_logfile) {
+ fclose(qemu_logfile);
+ qemu_logfile = NULL;
+ }
+}
+
+void cpu_set_log_filename(const char *filename)
+{
+ logfilename = strdup(filename);
+ if (qemu_logfile) {
+ fclose(qemu_logfile);
+ qemu_logfile = NULL;
+ }
+ cpu_set_log(qemu_loglevel);
+}
+
+const CPULogItem cpu_log_items[] = {
+ { CPU_LOG_TB_OUT_ASM, "out_asm",
+ "show generated host assembly code for each compiled TB" },
+ { CPU_LOG_TB_IN_ASM, "in_asm",
+ "show target assembly code for each compiled TB" },
+ { CPU_LOG_TB_OP, "op",
+ "show micro ops for each compiled TB" },
+ { CPU_LOG_TB_OP_OPT, "op_opt",
+ "show micro ops "
+#ifdef TARGET_I386
+ "before eflags optimization and "
+#endif
+ "after liveness analysis" },
+ { CPU_LOG_INT, "int",
+ "show interrupts/exceptions in short format" },
+ { CPU_LOG_EXEC, "exec",
+ "show trace before each executed TB (lots of logs)" },
+ { CPU_LOG_TB_CPU, "cpu",
+ "show CPU state before block translation" },
+#ifdef TARGET_I386
+ { CPU_LOG_PCALL, "pcall",
+ "show protected mode far calls/returns/exceptions" },
+ { CPU_LOG_RESET, "cpu_reset",
+ "show CPU state before CPU resets" },
+#endif
+#ifdef DEBUG_IOPORT
+ { CPU_LOG_IOPORT, "ioport",
+ "show all i/o ports accesses" },
+#endif
+ { LOG_UNIMP, "unimp",
+ "log unimplemented functionality" },
+ { 0, NULL, NULL },
+};
+
+static int cmp1(const char *s1, int n, const char *s2)
+{
+ if (strlen(s2) != n) {
+ return 0;
+ }
+ return memcmp(s1, s2, n) == 0;
+}
+
+/* takes a comma separated list of log masks. Return 0 if error. */
+int cpu_str_to_log_mask(const char *str)
+{
+ const CPULogItem *item;
+ int mask;
+ const char *p, *p1;
+
+ p = str;
+ mask = 0;
+ for (;;) {
+ p1 = strchr(p, ',');
+ if (!p1) {
+ p1 = p + strlen(p);
+ }
+ if (cmp1(p,p1-p,"all")) {
+ for (item = cpu_log_items; item->mask != 0; item++) {
+ mask |= item->mask;
+ }
+ } else {
+ for (item = cpu_log_items; item->mask != 0; item++) {
+ if (cmp1(p, p1 - p, item->name)) {
+ goto found;
+ }
+ }
+ return 0;
+ }
+ found:
+ mask |= item->mask;
+ if (*p1 != ',') {
+ break;
+ }
+ p = p1 + 1;
+ }
+ return mask;
+}
#ifndef QEMU_LOG_H
#define QEMU_LOG_H
-/* The deprecated global variables: */
-extern FILE *logfile;
-extern int loglevel;
+#include <stdarg.h>
+#ifdef NEED_CPU_H
+#include "disas.h"
+#endif
+/* Private global variables, don't use */
+extern FILE *qemu_logfile;
+extern int qemu_loglevel;
/*
* The new API:
/* Returns true if qemu_log() will really write somewhere
*/
-#define qemu_log_enabled() (logfile != NULL)
+static inline bool qemu_log_enabled(void)
+{
+ return qemu_logfile != NULL;
+}
+
+#define CPU_LOG_TB_OUT_ASM (1 << 0)
+#define CPU_LOG_TB_IN_ASM (1 << 1)
+#define CPU_LOG_TB_OP (1 << 2)
+#define CPU_LOG_TB_OP_OPT (1 << 3)
+#define CPU_LOG_INT (1 << 4)
+#define CPU_LOG_EXEC (1 << 5)
+#define CPU_LOG_PCALL (1 << 6)
+#define CPU_LOG_IOPORT (1 << 7)
+#define CPU_LOG_TB_CPU (1 << 8)
+#define CPU_LOG_RESET (1 << 9)
+#define LOG_UNIMP (1 << 10)
/* Returns true if a bit is set in the current loglevel mask
*/
-#define qemu_loglevel_mask(b) ((loglevel & (b)) != 0)
-
+static inline bool qemu_loglevel_mask(int mask)
+{
+ return (qemu_loglevel & mask) != 0;
+}
/* Logging functions: */
/* main logging function
*/
-#define qemu_log(...) do { \
- if (logfile) \
- fprintf(logfile, ## __VA_ARGS__); \
- } while (0)
+void GCC_FMT_ATTR(1, 2) qemu_log(const char *fmt, ...);
/* vfprintf-like logging function
*/
-#define qemu_log_vprintf(fmt, va) do { \
- if (logfile) \
- vfprintf(logfile, fmt, va); \
- } while (0)
+static inline void qemu_log_vprintf(const char *fmt, va_list va)
+{
+ if (qemu_logfile) {
+ vfprintf(qemu_logfile, fmt, va);
+ }
+}
/* log only if a bit is set on the current loglevel mask
*/
-#define qemu_log_mask(b, ...) do { \
- if (loglevel & (b)) \
- fprintf(logfile, ## __VA_ARGS__); \
- } while (0)
-
-
+void GCC_FMT_ATTR(2, 3) qemu_log_mask(int mask, const char *fmt, ...);
/* Special cases: */
#ifdef NEED_CPU_H
/* cpu_dump_state() logging functions: */
-#define log_cpu_state(env, f) cpu_dump_state((env), logfile, fprintf, (f));
-#define log_cpu_state_mask(b, env, f) do { \
- if (loglevel & (b)) log_cpu_state((env), (f)); \
- } while (0)
-
-/* disas() and target_disas() to logfile: */
-#define log_target_disas(start, len, flags) \
- target_disas(logfile, (start), (len), (flags))
-#define log_disas(start, len) \
- disas(logfile, (start), (len))
-
+static inline void log_cpu_state(CPUArchState *env1, int flags)
+{
+ cpu_dump_state(env1, qemu_logfile, fprintf, flags);
+}
+
+static inline void log_cpu_state_mask(int mask, CPUArchState *env1, int flags)
+{
+ if (qemu_loglevel & mask) {
+ log_cpu_state(env1, flags);
+ }
+}
+
+/* disas() and target_disas() to qemu_logfile: */
+static inline void log_target_disas(target_ulong start, target_ulong len,
+ int flags)
+{
+ target_disas(qemu_logfile, start, len, flags);
+}
+
+static inline void log_disas(void *code, unsigned long size)
+{
+ disas(qemu_logfile, code, size);
+}
+
+#if defined(CONFIG_USER_ONLY)
/* page_dump() output to the log file: */
-#define log_page_dump() page_dump(logfile)
+static inline void log_page_dump(void)
+{
+ page_dump(qemu_logfile);
+}
+#endif
#endif
-
/* Maintenance: */
/* fflush() the log file */
-#define qemu_log_flush() fflush(logfile)
+static inline void qemu_log_flush(void)
+{
+ fflush(qemu_logfile);
+}
/* Close the log file */
-#define qemu_log_close() do { \
- fclose(logfile); \
- logfile = NULL; \
- } while (0)
+static inline void qemu_log_close(void)
+{
+ fclose(qemu_logfile);
+ qemu_logfile = NULL;
+}
/* Set up a new log file */
-#define qemu_log_set_file(f) do { \
- logfile = (f); \
- } while (0)
+static inline void qemu_log_set_file(FILE *f)
+{
+ qemu_logfile = f;
+}
/* Set up a new log file, only if none is set */
-#define qemu_log_try_set_file(f) do { \
- if (!logfile) \
- logfile = (f); \
- } while (0)
-
+static inline void qemu_log_try_set_file(FILE *f)
+{
+ if (!qemu_logfile) {
+ qemu_logfile = f;
+ }
+}
+
+/* define log items */
+typedef struct CPULogItem {
+ int mask;
+ const char *name;
+ const char *help;
+} CPULogItem;
+
+extern const CPULogItem cpu_log_items[];
+
+void cpu_set_log(int log_flags);
+void cpu_set_log_filename(const char *filename);
+int cpu_str_to_log_mask(const char *str);
#endif
#include <sys/time.h>
-FILE *logfile;
-
struct QEMUBH
{
QEMUBHFunc *cb;
size_t instance_size;
void (*class_init)(ObjectClass *klass, void *data);
+ void (*class_base_init)(ObjectClass *klass, void *data);
void (*class_finalize)(ObjectClass *klass, void *data);
void *class_data;
return g_hash_table_lookup(type_table_get(), name);
}
-TypeImpl *type_register(const TypeInfo *info)
+static TypeImpl *type_register_internal(const TypeInfo *info)
{
TypeImpl *ti = g_malloc0(sizeof(*ti));
ti->instance_size = info->instance_size;
ti->class_init = info->class_init;
+ ti->class_base_init = info->class_base_init;
ti->class_finalize = info->class_finalize;
ti->class_data = info->class_data;
return ti;
}
+TypeImpl *type_register(const TypeInfo *info)
+{
+ assert(info->parent);
+ return type_register_internal(info);
+}
+
TypeImpl *type_register_static(const TypeInfo *info)
{
return type_register(info);
char *name = g_strdup_printf("<%s::%s>", ti->name, iface->parent);
info.name = name;
- iface->type = type_register(&info);
+ iface->type = type_register_internal(&info);
g_free(name);
}
static void type_initialize(TypeImpl *ti)
{
- size_t class_size = sizeof(ObjectClass);
+ TypeImpl *parent;
int i;
if (ti->class) {
ti->instance_size = type_object_get_size(ti);
ti->class = g_malloc0(ti->class_size);
- ti->class->type = ti;
-
- if (type_has_parent(ti)) {
- TypeImpl *parent = type_get_parent(ti);
+ parent = type_get_parent(ti);
+ if (parent) {
type_initialize(parent);
- class_size = parent->class_size;
g_assert(parent->class_size <= ti->class_size);
-
- memcpy((void *)ti->class + sizeof(ObjectClass),
- (void *)parent->class + sizeof(ObjectClass),
- parent->class_size - sizeof(ObjectClass));
+ memcpy(ti->class, parent->class, parent->class_size);
}
- memset((void *)ti->class + class_size, 0, ti->class_size - class_size);
+ ti->class->type = ti;
+
+ while (parent) {
+ if (parent->class_base_init) {
+ parent->class_base_init(ti->class, ti->class_data);
+ }
+ parent = type_get_parent(parent);
+ }
for (i = 0; i < ti->num_interfaces; i++) {
type_class_interface_init(ti, &ti->interfaces[i]);
object_initialize_with_type(data, type);
}
+static inline bool object_property_is_child(ObjectProperty *prop)
+{
+ return strstart(prop->type, "child<", NULL);
+}
+
+static inline bool object_property_is_link(ObjectProperty *prop)
+{
+ return strstart(prop->type, "link<", NULL);
+}
+
static void object_property_del_all(Object *obj)
{
while (!QTAILQ_EMPTY(&obj->properties)) {
ObjectProperty *prop;
QTAILQ_FOREACH(prop, &obj->properties, node) {
- if (strstart(prop->type, "child<", NULL) && prop->opaque == child) {
+ if (object_property_is_child(prop) && prop->opaque == child) {
object_property_del(obj, prop->name, errp);
break;
}
}
-static void register_types(void)
-{
- static TypeInfo interface_info = {
- .name = TYPE_INTERFACE,
- .instance_size = sizeof(Interface),
- .abstract = true,
- };
-
- type_interface = type_register_static(&interface_info);
-}
-
-type_init(register_types)
-
Object *object_dynamic_cast_assert(Object *obj, const char *typename)
{
Object *inst;
return type->class;
}
+ObjectClass *object_class_get_parent(ObjectClass *class)
+{
+ TypeImpl *type = type_get_parent(class->type);
+
+ if (!type) {
+ return NULL;
+ }
+
+ type_initialize(type);
+
+ return type->class;
+}
+
typedef struct OCFData
{
void (*fn)(ObjectClass *klass, void *opaque);
g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
}
+int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
+ void *opaque)
+{
+ ObjectProperty *prop;
+ int ret = 0;
+
+ QTAILQ_FOREACH(prop, &obj->properties, node) {
+ if (object_property_is_child(prop)) {
+ ret = fn(prop->opaque, opaque);
+ if (ret != 0) {
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
static void object_class_get_list_tramp(ObjectClass *klass, void *opaque)
{
GSList **list = opaque;
QTAILQ_INSERT_TAIL(&obj->properties, prop, node);
}
-static ObjectProperty *object_property_find(Object *obj, const char *name)
+ObjectProperty *object_property_find(Object *obj, const char *name,
+ Error **errp)
{
ObjectProperty *prop;
}
}
+ error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
return NULL;
}
void object_property_del(Object *obj, const char *name, Error **errp)
{
- ObjectProperty *prop = object_property_find(obj, name);
+ ObjectProperty *prop = object_property_find(obj, name, errp);
+ if (prop == NULL) {
+ return;
+ }
- QTAILQ_REMOVE(&obj->properties, prop, node);
+ if (prop->release) {
+ prop->release(obj, name, prop->opaque);
+ }
- prop->release(obj, prop->name, prop->opaque);
+ QTAILQ_REMOVE(&obj->properties, prop, node);
g_free(prop->name);
g_free(prop->type);
void object_property_get(Object *obj, Visitor *v, const char *name,
Error **errp)
{
- ObjectProperty *prop = object_property_find(obj, name);
-
+ ObjectProperty *prop = object_property_find(obj, name, errp);
if (prop == NULL) {
- error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
return;
}
void object_property_set(Object *obj, Visitor *v, const char *name,
Error **errp)
{
- ObjectProperty *prop = object_property_find(obj, name);
-
+ ObjectProperty *prop = object_property_find(obj, name, errp);
if (prop == NULL) {
- error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
return;
}
const char *object_property_get_type(Object *obj, const char *name, Error **errp)
{
- ObjectProperty *prop = object_property_find(obj, name);
-
+ ObjectProperty *prop = object_property_find(obj, name, errp);
if (prop == NULL) {
- error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
return NULL;
}
g_assert(obj->parent != NULL);
QTAILQ_FOREACH(prop, &obj->parent->properties, node) {
- if (!strstart(prop->type, "child<", NULL)) {
+ if (!object_property_is_child(prop)) {
continue;
}
Object *object_resolve_path_component(Object *parent, gchar *part)
{
- ObjectProperty *prop = object_property_find(parent, part);
+ ObjectProperty *prop = object_property_find(parent, part, NULL);
if (prop == NULL) {
return NULL;
}
- if (strstart(prop->type, "link<", NULL)) {
+ if (object_property_is_link(prop)) {
return *(Object **)prop->opaque;
- } else if (strstart(prop->type, "child<", NULL)) {
+ } else if (object_property_is_child(prop)) {
return prop->opaque;
} else {
return NULL;
QTAILQ_FOREACH(prop, &parent->properties, node) {
Object *found;
- if (!strstart(prop->type, "child<", NULL)) {
+ if (!object_property_is_child(prop)) {
continue;
}
property_release_str,
prop, errp);
}
+
+static char *qdev_get_type(Object *obj, Error **errp)
+{
+ return g_strdup(object_get_typename(obj));
+}
+
+static void object_instance_init(Object *obj)
+{
+ object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
+}
+
+static void register_types(void)
+{
+ static TypeInfo interface_info = {
+ .name = TYPE_INTERFACE,
+ .instance_size = sizeof(Interface),
+ .abstract = true,
+ };
+
+ static TypeInfo object_info = {
+ .name = TYPE_OBJECT,
+ .instance_size = sizeof(Object),
+ .instance_init = object_instance_init,
+ .abstract = true,
+ };
+
+ type_interface = type_register_internal(&interface_info);
+ type_register_internal(&object_info);
+}
+
+type_init(register_types)
}
readline_show_prompt(rs);
}
+ for (i = 0; i < rs->nb_completions; i++) {
+ g_free(rs->completions[i]);
+ }
}
/* return true if command handled */
$(foreach var,$(nested-vars),$(call push-var,$(var),$1/))
$(eval obj := $(obj)/$1)
$(eval include $(SRC_PATH)/$1/Makefile.objs)
+$(eval -include $(wildcard $1/*.d))
$(eval obj := $(patsubst %/$1,%,$(obj)))
$(foreach var,$(nested-vars),$(call pop-var,$(var),$1/))
endef
static int bdrv_fclose(void *opaque)
{
- return 0;
+ return bdrv_flush(opaque);
}
static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
se->is_ram = 1;
}
- if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
- char *id = dev->parent_bus->info->get_dev_path(dev);
+ if (dev) {
+ char *id = qdev_get_dev_path(dev);
if (id) {
pstrcpy(se->idstr, sizeof(se->idstr), id);
pstrcat(se->idstr, sizeof(se->idstr), "/");
SaveStateEntry *se, *new_se;
char id[256] = "";
- if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
- char *path = dev->parent_bus->info->get_dev_path(dev);
+ if (dev) {
+ char *path = qdev_get_dev_path(dev);
if (path) {
pstrcpy(id, sizeof(id), path);
pstrcat(id, sizeof(id), "/");
se->alias_id = alias_id;
se->no_migrate = vmsd->unmigratable;
- if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
- char *id = dev->parent_bus->info->get_dev_path(dev);
+ if (dev) {
+ char *id = qdev_get_dev_path(dev);
if (id) {
pstrcpy(se->idstr, sizeof(se->idstr), id);
pstrcat(se->idstr, sizeof(se->idstr), "/");
* Authors:
* Wen Congyang <wency@cn.fujitsu.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
*
*/
* Authors:
* Wen Congyang <wency@cn.fujitsu.com>
*
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
*
*/
.ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
.xlevel = 0x8000000A,
- .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
},
{
.name = "phenom",
.features = PPRO_FEATURES,
.ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
.xlevel = 0x80000004,
- .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
},
{
.name = "kvm32",
.features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
.ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
.xlevel = 0x80000008,
- /* XXX: put another string ? */
- .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
},
{
.name = "n270",
*/
void x86_cpudef_setup(void)
{
- int i;
+ int i, j;
+ static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
builtin_x86_defs[i].next = x86_defs;
builtin_x86_defs[i].flags = 1;
+
+ /* Look for specific "cpudef" models that */
+ /* have the QEmu version in .model_id */
+ for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
+ if (strcmp(model_with_versions[j], builtin_x86_defs[i].name) == 0) {
+ pstrcpy(builtin_x86_defs[i].model_id, sizeof(builtin_x86_defs[i].model_id), "QEMU Virtual CPU version ");
+ pstrcat(builtin_x86_defs[i].model_id, sizeof(builtin_x86_defs[i].model_id), qemu_get_version());
+ break;
+ }
+ }
+
x86_defs = &builtin_x86_defs[i];
}
#if !defined(CONFIG_USER_ONLY)
helper_svm_check_intercept_param(SVM_EXIT_RDPMC, 0);
/* currently unimplemented */
+ qemu_log_mask(LOG_UNIMP, "x86: unimplemented rdpmc\n");
raise_exception_err(EXCP06_ILLOP, 0);
}
cpu_R[dc->ra], cpu_R[dc->rb]);
break;
default:
- qemu_log ("unimplemented fcmp fpu_insn=%x pc=%x opc=%x\n",
- fpu_insn, dc->pc, dc->opcode);
+ qemu_log_mask(LOG_UNIMP,
+ "unimplemented fcmp fpu_insn=%x pc=%x"
+ " opc=%x\n",
+ fpu_insn, dc->pc, dc->opcode);
dc->abort_at_next_insn = 1;
break;
}
break;
default:
- qemu_log ("unimplemented FPU insn fpu_insn=%x pc=%x opc=%x\n",
- fpu_insn, dc->pc, dc->opcode);
+ qemu_log_mask(LOG_UNIMP, "unimplemented FPU insn fpu_insn=%x pc=%x"
+ " opc=%x\n",
+ fpu_insn, dc->pc, dc->opcode);
dc->abort_at_next_insn = 1;
break;
}
break;
#endif
default:
- cpu_fprintf(f, "%s: unimplemented\n", __func__);
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
}
}
disas_ed(s, op, r1, x2, b2, d2, r1b);
break;
default:
- LOG_DISAS("unimplemented opcode 0x%x\n", opc);
+ qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%x\n", opc);
gen_illegal_opcode(s, ilc);
break;
}
if (size == 8) {
ret = env->mxccregs[3];
} else {
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented access size: %d\n", addr,
+ size);
}
break;
case 0x01c00a04: /* MXCC control register */
if (size == 4) {
ret = env->mxccregs[3];
} else {
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented access size: %d\n", addr,
+ size);
}
break;
case 0x01c00c00: /* Module reset register */
ret = env->mxccregs[5];
/* should we do something here? */
} else {
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented access size: %d\n", addr,
+ size);
}
break;
case 0x01c00f00: /* MBus port address register */
if (size == 8) {
ret = env->mxccregs[7];
} else {
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented access size: %d\n", addr,
+ size);
}
break;
default:
- DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented address, size: %d\n", addr,
+ size);
break;
}
DPRINTF_MXCC("asi = %d, size = %d, sign = %d, "
if (size == 8) {
env->mxccdata[0] = val;
} else {
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented access size: %d\n", addr,
+ size);
}
break;
case 0x01c00008: /* MXCC stream data register 1 */
if (size == 8) {
env->mxccdata[1] = val;
} else {
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented access size: %d\n", addr,
+ size);
}
break;
case 0x01c00010: /* MXCC stream data register 2 */
if (size == 8) {
env->mxccdata[2] = val;
} else {
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented access size: %d\n", addr,
+ size);
}
break;
case 0x01c00018: /* MXCC stream data register 3 */
if (size == 8) {
env->mxccdata[3] = val;
} else {
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented access size: %d\n", addr,
+ size);
}
break;
case 0x01c00100: /* MXCC stream source */
if (size == 8) {
env->mxccregs[0] = val;
} else {
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented access size: %d\n", addr,
+ size);
}
env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
0);
if (size == 8) {
env->mxccregs[1] = val;
} else {
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented access size: %d\n", addr,
+ size);
}
stq_phys((env->mxccregs[1] & 0xffffffffULL) + 0,
env->mxccdata[0]);
if (size == 8) {
env->mxccregs[3] = val;
} else {
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented access size: %d\n", addr,
+ size);
}
break;
case 0x01c00a04: /* MXCC control register */
env->mxccregs[3] = (env->mxccregs[3] & 0xffffffff00000000ULL)
| val;
} else {
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented access size: %d\n", addr,
+ size);
}
break;
case 0x01c00e00: /* MXCC error register */
if (size == 8) {
env->mxccregs[6] &= ~val;
} else {
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented access size: %d\n", addr,
+ size);
}
break;
case 0x01c00f00: /* MBus port address register */
if (size == 8) {
env->mxccregs[7] = val;
} else {
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented access size: %d\n", addr,
+ size);
}
break;
default:
- DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr,
- size);
+ qemu_log_mask(LOG_UNIMP,
+ "%08x: unimplemented address, size: %d\n", addr,
+ size);
break;
}
DPRINTF_MXCC("asi = %d, size = %d, addr = %08x, val = %" PRIx64 "\n",
break;
default:
- tcg_dump_ops (s, stderr);
+ tcg_dump_ops (s);
tcg_abort ();
}
}
break;
default:
- tcg_dump_ops (s, stderr);
+ tcg_dump_ops (s);
tcg_abort ();
}
}
[TCG_COND_GTU] = "gtu"
};
-void tcg_dump_ops(TCGContext *s, FILE *outfile)
+void tcg_dump_ops(TCGContext *s)
{
const uint16_t *opc_ptr;
const TCGArg *args;
#else
pc = args[0];
#endif
- if (!first_insn)
- fprintf(outfile, "\n");
- fprintf(outfile, " ---- 0x%" PRIx64, pc);
+ if (!first_insn) {
+ qemu_log("\n");
+ }
+ qemu_log(" ---- 0x%" PRIx64, pc);
first_insn = 0;
nb_oargs = def->nb_oargs;
nb_iargs = def->nb_iargs;
nb_iargs = arg & 0xffff;
nb_cargs = def->nb_cargs;
- fprintf(outfile, " %s ", def->name);
+ qemu_log(" %s ", def->name);
/* function name */
- fprintf(outfile, "%s",
- tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1]));
+ qemu_log("%s",
+ tcg_get_arg_str_idx(s, buf, sizeof(buf),
+ args[nb_oargs + nb_iargs - 1]));
/* flags */
- fprintf(outfile, ",$0x%" TCG_PRIlx,
- args[nb_oargs + nb_iargs]);
+ qemu_log(",$0x%" TCG_PRIlx, args[nb_oargs + nb_iargs]);
/* nb out args */
- fprintf(outfile, ",$%d", nb_oargs);
+ qemu_log(",$%d", nb_oargs);
for(i = 0; i < nb_oargs; i++) {
- fprintf(outfile, ",");
- fprintf(outfile, "%s",
- tcg_get_arg_str_idx(s, buf, sizeof(buf), args[i]));
+ qemu_log(",");
+ qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
+ args[i]));
}
for(i = 0; i < (nb_iargs - 1); i++) {
- fprintf(outfile, ",");
+ qemu_log(",");
if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
- fprintf(outfile, "<dummy>");
+ qemu_log("<dummy>");
} else {
- fprintf(outfile, "%s",
- tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i]));
+ qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
+ args[nb_oargs + i]));
}
}
} else if (c == INDEX_op_movi_i32
nb_oargs = def->nb_oargs;
nb_iargs = def->nb_iargs;
nb_cargs = def->nb_cargs;
- fprintf(outfile, " %s %s,$", def->name,
- tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
+ qemu_log(" %s %s,$", def->name,
+ tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
val = args[1];
th = tcg_find_helper(s, val);
if (th) {
- fprintf(outfile, "%s", th->name);
+ qemu_log("%s", th->name);
} else {
- if (c == INDEX_op_movi_i32)
- fprintf(outfile, "0x%x", (uint32_t)val);
- else
- fprintf(outfile, "0x%" PRIx64 , (uint64_t)val);
+ if (c == INDEX_op_movi_i32) {
+ qemu_log("0x%x", (uint32_t)val);
+ } else {
+ qemu_log("0x%" PRIx64 , (uint64_t)val);
+ }
}
} else {
- fprintf(outfile, " %s ", def->name);
+ qemu_log(" %s ", def->name);
if (c == INDEX_op_nopn) {
/* variable number of arguments */
nb_cargs = *args;
k = 0;
for(i = 0; i < nb_oargs; i++) {
- if (k != 0)
- fprintf(outfile, ",");
- fprintf(outfile, "%s",
- tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
+ if (k != 0) {
+ qemu_log(",");
+ }
+ qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
+ args[k++]));
}
for(i = 0; i < nb_iargs; i++) {
- if (k != 0)
- fprintf(outfile, ",");
- fprintf(outfile, "%s",
- tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
+ if (k != 0) {
+ qemu_log(",");
+ }
+ qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
+ args[k++]));
}
switch (c) {
case INDEX_op_brcond_i32:
#elif TCG_TARGET_REG_BITS == 64
case INDEX_op_setcond_i64:
#endif
- if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]])
- fprintf(outfile, ",%s", cond_name[args[k++]]);
- else
- fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]);
+ if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
+ qemu_log(",%s", cond_name[args[k++]]);
+ } else {
+ qemu_log(",$0x%" TCG_PRIlx, args[k++]);
+ }
i = 1;
break;
default:
break;
}
for(; i < nb_cargs; i++) {
- if (k != 0)
- fprintf(outfile, ",");
+ if (k != 0) {
+ qemu_log(",");
+ }
arg = args[k++];
- fprintf(outfile, "$0x%" TCG_PRIlx, arg);
+ qemu_log("$0x%" TCG_PRIlx, arg);
}
}
- fprintf(outfile, "\n");
+ qemu_log("\n");
args += nb_iargs + nb_oargs + nb_cargs;
}
}
#ifdef DEBUG_DISAS
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
qemu_log("OP:\n");
- tcg_dump_ops(s, logfile);
+ tcg_dump_ops(s);
qemu_log("\n");
}
#endif
#ifdef DEBUG_DISAS
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
qemu_log("OP after liveness analysis:\n");
- tcg_dump_ops(s, logfile);
+ tcg_dump_ops(s);
qemu_log("\n");
}
#endif
/* only used for debugging purposes */
void tcg_register_helper(void *func, const char *name);
const char *tcg_helper_get_name(TCGContext *s, void *func);
-void tcg_dump_ops(TCGContext *s, FILE *outfile);
+void tcg_dump_ops(TCGContext *s);
void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
TCGv_i32 tcg_const_i32(int32_t val);
#if defined(CONFIG_DEBUG_TCG_INTERPRETER)
const char *envval = getenv("DEBUG_TCG");
if (envval) {
- loglevel = strtol(envval, NULL, 0);
+ cpu_set_log(strtol(envval, NULL, 0));
}
#endif
enum {
CMD_SENSE_INT = 0x08,
CMD_SEEK = 0x0f,
+ CMD_READ = 0xe6,
};
enum {
g_assert(!get_irq(FLOPPY_IRQ));
}
+static uint8_t send_read_command(void)
+{
+ uint8_t drive = 0;
+ uint8_t head = 0;
+ uint8_t cyl = 0;
+ uint8_t sect_addr = 1;
+ uint8_t sect_size = 2;
+ uint8_t eot = 1;
+ uint8_t gap = 0x1b;
+ uint8_t gpl = 0xff;
+
+ uint8_t msr = 0;
+ uint8_t st0;
+
+ uint8_t ret = 0;
+
+ floppy_send(CMD_READ);
+ floppy_send(head << 2 | drive);
+ g_assert(!get_irq(FLOPPY_IRQ));
+ floppy_send(cyl);
+ floppy_send(head);
+ floppy_send(sect_addr);
+ floppy_send(sect_size);
+ floppy_send(eot);
+ floppy_send(gap);
+ floppy_send(gpl);
+
+ uint8_t i = 0;
+ uint8_t n = 2;
+ for (; i < n; i++) {
+ msr = inb(FLOPPY_BASE + reg_msr);
+ if (msr == 0xd0) {
+ break;
+ }
+ sleep(1);
+ }
+
+ if (i >= n) {
+ return 1;
+ }
+
+ st0 = floppy_recv();
+ if (st0 != 0x40) {
+ ret = 1;
+ }
+
+ floppy_recv();
+ floppy_recv();
+ floppy_recv();
+ floppy_recv();
+ floppy_recv();
+ floppy_recv();
+
+ return ret;
+}
+
static void send_step_pulse(void)
{
int drive = 0;
assert_bit_set(dir, DSKCHG);
}
+static void test_read_without_media(void)
+{
+ uint8_t ret;
+
+ ret = send_read_command();
+ g_assert(ret == 0);
+}
+
static void test_media_change(void)
{
uint8_t dir;
assert_bit_set(dir, DSKCHG);
}
+/* success if no crash or abort */
+static void fuzz_registers(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < 1000; i++) {
+ uint8_t reg, val;
+
+ reg = (uint8_t)g_test_rand_int_range(0, 8);
+ val = (uint8_t)g_test_rand_int_range(0, 256);
+
+ outb(FLOPPY_BASE + reg, val);
+ inb(FLOPPY_BASE + reg);
+ }
+}
+
int main(int argc, char **argv)
{
const char *arch = qtest_get_arch();
qtest_irq_intercept_in(global_qtest, "ioapic");
qtest_add_func("/fdc/cmos", test_cmos);
qtest_add_func("/fdc/no_media_on_start", test_no_media_on_start);
+ qtest_add_func("/fdc/read_without_media", test_read_without_media);
qtest_add_func("/fdc/media_change", test_media_change);
+ qtest_add_func("/fdc/fuzz-registers", fuzz_registers);
ret = g_test_run();
import os
import iotests
from iotests import qemu_img, qemu_io
+import struct
backing_img = os.path.join(iotests.test_dir, 'backing.img')
mid_img = os.path.join(iotests.test_dir, 'mid.img')
self.assert_no_active_streams()
+ def create_image(self, name, size):
+ file = open(name, 'w')
+ i = 0
+ while i < size:
+ sector = struct.pack('>l504xl', i / 512, i / 512)
+ file.write(sector)
+ i = i + 512
+ file.close()
+
+
class TestSingleDrive(ImageStreamingTestCase):
image_len = 1 * 1024 * 1024 # MB
def setUp(self):
- qemu_img('create', backing_img, str(TestSingleDrive.image_len))
+ self.create_image(backing_img, TestSingleDrive.image_len)
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
self.vm = iotests.VM().add_drive(test_img)
result = self.vm.qmp('block-stream', device='drive0')
self.assert_qmp(result, 'return', {})
- time.sleep(1)
+ time.sleep(0.1)
events = self.vm.get_qmp_events(wait=False)
self.assertEqual(events, [], 'unexpected QMP event: %s' % events)
--- /dev/null
+#!/bin/bash
+#
+# Test that qcow2 unknown autoclear feature bits are cleared
+#
+# Copyright (C) 2011 Red Hat, Inc.
+# Copyright IBM, Corp. 2010
+#
+# Based on test 031.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=stefanha@linux.vnet.ibm.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.pattern
+
+# This tests qcow2-specific low-level functionality
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+# Only qcow2v3 and later supports feature bits
+IMGOPTS="compat=1.1"
+
+echo === Create image with unknown autoclear feature bit ===
+echo
+_make_test_img 64M
+./qcow2.py $TEST_IMG set-feature-bit autoclear 63
+./qcow2.py $TEST_IMG dump-header
+
+echo
+echo === Repair image ===
+echo
+$QEMU_IMG check -r all $TEST_IMG
+./qcow2.py $TEST_IMG dump-header
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
--- /dev/null
+QA output created by 036
+=== Create image with unknown autoclear feature bit ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+magic 0x514649fb
+version 3
+backing_file_offset 0x0
+backing_file_size 0x0
+cluster_bits 16
+size 67108864
+crypt_method 0
+l1_size 1
+l1_table_offset 0x30000
+refcount_table_offset 0x10000
+refcount_table_clusters 1
+nb_snapshots 0
+snapshot_offset 0x0
+incompatible_features 0x0
+compatible_features 0x0
+autoclear_features 0x8000000000000000
+refcount_order 4
+header_length 104
+
+
+=== Repair image ===
+
+No errors were found on the image.
+magic 0x514649fb
+version 3
+backing_file_offset 0x0
+backing_file_size 0x0
+cluster_bits 16
+size 67108864
+crypt_method 0
+l1_size 1
+l1_table_offset 0x30000
+refcount_table_offset 0x10000
+refcount_table_clusters 1
+nb_snapshots 0
+snapshot_offset 0x0
+incompatible_features 0x0
+compatible_features 0x0
+autoclear_features 0x0
+refcount_order 4
+header_length 104
+
+Header extension:
+magic 0x6803f857
+length 0
+data ''
+
+*** done
--- /dev/null
+#!/bin/bash
+#
+# Test COW from backing files
+#
+# Copyright (C) 2012 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=kwolf@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow qcow2 vmdk qed
+_supported_proto generic
+_supported_os Linux
+
+CLUSTER_SIZE=4k
+size=128M
+
+echo
+echo "== creating backing file for COW tests =="
+
+_make_test_img $size
+
+function backing_io()
+{
+ local offset=$1
+ local sectors=$2
+ local op=$3
+ local pattern=0
+ local cur_sec=0
+
+ for i in $(seq 0 $((sectors - 1))); do
+ cur_sec=$((offset / 512 + i))
+ pattern=$(( ( (cur_sec % 256) + (cur_sec / 256)) % 256 ))
+
+ echo "$op -P $pattern $((cur_sec * 512)) 512"
+ done
+}
+
+backing_io 0 256 write | $QEMU_IO $TEST_IMG | _filter_qemu_io
+
+mv $TEST_IMG $TEST_IMG.base
+
+_make_test_img -b $TEST_IMG.base 6G
+
+echo
+echo "== COW in a single cluster =="
+$QEMU_IO -c "write -P 0x77 0 2k" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "write -P 0x88 6k 2k" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "write -P 0x99 9k 2k" $TEST_IMG | _filter_qemu_io
+
+$QEMU_IO -c "read -P 0x77 0 2k" $TEST_IMG | _filter_qemu_io
+backing_io $((2 * 1024)) 8 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -P 0x88 6k 2k" $TEST_IMG | _filter_qemu_io
+backing_io $((8 * 1024)) 2 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -P 0x99 9k 2k" $TEST_IMG | _filter_qemu_io
+backing_io $((11 * 1024)) 2 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+
+echo
+echo "== COW in two-cluster allocations =="
+$QEMU_IO -c "write -P 0x77 16k 6k" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "write -P 0x88 26k 6k" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "write -P 0x99 33k 5k" $TEST_IMG | _filter_qemu_io
+
+$QEMU_IO -c "read -P 0x77 16k 6k" $TEST_IMG | _filter_qemu_io
+backing_io $((22 * 1024)) 8 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -P 0x88 26k 6k" $TEST_IMG | _filter_qemu_io
+backing_io $((32 * 1024)) 2 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -P 0x99 33k 5k" $TEST_IMG | _filter_qemu_io
+backing_io $((38 * 1024)) 4 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+
+echo
+echo "== COW in multi-cluster allocations =="
+$QEMU_IO -c "write -P 0x77 48k 15k" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "write -P 0x88 66k 14k" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "write -P 0x99 83k 15k" $TEST_IMG | _filter_qemu_io
+
+$QEMU_IO -c "read -P 0x77 48k 15k" $TEST_IMG | _filter_qemu_io
+backing_io $((63 * 1024)) 6 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -P 0x88 66k 14k" $TEST_IMG | _filter_qemu_io
+backing_io $((80 * 1024)) 6 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -P 0x99 83k 15k" $TEST_IMG | _filter_qemu_io
+backing_io $((98 * 1024)) 4 read | $QEMU_IO $TEST_IMG | _filter_qemu_io
+
+_check_test_img
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
--- /dev/null
+QA output created by 037
+
+== creating backing file for COW tests ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+qemu-io> wrote 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 1024
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 1536
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 2048
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 2560
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 3072
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 3584
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 4096
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 4608
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 5120
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 5632
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 6144
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 6656
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 7168
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 7680
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 8192
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 8704
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 9216
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 9728
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 10240
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 10752
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 11264
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 11776
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 12288
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 12800
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 13312
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 13824
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 14336
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 14848
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 15360
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 15872
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 16384
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 16896
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 17408
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 17920
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 18432
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 18944
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 19456
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 19968
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 20480
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 20992
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 21504
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 22016
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 22528
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 23040
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 23552
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 24064
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 24576
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 25088
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 25600
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 26112
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 26624
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 27136
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 27648
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 28160
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 28672
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 29184
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 29696
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 30208
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 30720
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 31232
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 31744
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 32256
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 32768
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 33280
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 33792
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 34304
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 34816
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 35328
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 35840
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 36352
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 36864
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 37376
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 37888
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 38400
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 38912
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 39424
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 39936
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 40448
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 40960
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 41472
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 41984
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 42496
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 43008
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 43520
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 44032
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 44544
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 45056
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 45568
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 46080
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 46592
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 47104
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 47616
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 48128
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 48640
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 49152
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 49664
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 50176
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 50688
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 51200
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 51712
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 52224
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 52736
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 53248
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 53760
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 54272
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 54784
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 55296
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 55808
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 56320
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 56832
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 57344
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 57856
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 58368
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 58880
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 59392
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 59904
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 60416
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 60928
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 61440
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 61952
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 62464
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 62976
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 63488
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 64000
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 64512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 65024
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 65536
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 66048
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 66560
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 67072
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 67584
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 68096
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 68608
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 69120
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 69632
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 70144
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 70656
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 71168
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 71680
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 72192
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 72704
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 73216
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 73728
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 74240
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 74752
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 75264
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 75776
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 76288
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 76800
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 77312
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 77824
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 78336
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 78848
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 79360
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 79872
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 80384
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 80896
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 81408
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 81920
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 82432
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 82944
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 83456
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 83968
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 84480
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 84992
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 85504
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 86016
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 86528
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 87040
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 87552
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 88064
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 88576
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 89088
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 89600
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 90112
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 90624
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 91136
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 91648
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 92160
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 92672
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 93184
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 93696
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 94208
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 94720
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 95232
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 95744
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 96256
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 96768
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 97280
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 97792
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 98304
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 98816
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 99328
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 99840
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 100352
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 100864
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 101376
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 101888
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 102400
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 102912
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 103424
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 103936
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 104448
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 104960
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 105472
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 105984
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 106496
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 107008
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 107520
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 108032
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 108544
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 109056
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 109568
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 110080
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 110592
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 111104
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 111616
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 112128
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 112640
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 113152
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 113664
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 114176
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 114688
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 115200
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 115712
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 116224
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 116736
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 117248
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 117760
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 118272
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 118784
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 119296
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 119808
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 120320
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 120832
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 121344
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 121856
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 122368
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 122880
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 123392
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 123904
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 124416
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 124928
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 125440
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 125952
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 126464
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 126976
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 127488
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 128000
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 128512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 129024
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 129536
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 130048
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 512/512 bytes at offset 130560
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
+
+== COW in a single cluster ==
+wrote 2048/2048 bytes at offset 0
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 2048/2048 bytes at offset 6144
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 2048/2048 bytes at offset 9216
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 2048/2048 bytes at offset 0
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 2048
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 2560
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 3072
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 3584
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 4096
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 4608
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 5120
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 5632
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 2048/2048 bytes at offset 6144
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 8192
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 8704
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 2048/2048 bytes at offset 9216
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 11264
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 11776
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io>
+== COW in two-cluster allocations ==
+wrote 6144/6144 bytes at offset 16384
+6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 6144/6144 bytes at offset 26624
+6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 5120/5120 bytes at offset 33792
+5 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 6144/6144 bytes at offset 16384
+6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 22528
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 23040
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 23552
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 24064
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 24576
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 25088
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 25600
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 26112
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 6144/6144 bytes at offset 26624
+6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 32768
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 33280
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 5120/5120 bytes at offset 33792
+5 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 38912
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 39424
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 39936
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 40448
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io>
+== COW in multi-cluster allocations ==
+wrote 15360/15360 bytes at offset 49152
+15 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 14336/14336 bytes at offset 67584
+14 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 15360/15360 bytes at offset 84992
+15 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 15360/15360 bytes at offset 49152
+15 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 64512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 65024
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 65536
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 66048
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 66560
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 67072
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 14336/14336 bytes at offset 67584
+14 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 81920
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 82432
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 82944
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 83456
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 83968
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 84480
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 15360/15360 bytes at offset 84992
+15 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 100352
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 100864
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 101376
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 512/512 bytes at offset 101888
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> No errors were found on the image.
+*** done
--- /dev/null
+#!/bin/bash
+#
+# Test COW from backing files with AIO
+#
+# Copyright (C) 2012 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=kwolf@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2 qed
+_supported_proto generic
+_supported_os Linux
+
+CLUSTER_SIZE=2M
+size=128M
+
+echo
+echo "== creating backing file for COW tests =="
+
+_make_test_img $size
+
+function backing_io()
+{
+ local offset=$1
+ local sectors=$2
+ local op=$3
+ local pattern=0
+ local cur_sec=0
+
+ for i in $(seq 0 $((sectors - 1))); do
+ cur_sec=$((offset / 65536 + i))
+ pattern=$(( ( (cur_sec % 128) + (cur_sec / 128)) % 128 ))
+
+ echo "$op -P $pattern $((cur_sec * 64))k 64k"
+ done
+}
+
+backing_io 0 256 write | $QEMU_IO $TEST_IMG | _filter_qemu_io
+
+mv $TEST_IMG $TEST_IMG.base
+
+_make_test_img -b $TEST_IMG.base 6G
+
+echo
+echo "== Some concurrent requests touching the same cluster =="
+
+function overlay_io()
+{
+ # Start with a request touching two clusters
+ echo aio_write -P 0x80 2020k 80k
+
+ # Then add some requests all over the place
+ for i in $(seq 0 15; seq 17 31; seq 33 47); do
+ echo aio_write -P $((0x81 + i)) $((i * 128))k 64k
+ done
+
+ # Then backwards overwriting part of them
+ for i in $( (seq 0 15; seq 17 31; seq 33 47) | tac); do
+ echo aio_write -P $((0x81 + i)) $((i * 128 + 32))k 64k
+ done
+
+ # And finally crossing the next cluster boundary
+ echo aio_write -P 0x90 4080k 80k
+}
+
+overlay_io | $QEMU_IO $TEST_IMG | _filter_qemu_io |\
+ sed -e 's/bytes at offset [0-9]*/bytes at offset XXX/g'
+
+echo
+echo "== Verify image content =="
+
+function verify_io()
+{
+ echo read -P 31 2016k 4k
+ echo read -P 0x80 2020k 80k
+ echo read -P 32 2100k 12k
+ echo read -P 33 2112k 64k
+
+ echo read -P 63 4064k 16k
+ echo read -P 0x90 4080k 80k
+ echo read -P 65 4160k 64k
+
+ for i in $(seq 0 15; seq 17 31; seq 33 47); do
+ echo read -P $((0x81 + i)) $((i * 128))k 96k
+ done
+
+ for i in $(seq 0 14; seq 16 30; seq 32 47); do
+ local cur_sec=$(( i * 2 + 1 ))
+ local pattern=$(( ( (cur_sec % 128) + (cur_sec / 128)) % 128 ))
+
+ echo read -P $pattern $((i * 128 + 96))k 32k
+ done
+}
+
+verify_io | $QEMU_IO $TEST_IMG | _filter_qemu_io
+
+_check_test_img
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
--- /dev/null
+QA output created by 038
+
+== creating backing file for COW tests ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+qemu-io> wrote 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 65536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 131072
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 196608
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 262144
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 327680
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 393216
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 458752
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 524288
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 589824
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 655360
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 720896
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 786432
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 851968
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 917504
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 983040
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1048576
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1114112
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1179648
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1245184
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1310720
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1376256
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1441792
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1507328
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1572864
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1638400
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1703936
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1769472
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1835008
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1900544
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 1966080
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2031616
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2097152
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2162688
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2228224
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2293760
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2359296
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2424832
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2490368
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2555904
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2621440
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2686976
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2752512
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2818048
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2883584
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 2949120
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3014656
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3080192
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3145728
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3211264
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3276800
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3342336
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3407872
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3473408
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3538944
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3604480
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3670016
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3735552
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3801088
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3866624
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3932160
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 3997696
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4063232
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4128768
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4194304
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4259840
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4325376
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4390912
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4456448
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4521984
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4587520
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4653056
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4718592
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4784128
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4849664
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4915200
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 4980736
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5046272
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5111808
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5177344
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5242880
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5308416
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5373952
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5439488
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5505024
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5570560
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5636096
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5701632
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5767168
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5832704
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5898240
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 5963776
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6029312
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6094848
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6160384
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6225920
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6291456
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6356992
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6422528
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6488064
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6553600
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6619136
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6684672
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6750208
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6815744
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6881280
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 6946816
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7012352
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7077888
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7143424
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7208960
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7274496
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7340032
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7405568
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7471104
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7536640
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7602176
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7667712
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7733248
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7798784
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7864320
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7929856
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 7995392
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8060928
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8126464
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8192000
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8257536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8323072
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8388608
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8454144
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8519680
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8585216
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8650752
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8716288
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8781824
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8847360
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8912896
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 8978432
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9043968
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9109504
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9175040
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9240576
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9306112
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9371648
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9437184
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9502720
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9568256
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9633792
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9699328
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9764864
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9830400
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9895936
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 9961472
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10027008
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10092544
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10158080
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10223616
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10289152
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10354688
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10420224
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10485760
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10551296
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10616832
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10682368
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10747904
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10813440
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10878976
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 10944512
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11010048
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11075584
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11141120
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11206656
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11272192
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11337728
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11403264
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11468800
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11534336
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11599872
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11665408
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11730944
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11796480
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11862016
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11927552
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 11993088
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12058624
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12124160
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12189696
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12255232
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12320768
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12386304
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12451840
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12517376
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12582912
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12648448
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12713984
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12779520
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12845056
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12910592
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 12976128
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13041664
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13107200
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13172736
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13238272
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13303808
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13369344
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13434880
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13500416
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13565952
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13631488
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13697024
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13762560
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13828096
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13893632
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 13959168
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14024704
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14090240
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14155776
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14221312
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14286848
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14352384
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14417920
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14483456
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14548992
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14614528
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14680064
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14745600
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14811136
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14876672
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 14942208
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15007744
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15073280
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15138816
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15204352
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15269888
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15335424
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15400960
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15466496
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15532032
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15597568
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15663104
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15728640
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15794176
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15859712
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15925248
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 15990784
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16056320
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16121856
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16187392
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16252928
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16318464
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16384000
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16449536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16515072
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16580608
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16646144
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> wrote 65536/65536 bytes at offset 16711680
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base'
+
+== Some concurrent requests touching the same cluster ==
+qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> wrote 81920/81920 bytes at offset XXX
+80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 65536/65536 bytes at offset XXX
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 81920/81920 bytes at offset XXX
+80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Verify image content ==
+qemu-io> read 4096/4096 bytes at offset 2064384
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 81920/81920 bytes at offset 2068480
+80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 12288/12288 bytes at offset 2150400
+12 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 65536/65536 bytes at offset 2162688
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 16384/16384 bytes at offset 4161536
+16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 81920/81920 bytes at offset 4177920
+80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 65536/65536 bytes at offset 4259840
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 0
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 131072
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 262144
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 393216
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 524288
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 655360
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 786432
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 917504
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1048576
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1179648
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1310720
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1441792
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1572864
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1703936
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1835008
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 1966080
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 2228224
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 2359296
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 2490368
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 2621440
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 2752512
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 2883584
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3014656
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3145728
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3276800
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3407872
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3538944
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3670016
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3801088
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 3932160
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 4063232
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 4325376
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 4456448
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 4587520
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 4718592
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 4849664
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 4980736
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 5111808
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 5242880
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 5373952
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 5505024
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 5636096
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 5767168
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 5898240
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 6029312
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 98304/98304 bytes at offset 6160384
+96 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 98304
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 229376
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 360448
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 491520
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 622592
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 753664
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 884736
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1015808
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1146880
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1277952
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1409024
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1540096
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1671168
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1802240
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 1933312
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 2195456
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 2326528
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 2457600
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 2588672
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 2719744
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 2850816
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 2981888
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 3112960
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 3244032
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 3375104
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 3506176
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 3637248
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 3768320
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 3899392
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 4030464
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 4292608
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 4423680
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 4554752
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 4685824
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 4816896
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 4947968
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5079040
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5210112
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5341184
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5472256
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5603328
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5734400
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5865472
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 5996544
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 6127616
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> read 32768/32768 bytes at offset 6258688
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-io> No errors were found on the image.
+*** done
033 rw auto
034 rw auto backing
035 rw auto quick
+036 rw auto quick
+037 rw auto backing
+038 rw auto backing
self._qemu_log_path = os.path.join(test_dir, 'qemu-log.%d' % os.getpid())
self._args = qemu_args + ['-chardev',
'socket,id=mon,path=' + self._monitor_path,
- '-mon', 'chardev=mon,mode=control', '-nographic']
+ '-mon', 'chardev=mon,mode=control',
+ '-qtest', 'stdio', '-machine', 'accel=qtest',
+ '-display', 'none', '-vga', 'none']
self._num_drives = 0
def add_drive(self, path, opts=''):
h.update(fd)
+def cmd_set_feature_bit(fd, group, bit):
+ try:
+ bit = int(bit, 0)
+ if bit < 0 or bit >= 64:
+ raise ValueError
+ except:
+ print "'%s' is not a valid bit number in range [0, 64)" % bit
+ sys.exit(1)
+
+ h = QcowHeader(fd)
+ if group == 'incompatible':
+ h.incompatible_features |= 1 << bit
+ elif group == 'compatible':
+ h.compatible_features |= 1 << bit
+ elif group == 'autoclear':
+ h.autoclear_features |= 1 << bit
+ else:
+ print "'%s' is not a valid group, try 'incompatible', 'compatible', or 'autoclear'" % group
+ sys.exit(1)
+
+ h.update(fd)
+
cmds = [
[ 'dump-header', cmd_dump_header, 0, 'Dump image header and header extensions' ],
[ 'add-header-ext', cmd_add_header_ext, 2, 'Add a header extension' ],
[ 'del-header-ext', cmd_del_header_ext, 1, 'Delete a header extension' ],
+ [ 'set-feature-bit', cmd_set_feature_bit, 2, 'Set a feature bit'],
]
def main(filename, cmd, args):
# monitor.c
handle_qmp_command(void *mon, const char *cmd_name) "mon %p cmd_name \"%s\""
monitor_protocol_emitter(void *mon) "mon %p"
+monitor_protocol_event(uint32_t event, const char *evname, void *data) "event=%d name \"%s\" data %p"
+monitor_protocol_event_handler(uint32_t event, void *data, uint64_t last, uint64_t now) "event=%d data=%p last=%" PRId64 " now=%" PRId64
+monitor_protocol_event_emit(uint32_t event, void *data) "event=%d data=%p"
+monitor_protocol_event_queue(uint32_t event, void *data, uint64_t rate, uint64_t last, uint64_t now) "event=%d data=%p rate=%" PRId64 " last=%" PRId64 " now=%" PRId64
+monitor_protocol_event_throttle(uint32_t event, uint64_t rate) "event=%d rate=%" PRId64
# hw/opencores_eth.c
open_eth_mii_write(unsigned idx, uint16_t v) "MII[%02x] <- %04x"
}
loc_set_none();
+ if (machine->hw_version) {
+ qemu_set_version(machine->hw_version);
+ }
+
/* Init CPU def lists, based on config
* - Must be called after all the qemu_read_config_file() calls
* - Must be called before list_cpus()