summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile5
-rw-r--r--block.c16
-rw-r--r--block/blkdebug.c4
-rw-r--r--block/blkverify.c2
-rw-r--r--block/curl.c2
-rw-r--r--block/gluster.c2
-rw-r--r--block/iscsi.c2
-rw-r--r--block/nbd.c2
-rw-r--r--block/qapi.c4
-rw-r--r--block/qcow2.c6
-rw-r--r--block/raw-posix.c12
-rw-r--r--block/raw-win32.c4
-rw-r--r--block/raw_bsd.c2
-rw-r--r--block/rbd.c2
-rw-r--r--block/sheepdog.c2
-rw-r--r--block/snapshot.c2
-rw-r--r--block/vvfat.c2
-rw-r--r--blockdev.c46
-rw-r--r--blockjob.c4
-rwxr-xr-xconfigure62
-rw-r--r--default-configs/ppc-softmmu.mak1
-rw-r--r--default-configs/ppc64-softmmu.mak1
-rw-r--r--default-configs/ppcemb-softmmu.mak20
-rw-r--r--disas/i386.c146
-rw-r--r--docs/tracing.txt36
-rw-r--r--fpu/softfloat.c38
-rw-r--r--hmp.c11
-rw-r--r--hw/Makefile.objs1
-rw-r--r--hw/acpi/piix4.c6
-rw-r--r--hw/arm/exynos4210.c2
-rw-r--r--hw/arm/musicpal.c4
-rw-r--r--hw/arm/nseries.c2
-rw-r--r--hw/arm/pxa2xx.c80
-rw-r--r--hw/arm/pxa2xx_pic.c11
-rw-r--r--hw/arm/realview.c4
-rw-r--r--hw/arm/spitz.c2
-rw-r--r--hw/arm/stellaris.c8
-rw-r--r--hw/arm/tosa.c18
-rw-r--r--hw/arm/versatilepb.c4
-rw-r--r--hw/arm/z2.c22
-rw-r--r--hw/audio/adlib.c2
-rw-r--r--hw/audio/cs4231a.c2
-rw-r--r--hw/audio/gus.c2
-rw-r--r--hw/audio/pcspk.c2
-rw-r--r--hw/audio/sb16.c4
-rw-r--r--hw/audio/wm8750.c33
-rw-r--r--hw/block/fdc.c2
-rw-r--r--hw/block/nand.c2
-rw-r--r--hw/char/Makefile.objs2
-rw-r--r--hw/char/debugcon.c4
-rw-r--r--hw/char/ipoctal232.c20
-rw-r--r--hw/char/parallel.c2
-rw-r--r--hw/char/serial-isa.c2
-rw-r--r--hw/core/qdev-properties-system.c12
-rw-r--r--hw/core/qdev-properties.c204
-rw-r--r--hw/core/qdev.c38
-rw-r--r--hw/display/g364fb.c2
-rw-r--r--hw/display/ssd0303.c18
-rw-r--r--hw/display/tcx.c4
-rw-r--r--hw/dma/i82374.c2
-rw-r--r--hw/dma/sun4m_iommu.c2
-rw-r--r--hw/gpio/max7310.c23
-rw-r--r--hw/i2c/bitbang_i2c.c6
-rw-r--r--hw/i2c/bitbang_i2c.h2
-rw-r--r--hw/i2c/core.c32
-rw-r--r--hw/i2c/exynos4210_i2c.c2
-rw-r--r--hw/i2c/omap_i2c.c4
-rw-r--r--hw/i2c/pm_smbus.c2
-rw-r--r--hw/i2c/smbus.c18
-rw-r--r--hw/i2c/smbus_eeprom.c2
-rw-r--r--hw/i2c/smbus_ich9.c2
-rw-r--r--hw/i2c/versatile_i2c.c2
-rw-r--r--hw/i386/kvm/i8254.c8
-rw-r--r--hw/i386/pc_piix.c2
-rw-r--r--hw/ide/isa.c4
-rw-r--r--hw/ide/qdev.c2
-rw-r--r--hw/input/lm832x.c22
-rw-r--r--hw/intc/arm_gic.c2
-rw-r--r--hw/intc/i8259_common.c6
-rw-r--r--hw/ipack/Makefile.objs2
-rw-r--r--hw/ipack/ipack.c (renamed from hw/char/ipack.c)43
-rw-r--r--hw/ipack/tpci200.c (renamed from hw/char/tpci200.c)2
-rw-r--r--hw/isa/pc87312.c2
-rw-r--r--hw/isa/vt82c686.c4
-rw-r--r--hw/mips/mips_fulong2e.c2
-rw-r--r--hw/mips/mips_malta.c2
-rw-r--r--hw/misc/applesmc.c2
-rw-r--r--hw/misc/debugexit.c4
-rw-r--r--hw/misc/eccmemctl.c2
-rw-r--r--hw/net/ne2000-isa.c2
-rw-r--r--hw/nvram/fw_cfg.c4
-rw-r--r--hw/pci/pci-hotplug-old.c4
-rw-r--r--hw/ppc/Makefile.objs4
-rw-r--r--hw/ppc/spapr_pci.c16
-rw-r--r--hw/scsi/megasas.c2
-rw-r--r--hw/scsi/scsi-disk.c6
-rw-r--r--hw/sd/sdhci.c4
-rw-r--r--hw/timer/ds1338.c21
-rw-r--r--hw/timer/i8254.c2
-rw-r--r--hw/timer/m48t59.c4
-rw-r--r--hw/timer/mc146818rtc.c14
-rw-r--r--hw/timer/twl92230.c35
-rw-r--r--hw/usb/desc.c2
-rw-r--r--hw/usb/dev-audio.c2
-rw-r--r--hw/usb/dev-bluetooth.c2
-rw-r--r--hw/usb/dev-hid.c8
-rw-r--r--hw/usb/dev-hub.c3
-rw-r--r--hw/usb/dev-network.c6
-rw-r--r--hw/usb/dev-serial.c2
-rw-r--r--hw/usb/dev-smartcard-reader.c3
-rw-r--r--hw/usb/dev-storage.c6
-rw-r--r--hw/usb/dev-uas.c4
-rw-r--r--hw/usb/dev-wacom.c2
-rw-r--r--hw/usb/hcd-uhci.c2
-rw-r--r--hw/usb/hcd-xhci.c102
-rw-r--r--hw/usb/host-libusb.c4
-rw-r--r--hw/virtio/virtio-pci.c6
-rw-r--r--include/fpu/softfloat.h3
-rw-r--r--include/hw/arm/exynos4210.h2
-rw-r--r--include/hw/arm/omap.h2
-rw-r--r--include/hw/arm/pxa.h2
-rw-r--r--include/hw/block/block.h6
-rw-r--r--include/hw/i2c/i2c.h20
-rw-r--r--include/hw/i2c/pm_smbus.h2
-rw-r--r--include/hw/i2c/smbus.h20
-rw-r--r--include/hw/i386/ich9.h2
-rw-r--r--include/hw/i386/pc.h6
-rw-r--r--include/hw/ipack/ipack.h (renamed from hw/char/ipack.h)15
-rw-r--r--include/hw/isa/vt82c686.h4
-rw-r--r--include/hw/qdev-core.h1
-rw-r--r--include/hw/qdev-dma.h2
-rw-r--r--include/hw/qdev-properties.h11
-rw-r--r--include/hw/usb.h5
-rw-r--r--include/qapi/string-output-visitor.h2
-rw-r--r--include/qemu-common.h8
-rw-r--r--include/qemu/typedefs.h2
-rw-r--r--include/qom/object.h3
-rw-r--r--include/sysemu/qtest.h3
-rw-r--r--linux-user/alpha/syscall_nr.h7
-rw-r--r--linux-user/arm/syscall_nr.h6
-rw-r--r--linux-user/cris/syscall_nr.h1
-rw-r--r--linux-user/elfload.c16
-rw-r--r--linux-user/i386/syscall_nr.h6
-rw-r--r--linux-user/ioctls.h1
-rw-r--r--linux-user/m68k/syscall_nr.h5
-rw-r--r--linux-user/main.c6
-rw-r--r--linux-user/microblaze/syscall_nr.h7
-rw-r--r--linux-user/mips/syscall_nr.h6
-rw-r--r--linux-user/mips64/syscall_nr.h13
-rw-r--r--linux-user/openrisc/syscall_nr.h6
-rw-r--r--linux-user/ppc/syscall_nr.h6
-rw-r--r--linux-user/s390x/syscall_nr.h7
-rw-r--r--linux-user/sh4/syscall_nr.h6
-rw-r--r--linux-user/signal.c1
-rw-r--r--linux-user/sparc/syscall_nr.h7
-rw-r--r--linux-user/sparc64/syscall_nr.h7
-rw-r--r--linux-user/syscall.c20
-rw-r--r--linux-user/syscall_defs.h1
-rw-r--r--linux-user/syscall_types.h13
-rw-r--r--linux-user/x86_64/syscall_nr.h7
-rw-r--r--monitor.c95
-rw-r--r--net/net.c12
-rw-r--r--qapi-schema.json80
-rw-r--r--qapi/string-input-visitor.c24
-rw-r--r--qapi/string-output-visitor.c56
-rw-r--r--qdev-monitor.c8
-rw-r--r--qemu-char.c25
-rw-r--r--qemu-img.c8
-rw-r--r--qga/commands-posix.c18
-rw-r--r--qga/commands-win32.c2
-rw-r--r--qmp-commands.hx41
-rw-r--r--qom/object.c4
-rw-r--r--qtest.c8
-rw-r--r--savevm.c4
-rwxr-xr-xscripts/qmp/qmp-shell3
-rw-r--r--scripts/tracetool/backend/ust.py101
-rw-r--r--scripts/tracetool/format/ust_events_c.py30
-rw-r--r--scripts/tracetool/format/ust_events_h.py57
-rw-r--r--target-arm/cpu.c8
-rw-r--r--target-arm/cpu.h105
-rw-r--r--target-arm/helper-a64.c105
-rw-r--r--target-arm/helper-a64.h9
-rw-r--r--target-arm/helper.c620
-rw-r--r--target-arm/helper.h3
-rw-r--r--target-arm/kvm-consts.h16
-rw-r--r--target-arm/neon_helper.c16
-rw-r--r--target-arm/op_helper.c46
-rw-r--r--target-arm/translate-a64.c1316
-rw-r--r--target-arm/translate.c28
-rw-r--r--target-i386/translate.c2
-rw-r--r--target-ppc/translate_init.c38
-rw-r--r--tcg/arm/tcg-target.c2
-rw-r--r--tcg/i386/tcg-target.c160
-rw-r--r--tcg/i386/tcg-target.h9
-rw-r--r--tcg/optimize.c165
-rw-r--r--tcg/tcg.c2
-rw-r--r--tests/Makefile85
-rw-r--r--tests/e1000-test.c33
-rw-r--r--tests/eepro100-test.c63
-rw-r--r--tests/endianness-test.c2
-rw-r--r--tests/fw_cfg-test.c7
-rw-r--r--tests/i440fx-test.c11
-rw-r--r--tests/ipoctal232-test.c33
-rw-r--r--tests/libqtest.c59
-rw-r--r--tests/m48t59-test.c3
-rw-r--r--tests/ne2000-test.c33
-rw-r--r--tests/pcnet-test.c33
-rw-r--r--tests/qom-test.c292
-rw-r--r--tests/rtc-test.c5
-rw-r--r--tests/rtl8139-test.c33
-rw-r--r--tests/test-qmp-input-strict.c16
-rw-r--r--tests/test-qmp-input-visitor.c20
-rw-r--r--tests/test-qmp-output-visitor.c22
-rw-r--r--tests/test-string-input-visitor.c20
-rw-r--r--tests/test-string-output-visitor.c16
-rw-r--r--tests/test-visitor-serialization.c2
-rw-r--r--tests/tmp105-test.c5
-rw-r--r--tests/tpci200-test.c33
-rw-r--r--tests/virtio-net-test.c33
-rw-r--r--tests/vmxnet3-test.c33
-rw-r--r--tpm.c2
-rw-r--r--trace-events8
-rw-r--r--trace/Makefile.objs25
-rw-r--r--util/qemu-config.c16
-rw-r--r--util/qemu-option.c22
-rw-r--r--vl.c32
227 files changed, 4097 insertions, 1843 deletions
diff --git a/.gitignore b/.gitignore
index 6e74d63..ef7019f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,8 @@
/trace/generated-tracers.dtrace
/trace/generated-events.h
/trace/generated-events.c
+/trace/generated-ust-provider.h
+/trace/generated-ust.c
/libcacard/trace/generated-tracers.c
*-timestamp
/*-softmmu
diff --git a/Makefile b/Makefile
index 992cd23..a28a3c8 100644
--- a/Makefile
+++ b/Makefile
@@ -57,6 +57,11 @@ GENERATED_HEADERS += trace/generated-tracers-dtrace.h
endif
GENERATED_SOURCES += trace/generated-tracers.c
+ifeq ($(TRACE_BACKEND),ust)
+GENERATED_HEADERS += trace/generated-ust-provider.h
+GENERATED_SOURCES += trace/generated-ust.c
+endif
+
# Don't try to regenerate Makefile or configure
# We don't generate any of them
Makefile: ;
diff --git a/block.c b/block.c
index 8f718f9..6f4baca 100644
--- a/block.c
+++ b/block.c
@@ -421,7 +421,7 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
assert(cco->drv);
ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(&cco->err, local_err);
}
cco->ret = ret;
@@ -460,7 +460,7 @@ int bdrv_create(BlockDriver *drv, const char* filename,
ret = cco.ret;
if (ret < 0) {
- if (error_is_set(&cco.err)) {
+ if (cco.err) {
error_propagate(errp, cco.err);
} else {
error_setg_errno(errp, -ret, "Could not create image");
@@ -486,7 +486,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
}
ret = bdrv_create(drv, filename, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
}
return ret;
@@ -916,7 +916,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
}
if (ret < 0) {
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
} else if (bs->filename[0]) {
error_setg_errno(errp, -ret, "Could not open '%s'", bs->filename);
@@ -1037,7 +1037,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
/* Parse the filename and open it */
if (drv->bdrv_parse_filename && filename) {
drv->bdrv_parse_filename(filename, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
@@ -1406,7 +1406,7 @@ fail:
QDECREF(bs->options);
QDECREF(options);
bs->options = NULL;
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
}
return ret;
@@ -1414,7 +1414,7 @@ fail:
close_and_fail:
bdrv_close(bs);
QDECREF(options);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
}
return ret;
@@ -5340,7 +5340,7 @@ out:
free_option_parameters(create_options);
free_option_parameters(param);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
}
}
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 8eb0db0..ee10013 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -303,7 +303,7 @@ static int read_config(BDRVBlkdebugState *s, const char *filename,
}
qemu_config_parse_qdict(options, config_groups, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
@@ -393,7 +393,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto out;
diff --git a/block/blkverify.c b/block/blkverify.c
index cfcbcf4..1563c88 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -128,7 +128,7 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
diff --git a/block/curl.c b/block/curl.c
index a807584..bb1fc4a 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -463,7 +463,7 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
goto out_noclean;
diff --git a/block/gluster.c b/block/gluster.c
index a009b15..58eab07 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -282,7 +282,7 @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
ret = -EINVAL;
diff --git a/block/iscsi.c b/block/iscsi.c
index c97c040..f8e496f 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1127,7 +1127,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
ret = -EINVAL;
diff --git a/block/nbd.c b/block/nbd.c
index 327e913..abae506 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -209,7 +209,7 @@ static int nbd_config(BDRVNBDState *s, QDict *options, char **export)
&error_abort);
qemu_opts_absorb_qdict(s->socket_opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return -EINVAL;
diff --git a/block/qapi.c b/block/qapi.c
index 8f4134b..8f2b4db 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -271,7 +271,7 @@ void bdrv_query_info(BlockDriverState *bs,
p_image_info = &info->inserted->image;
while (1) {
bdrv_query_image_info(bs0, p_image_info, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
goto err;
}
@@ -336,7 +336,7 @@ BlockInfoList *qmp_query_block(Error **errp)
while ((bs = bdrv_next(bs))) {
BlockInfoList *info = g_malloc0(sizeof(*info));
bdrv_query_info(bs, &info->value, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
goto err;
}
diff --git a/block/qcow2.c b/block/qcow2.c
index 0b4335c..b1dbdb1 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -671,7 +671,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
/* Enable lazy_refcounts according to image and command line options */
opts = qemu_opts_create(&qcow2_runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
@@ -1605,7 +1605,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
ret = bdrv_open(bs, filename, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_BACKING,
drv, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
goto out;
}
@@ -1685,7 +1685,7 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options,
ret = qcow2_create2(filename, sectors, backing_file, backing_fmt, flags,
cluster_size, prealloc, options, version, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
}
return ret;
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 126a634..161ea14 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -361,7 +361,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
@@ -448,7 +448,7 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
s->type = FTYPE_FILE;
ret = raw_open_common(bs, options, flags, 0, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
}
return ret;
@@ -1597,7 +1597,7 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
ret = raw_open_common(bs, options, flags, 0, &local_err);
if (ret < 0) {
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
}
return ret;
@@ -1832,7 +1832,7 @@ static int floppy_open(BlockDriverState *bs, QDict *options, int flags,
/* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
ret = raw_open_common(bs, options, flags, O_NONBLOCK, &local_err);
if (ret) {
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
}
return ret;
@@ -1961,7 +1961,7 @@ static int cdrom_open(BlockDriverState *bs, QDict *options, int flags,
/* open will not fail even if no CD is inserted, so add O_NONBLOCK */
ret = raw_open_common(bs, options, flags, O_NONBLOCK, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
}
return ret;
@@ -2078,7 +2078,7 @@ static int cdrom_open(BlockDriverState *bs, QDict *options, int flags,
ret = raw_open_common(bs, options, flags, 0, &local_err);
if (ret) {
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
}
return ret;
diff --git a/block/raw-win32.c b/block/raw-win32.c
index beb7f23..ae1c8e6 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -279,7 +279,7 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
@@ -594,7 +594,7 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
QemuOpts *opts = qemu_opts_create(&raw_runtime_opts, NULL, 0,
&error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto done;
diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index af8706d..01ea692 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -146,7 +146,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
int ret;
ret = bdrv_create_file(filename, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
}
return ret;
diff --git a/block/rbd.c b/block/rbd.c
index 121fae2..dbc79f4 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -440,7 +440,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
qemu_opts_del(opts);
diff --git a/block/sheepdog.c b/block/sheepdog.c
index 672b9c9..e6c0376 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -1385,7 +1385,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
ret = -EINVAL;
diff --git a/block/snapshot.c b/block/snapshot.c
index 9047f8d..85c52ff 100644
--- a/block/snapshot.c
+++ b/block/snapshot.c
@@ -345,7 +345,7 @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
ret = bdrv_snapshot_load_tmp(bs, NULL, id_or_name, &local_err);
}
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
}
diff --git a/block/vvfat.c b/block/vvfat.c
index 664941c..a19e4ca 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1085,7 +1085,7 @@ DLOG(if (stderr == NULL) {
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
ret = -EINVAL;
diff --git a/blockdev.c b/blockdev.c
index dfb5ec7..3cc8cda 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -330,13 +330,13 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
* stay in bs_opts for processing by bdrv_open(). */
id = qdict_get_try_str(bs_opts, "id");
opts = qemu_opts_create(&qemu_common_drive_opts, id, 1, &error);
- if (error_is_set(&error)) {
+ if (error) {
error_propagate(errp, error);
return NULL;
}
qemu_opts_absorb_qdict(opts, bs_opts, &error);
- if (error_is_set(&error)) {
+ if (error) {
error_propagate(errp, error);
goto early_err;
}
@@ -437,7 +437,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
on_write_error = parse_block_error_action(buf, 0, &error);
- if (error_is_set(&error)) {
+ if (error) {
error_propagate(errp, error);
goto early_err;
}
@@ -446,7 +446,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
on_read_error = BLOCKDEV_ON_ERROR_REPORT;
if ((buf = qemu_opt_get(opts, "rerror")) != NULL) {
on_read_error = parse_block_error_action(buf, 1, &error);
- if (error_is_set(&error)) {
+ if (error) {
error_propagate(errp, error);
goto early_err;
}
@@ -691,7 +691,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
legacy_opts = qemu_opts_create(&qemu_legacy_drive_opts, NULL, 0,
&error_abort);
qemu_opts_absorb_qdict(legacy_opts, bs_opts, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
goto fail;
@@ -779,6 +779,10 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
translation = BIOS_ATA_TRANSLATION_NONE;
} else if (!strcmp(value, "lba")) {
translation = BIOS_ATA_TRANSLATION_LBA;
+ } else if (!strcmp(value, "large")) {
+ translation = BIOS_ATA_TRANSLATION_LARGE;
+ } else if (!strcmp(value, "rechs")) {
+ translation = BIOS_ATA_TRANSLATION_RECHS;
} else if (!strcmp(value, "auto")) {
translation = BIOS_ATA_TRANSLATION_AUTO;
} else {
@@ -899,13 +903,13 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
/* Actual block device init: Functionality shared with blockdev-add */
dinfo = blockdev_init(filename, bs_opts, &local_err);
if (dinfo == NULL) {
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
}
goto fail;
} else {
- assert(!error_is_set(&local_err));
+ assert(!local_err);
}
/* Set legacy DriveInfo fields */
@@ -1042,7 +1046,7 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
}
ret = bdrv_snapshot_find_by_id_and_name(bs, id, name, &sn, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return NULL;
}
@@ -1055,7 +1059,7 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
}
bdrv_snapshot_delete(bs, id, name, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return NULL;
}
@@ -1269,7 +1273,7 @@ static void external_snapshot_prepare(BlkTransactionState *common,
state->old_bs = bdrv_lookup_bs(has_device ? device : NULL,
has_node_name ? node_name : NULL,
&local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return;
}
@@ -1314,7 +1318,7 @@ static void external_snapshot_prepare(BlkTransactionState *common,
state->old_bs->filename,
state->old_bs->drv->format_name,
NULL, -1, flags, &local_err, false);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return;
}
@@ -1383,7 +1387,7 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
backup->has_on_source_error, backup->on_source_error,
backup->has_on_target_error, backup->on_target_error,
&local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
state->bs = NULL;
state->job = NULL;
@@ -1475,7 +1479,7 @@ void qmp_transaction(TransactionActionList *dev_list, Error **errp)
QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, state, entry);
state->ops->prepare(state, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
goto delete_and_fail;
}
@@ -1556,7 +1560,7 @@ void qmp_block_passwd(bool has_device, const char *device,
bs = bdrv_lookup_bs(has_device ? device : NULL,
has_node_name ? node_name : NULL,
&local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return;
}
@@ -1621,7 +1625,7 @@ void qmp_change_blockdev(const char *device, const char *filename,
}
eject_device(bs, 0, &err);
- if (error_is_set(&err)) {
+ if (err) {
error_propagate(errp, err);
return;
}
@@ -1758,7 +1762,7 @@ void qmp_block_resize(bool has_device, const char *device,
bs = bdrv_lookup_bs(has_device ? device : NULL,
has_node_name ? node_name : NULL,
&local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return;
}
@@ -1851,7 +1855,7 @@ void qmp_block_stream(const char *device, bool has_base,
stream_start(bs, base_bs, base, has_speed ? speed : 0,
on_error, block_job_cb, bs, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return;
}
@@ -2009,7 +2013,7 @@ void qmp_drive_backup(const char *device, const char *target,
}
}
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return;
}
@@ -2150,7 +2154,7 @@ void qmp_drive_mirror(const char *device, const char *target,
}
}
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return;
}
@@ -2289,7 +2293,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
visit_type_BlockdevOptions(qmp_output_get_visitor(ov),
&options, NULL, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
goto fail;
}
@@ -2300,7 +2304,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
qdict_flatten(qdict);
blockdev_init(NULL, qdict, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
goto fail;
}
diff --git a/blockjob.c b/blockjob.c
index 9e5fd5c..b3ce14c 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -61,7 +61,7 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
Error *local_err = NULL;
block_job_set_speed(job, speed, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
bs->job = NULL;
g_free(job);
bdrv_set_in_use(bs, 0);
@@ -92,7 +92,7 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
return;
}
job->driver->set_speed(job, speed, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return;
}
diff --git a/configure b/configure
index 46b5b6d..00f9070 100755
--- a/configure
+++ b/configure
@@ -1331,6 +1331,35 @@ else
error_exit "\"$cc\" either does not exist or does not work"
fi
+# Check that the C++ compiler exists and works with the C compiler
+if has $cxx; then
+ cat > $TMPC <<EOF
+int c_function(void);
+int main(void) { return c_function(); }
+EOF
+
+ compile_object
+
+ cat > $TMPC <<EOF
+extern "C" {
+ int c_function(void);
+}
+int c_function(void) { return 42; }
+EOF
+
+ if (cc=$cxx do_cc $QEMU_CFLAGS -o $TMPE $TMPC $TMPO $LDFLAGS); then
+ # C++ compiler $cxx works ok with C compiler $cc
+ :
+ else
+ echo "C++ compiler $cxx does not work with C compiler $cc"
+ echo "Disabling C++ specific optional code"
+ cxx=
+ fi
+else
+ echo "No C++ compiler available; disabling C++ specific optional code"
+ cxx=
+fi
+
# Consult white-list to determine whether to enable werror
# by default. Only enable by default for git builds
z_version=`cut -f3 -d. $source_path/VERSION`
@@ -3452,15 +3481,25 @@ fi
# For 'ust' backend, test if ust headers are present
if test "$trace_backend" = "ust"; then
cat > $TMPC << EOF
-#include <ust/tracepoint.h>
-#include <ust/marker.h>
+#include <lttng/tracepoint.h>
int main(void) { return 0; }
EOF
if compile_prog "" "" ; then
- LIBS="-lust -lurcu-bp $LIBS"
- libs_qga="-lust -lurcu-bp $libs_qga"
+ if $pkg_config lttng-ust --exists; then
+ lttng_ust_libs=`$pkg_config --libs lttng-ust`
+ else
+ lttng_ust_libs="-llttng-ust"
+ fi
+ if $pkg_config liburcu-bp --exists; then
+ urcu_bp_libs=`$pkg_config --libs liburcu-bp`
+ else
+ urcu_bp_libs="-lurcu-bp"
+ fi
+
+ LIBS="$lttng_ust_libs $urcu_bp_libs $LIBS"
+ libs_qga="$lttng_ust_libs $urcu_bp_libs $libs_qga"
else
- error_exit "Trace backend 'ust' missing libust header files"
+ error_exit "Trace backend 'ust' missing lttng-ust header files"
fi
fi
@@ -3637,7 +3676,18 @@ cpuid_h=no
cat > $TMPC << EOF
#include <cpuid.h>
int main(void) {
- return 0;
+ unsigned a, b, c, d;
+ int max = __get_cpuid_max(0, 0);
+
+ if (max >= 1) {
+ __cpuid(1, a, b, c, d);
+ }
+
+ if (max >= 7) {
+ __cpuid_count(7, 0, a, b, c, d);
+ }
+
+ return 0;
}
EOF
if compile_prog "" "" ; then
diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index f380ca4..e5f9d36 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -42,6 +42,7 @@ CONFIG_XILINX=y
CONFIG_XILINX_ETHLITE=y
CONFIG_OPENPIC=y
CONFIG_PREP=y
+CONFIG_MAC=y
CONFIG_E500=y
CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
# For PReP
diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
index fcc0452..e2beac6 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -43,6 +43,7 @@ CONFIG_XILINX_ETHLITE=y
CONFIG_OPENPIC=y
CONFIG_PSERIES=y
CONFIG_PREP=y
+CONFIG_MAC=y
CONFIG_E500=y
CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
# For pSeries
diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak
index fdf1e14..1e4fde2 100644
--- a/default-configs/ppcemb-softmmu.mak
+++ b/default-configs/ppcemb-softmmu.mak
@@ -3,30 +3,12 @@
include pci.mak
include sound.mak
include usb.mak
-CONFIG_ISA_MMIO=y
-CONFIG_ESCC=y
CONFIG_M48T59=y
CONFIG_VGA=y
CONFIG_VGA_PCI=y
CONFIG_SERIAL=y
-CONFIG_I8254=y
-CONFIG_FDC=y
CONFIG_I8257=y
CONFIG_OPENPIC=y
-CONFIG_MACIO=y
-CONFIG_CUDA=y
-CONFIG_ADB=y
-CONFIG_MAC_NVRAM=y
-CONFIG_MAC_DBDMA=y
-CONFIG_HEATHROW_PIC=y
-CONFIG_GRACKLE_PCI=y
-CONFIG_UNIN_PCI=y
-CONFIG_DEC_PCI=y
-CONFIG_PPCE500_PCI=y
-CONFIG_IDE_ISA=y
-CONFIG_IDE_CMD646=y
-CONFIG_IDE_MACIO=y
-CONFIG_NE2000_ISA=y
CONFIG_PFLASH_CFI01=y
CONFIG_PFLASH_CFI02=y
CONFIG_PTIMER=y
@@ -34,5 +16,3 @@ CONFIG_I8259=y
CONFIG_XILINX=y
CONFIG_XILINX_ETHLITE=y
CONFIG_OPENPIC=y
-CONFIG_E500=y
-CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
diff --git a/disas/i386.c b/disas/i386.c
index 044e02c..00ceca9 100644
--- a/disas/i386.c
+++ b/disas/i386.c
@@ -171,6 +171,7 @@ static void print_operand_value (char *buf, size_t bufsize, int hex, bfd_vma dis
static void print_displacement (char *, bfd_vma);
static void OP_E (int, int);
static void OP_G (int, int);
+static void OP_vvvv (int, int);
static bfd_vma get64 (void);
static bfd_signed_vma get32 (void);
static bfd_signed_vma get32s (void);
@@ -264,6 +265,9 @@ static int rex_used;
current instruction. */
static int used_prefixes;
+/* The VEX.vvvv register, unencoded. */
+static int vex_reg;
+
/* Flags stored in PREFIXES. */
#define PREFIX_REPZ 1
#define PREFIX_REPNZ 2
@@ -278,6 +282,10 @@ static int used_prefixes;
#define PREFIX_ADDR 0x400
#define PREFIX_FWAIT 0x800
+#define PREFIX_VEX_0F 0x1000
+#define PREFIX_VEX_0F38 0x2000
+#define PREFIX_VEX_0F3A 0x4000
+
/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
to ADDR (exclusive) are valid. Returns 1 for success, longjmps
on error. */
@@ -323,6 +331,7 @@ fetch_data(struct disassemble_info *info, bfd_byte *addr)
#define XX { NULL, 0 }
+#define Bv { OP_vvvv, v_mode }
#define Eb { OP_E, b_mode }
#define Ev { OP_E, v_mode }
#define Ed { OP_E, d_mode }
@@ -671,7 +680,8 @@ fetch_data(struct disassemble_info *info, bfd_byte *addr)
#define PREGRP102 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 102 } }
#define PREGRP103 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 103 } }
#define PREGRP104 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 104 } }
-
+#define PREGRP105 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 105 } }
+#define PREGRP106 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 106 } }
#define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
#define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
@@ -1449,7 +1459,7 @@ static const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
/* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
/* d0 */ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1, /* df */
/* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
- /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
+ /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
/* ------------------------------- */
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
};
@@ -1473,7 +1483,7 @@ static const unsigned char threebyte_0x38_uses_REPNZ_prefix[256] = {
/* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
/* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
/* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
- /* f0 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
+ /* f0 */ 1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
/* ------------------------------- */
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
};
@@ -1497,7 +1507,7 @@ static const unsigned char threebyte_0x38_uses_REPZ_prefix[256] = {
/* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
/* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
/* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
- /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
+ /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
/* ------------------------------- */
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
};
@@ -2774,6 +2784,22 @@ static const struct dis386 prefix_user_table[][4] = {
{ "(bad)", { XX } },
},
+ /* PREGRP105 */
+ {
+ { "andnS", { Gv, Bv, Ev } },
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREGRP106 */
+ {
+ { "bextrS", { Gv, Ev, Bv } },
+ { "sarxS", { Gv, Ev, Bv } },
+ { "shlxS", { Gv, Ev, Bv } },
+ { "shrxS", { Gv, Ev, Bv } },
+ },
+
};
static const struct dis386 x86_64_table[][2] = {
@@ -3071,12 +3097,12 @@ static const struct dis386 three_byte_table[][256] = {
/* f0 */
{ PREGRP87 },
{ PREGRP88 },
+ { PREGRP105 },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
+ { PREGRP106 },
/* f8 */
{ "(bad)", { XX } },
{ "(bad)", { XX } },
@@ -3477,6 +3503,74 @@ ckprefix (void)
}
}
+static void
+ckvexprefix (void)
+{
+ int op, vex2, vex3, newrex = 0, newpfx = prefixes;
+
+ if (address_mode == mode_16bit) {
+ return;
+ }
+
+ fetch_data(the_info, codep + 1);
+ op = *codep;
+
+ if (op != 0xc4 && op != 0xc5) {
+ return;
+ }
+
+ fetch_data(the_info, codep + 2);
+ vex2 = codep[1];
+
+ if (address_mode == mode_32bit && (vex2 & 0xc0) != 0xc0) {
+ return;
+ }
+
+ if (op == 0xc4) {
+ /* Three byte VEX prefix. */
+ fetch_data(the_info, codep + 3);
+ vex3 = codep[2];
+
+ newrex |= (vex2 & 0x80 ? 0 : REX_R);
+ newrex |= (vex2 & 0x40 ? 0 : REX_X);
+ newrex |= (vex2 & 0x20 ? 0 : REX_B);
+ newrex |= (vex3 & 0x80 ? REX_W : 0);
+ switch (vex2 & 0x1f) { /* VEX.m-mmmm */
+ case 1:
+ newpfx |= PREFIX_VEX_0F;
+ break;
+ case 2:
+ newpfx |= PREFIX_VEX_0F | PREFIX_VEX_0F38;
+ break;
+ case 3:
+ newpfx |= PREFIX_VEX_0F | PREFIX_VEX_0F3A;
+ break;
+ }
+ vex2 = vex3;
+ codep += 3;
+ } else {
+ /* Two byte VEX prefix. */
+ newrex |= (vex2 & 0x80 ? 0 : REX_R);
+ codep += 2;
+ }
+
+ vex_reg = (~vex2 >> 3) & 15; /* VEX.vvvv */
+ switch (vex2 & 3) { /* VEX.pp */
+ case 1:
+ newpfx |= PREFIX_DATA; /* 0x66 */
+ break;
+ case 2:
+ newpfx |= PREFIX_REPZ; /* 0xf3 */
+ break;
+ case 3:
+ newpfx |= PREFIX_REPNZ; /* 0xf2 */
+ break;
+ }
+
+ rex = newrex;
+ prefixes = newpfx;
+}
+
/* Return the name of the prefix byte PREF, or NULL if PREF is not a
prefix byte. */
@@ -3598,6 +3692,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
const char *p;
struct dis_private priv;
unsigned char op;
+ unsigned char threebyte;
if (info->mach == bfd_mach_x86_64_intel_syntax
|| info->mach == bfd_mach_x86_64)
@@ -3752,6 +3847,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
obufp = obuf;
ckprefix ();
+ ckvexprefix ();
insn_codep = codep;
sizeflag = priv.orig_sizeflag;
@@ -3775,18 +3871,29 @@ print_insn (bfd_vma pc, disassemble_info *info)
}
op = 0;
+ if (prefixes & PREFIX_VEX_0F)
+ {
+ used_prefixes |= PREFIX_VEX_0F | PREFIX_VEX_0F38 | PREFIX_VEX_0F3A;
+ if (prefixes & PREFIX_VEX_0F38)
+ threebyte = 0x38;
+ else if (prefixes & PREFIX_VEX_0F3A)
+ threebyte = 0x3a;
+ else
+ threebyte = *codep++;
+ goto vex_opcode;
+ }
if (*codep == 0x0f)
{
- unsigned char threebyte;
fetch_data(info, codep + 2);
- threebyte = *++codep;
+ threebyte = codep[1];
+ codep += 2;
+ vex_opcode:
dp = &dis386_twobyte[threebyte];
- need_modrm = twobyte_has_modrm[*codep];
- uses_DATA_prefix = twobyte_uses_DATA_prefix[*codep];
- uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[*codep];
- uses_REPZ_prefix = twobyte_uses_REPZ_prefix[*codep];
- uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
- codep++;
+ need_modrm = twobyte_has_modrm[threebyte];
+ uses_DATA_prefix = twobyte_uses_DATA_prefix[threebyte];
+ uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[threebyte];
+ uses_REPZ_prefix = twobyte_uses_REPZ_prefix[threebyte];
+ uses_LOCK_prefix = (threebyte & ~0x02) == 0x20;
if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
{
fetch_data(info, codep + 2);
@@ -5291,6 +5398,17 @@ OP_G (int bytemode, int sizeflag)
}
}
+static void
+OP_vvvv (int bytemode, int sizeflags)
+{
+ USED_REX (REX_W);
+ if (rex & REX_W) {
+ oappend(names64[vex_reg]);
+ } else {
+ oappend(names32[vex_reg]);
+ }
+}
+
static bfd_vma
get64 (void)
{
diff --git a/docs/tracing.txt b/docs/tracing.txt
index bfc261b..bf2e15c 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -214,6 +214,42 @@ The "ust" backend uses the LTTng Userspace Tracer library. There are no
monitor commands built into QEMU, instead UST utilities should be used to list,
enable/disable, and dump traces.
+Package lttng-tools is required for userspace tracing. You must ensure that the
+current user belongs to the "tracing" group, or manually launch the
+lttng-sessiond daemon for the current user prior to running any instance of
+QEMU.
+
+While running an instrumented QEMU, LTTng should be able to list all available
+events:
+
+ lttng list -u
+
+Create tracing session:
+
+ lttng create mysession
+
+Enable events:
+
+ lttng enable-event qemu:g_malloc -u
+
+Where the events can either be a comma-separated list of events, or "-a" to
+enable all tracepoint events. Start and stop tracing as needed:
+
+ lttng start
+ lttng stop
+
+View the trace:
+
+ lttng view
+
+Destroy tracing session:
+
+ lttng destroy
+
+Babeltrace can be used at any later time to view the trace:
+
+ babeltrace $HOME/lttng-traces/mysession-<date>-<time>
+
=== SystemTap ===
The "dtrace" backend uses DTrace sdt probes but has only been tested with
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index e0ea599..fc0b179 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2372,6 +2372,17 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM)
}
}
/* Zero plus something non-zero : just return the something */
+ if (flags & float_muladd_halve_result) {
+ if (cExp == 0) {
+ normalizeFloat32Subnormal(cSig, &cExp, &cSig);
+ }
+ /* Subtract one to halve, and one again because roundAndPackFloat32
+ * wants one less than the true exponent.
+ */
+ cExp -= 2;
+ cSig = (cSig | 0x00800000) << 7;
+ return roundAndPackFloat32(cSign ^ signflip, cExp, cSig STATUS_VAR);
+ }
return packFloat32(cSign ^ signflip, cExp, cSig);
}
@@ -2408,6 +2419,9 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM)
/* Throw out the special case of c being an exact zero now */
shift64RightJamming(pSig64, 32, &pSig64);
pSig = pSig64;
+ if (flags & float_muladd_halve_result) {
+ pExp--;
+ }
return roundAndPackFloat32(zSign, pExp - 1,
pSig STATUS_VAR);
}
@@ -2472,6 +2486,10 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM)
zSig64 <<= shiftcount;
zExp -= shiftcount;
}
+ if (flags & float_muladd_halve_result) {
+ zExp--;
+ }
+
shift64RightJamming(zSig64, 32, &zSig64);
return roundAndPackFloat32(zSign, zExp, zSig64 STATUS_VAR);
}
@@ -4088,6 +4106,17 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM)
}
}
/* Zero plus something non-zero : just return the something */
+ if (flags & float_muladd_halve_result) {
+ if (cExp == 0) {
+ normalizeFloat64Subnormal(cSig, &cExp, &cSig);
+ }
+ /* Subtract one to halve, and one again because roundAndPackFloat64
+ * wants one less than the true exponent.
+ */
+ cExp -= 2;
+ cSig = (cSig | 0x0010000000000000ULL) << 10;
+ return roundAndPackFloat64(cSign ^ signflip, cExp, cSig STATUS_VAR);
+ }
return packFloat64(cSign ^ signflip, cExp, cSig);
}
@@ -4123,6 +4152,9 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM)
if (!cSig) {
/* Throw out the special case of c being an exact zero now */
shift128RightJamming(pSig0, pSig1, 64, &pSig0, &pSig1);
+ if (flags & float_muladd_halve_result) {
+ pExp--;
+ }
return roundAndPackFloat64(zSign, pExp - 1,
pSig1 STATUS_VAR);
}
@@ -4159,6 +4191,9 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM)
zExp--;
}
shift128RightJamming(zSig0, zSig1, 64, &zSig0, &zSig1);
+ if (flags & float_muladd_halve_result) {
+ zExp--;
+ }
return roundAndPackFloat64(zSign, zExp, zSig1 STATUS_VAR);
} else {
/* Subtraction */
@@ -4209,6 +4244,9 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM)
zExp -= (shiftcount + 64);
}
}
+ if (flags & float_muladd_halve_result) {
+ zExp--;
+ }
return roundAndPackFloat64(zSign, zExp, zSig0 STATUS_VAR);
}
}
diff --git a/hmp.c b/hmp.c
index 1af0809..e3ddd46 100644
--- a/hmp.c
+++ b/hmp.c
@@ -881,7 +881,7 @@ void hmp_balloon(Monitor *mon, const QDict *qdict)
Error *errp = NULL;
qmp_balloon(value, &errp);
- if (error_is_set(&errp)) {
+ if (errp) {
monitor_printf(mon, "balloon: %s\n", error_get_pretty(errp));
error_free(errp);
}
@@ -1118,7 +1118,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
}
qmp_change(device, target, !!arg, arg, &err);
- if (error_is_set(&err) &&
+ if (err &&
error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
error_free(err);
monitor_read_block_device_key(mon, device, NULL, NULL);
@@ -1234,7 +1234,8 @@ static void hmp_migrate_status_cb(void *opaque)
MigrationInfo *info;
info = qmp_query_migrate(NULL);
- if (!info->has_status || strcmp(info->status, "active") == 0) {
+ if (!info->has_status || strcmp(info->status, "active") == 0 ||
+ strcmp(info->status, "setup") == 0) {
if (info->has_disk) {
int progress;
@@ -1335,12 +1336,12 @@ void hmp_netdev_add(Monitor *mon, const QDict *qdict)
QemuOpts *opts;
opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
- if (error_is_set(&err)) {
+ if (err) {
goto out;
}
netdev_add(opts, &err);
- if (error_is_set(&err)) {
+ if (err) {
qemu_opts_del(opts);
}
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index d91b9cc..05a00dc 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -12,6 +12,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += i2c/
devices-dirs-$(CONFIG_SOFTMMU) += ide/
devices-dirs-$(CONFIG_SOFTMMU) += input/
devices-dirs-$(CONFIG_SOFTMMU) += intc/
+devices-dirs-$(CONFIG_IPACK) += ipack/
devices-dirs-$(CONFIG_SOFTMMU) += isa/
devices-dirs-$(CONFIG_SOFTMMU) += misc/
devices-dirs-$(CONFIG_SOFTMMU) += net/
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 9f21653..67dc075 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -439,9 +439,9 @@ Object *piix4_pm_find(void)
return o;
}
-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, FWCfgState *fw_cfg)
+I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
+ qemu_irq sci_irq, qemu_irq smi_irq,
+ int kvm_enabled, FWCfgState *fw_cfg)
{
DeviceState *dev;
PIIX4PMState *s;
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index 4ebb938..9f137e9 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -326,7 +326,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
busdev = SYS_BUS_DEVICE(dev);
sysbus_connect_irq(busdev, 0, i2c_irq);
sysbus_mmio_map(busdev, 0, addr);
- s->i2c_if[n] = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
+ s->i2c_if[n] = (I2CBus *)qdev_get_child_bus(dev, "i2c");
}
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index 023e875..50a3b8f 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -1593,7 +1593,7 @@ static void musicpal_init(QEMUMachineInitArgs *args)
DeviceState *key_dev;
DeviceState *wm8750_dev;
SysBusDevice *s;
- i2c_bus *i2c;
+ I2CBus *i2c;
int i;
unsigned long flash_size;
DriveInfo *dinfo;
@@ -1687,7 +1687,7 @@ static void musicpal_init(QEMUMachineInitArgs *args)
dev = sysbus_create_simple(TYPE_MUSICPAL_GPIO, MP_GPIO_BASE,
pic[MP_GPIO_IRQ]);
i2c_dev = sysbus_create_simple("gpio_i2c", -1, NULL);
- i2c = (i2c_bus *)qdev_get_child_bus(i2c_dev, "i2c");
+ i2c = (I2CBus *)qdev_get_child_bus(i2c_dev, "i2c");
lcd_dev = sysbus_create_simple(TYPE_MUSICPAL_LCD, MP_LCD_BASE, NULL);
key_dev = sysbus_create_simple(TYPE_MUSICPAL_KEY, -1, NULL);
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index 9ef31ca..c28f895 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -202,7 +202,7 @@ static void n8x0_i2c_setup(struct n800_s *s)
{
DeviceState *dev;
qemu_irq tmp_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_TMP105_GPIO);
- i2c_bus *i2c = omap_i2c_bus(s->mpu->i2c[0]);
+ I2CBus *i2c = omap_i2c_bus(s->mpu->i2c[0]);
/* Attach a menelaus PM chip */
dev = i2c_create_slave(i2c, "twl92230", N8X0_MENELAUS_ADDR);
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 25ec549..45a99c8 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -224,27 +224,24 @@ static const VMStateDescription vmstate_pxa2xx_cm = {
}
};
-static int pxa2xx_clkcfg_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t pxa2xx_clkcfg_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
PXA2xxState *s = (PXA2xxState *)ri->opaque;
- *value = s->clkcfg;
- return 0;
+ return s->clkcfg;
}
-static int pxa2xx_clkcfg_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void pxa2xx_clkcfg_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
PXA2xxState *s = (PXA2xxState *)ri->opaque;
s->clkcfg = value & 0xf;
if (value & 2) {
printf("%s: CPU frequency change attempt\n", __func__);
}
- return 0;
}
-static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
PXA2xxState *s = (PXA2xxState *)ri->opaque;
static const char *pwrmode[8] = {
@@ -310,36 +307,29 @@ static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
printf("%s: machine entered %s mode\n", __func__,
pwrmode[value & 7]);
}
-
- return 0;
}
-static int pxa2xx_cppmnc_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t pxa2xx_cppmnc_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
PXA2xxState *s = (PXA2xxState *)ri->opaque;
- *value = s->pmnc;
- return 0;
+ return s->pmnc;
}
-static int pxa2xx_cppmnc_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void pxa2xx_cppmnc_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
PXA2xxState *s = (PXA2xxState *)ri->opaque;
s->pmnc = value;
- return 0;
}
-static int pxa2xx_cpccnt_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t pxa2xx_cpccnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
PXA2xxState *s = (PXA2xxState *)ri->opaque;
if (s->pmnc & 1) {
- *value = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
} else {
- *value = 0;
+ return 0;
}
- return 0;
}
static const ARMCPRegInfo pxa_cp_reginfo[] = {
@@ -1222,8 +1212,14 @@ static const TypeInfo pxa2xx_rtc_sysbus_info = {
};
/* I2C Interface */
-typedef struct {
- I2CSlave i2c;
+
+#define TYPE_PXA2XX_I2C_SLAVE "pxa2xx-i2c-slave"
+#define PXA2XX_I2C_SLAVE(obj) \
+ OBJECT_CHECK(PXA2xxI2CSlaveState, (obj), TYPE_PXA2XX_I2C_SLAVE)
+
+typedef struct PXA2xxI2CSlaveState {
+ I2CSlave parent_obj;
+
PXA2xxI2CState *host;
} PXA2xxI2CSlaveState;
@@ -1238,7 +1234,7 @@ struct PXA2xxI2CState {
MemoryRegion iomem;
PXA2xxI2CSlaveState *slave;
- i2c_bus *bus;
+ I2CBus *bus;
qemu_irq irq;
uint32_t offset;
uint32_t region_size;
@@ -1268,7 +1264,7 @@ static void pxa2xx_i2c_update(PXA2xxI2CState *s)
/* These are only stubs now. */
static void pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event event)
{
- PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c);
+ PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
PXA2xxI2CState *s = slave->host;
switch (event) {
@@ -1292,10 +1288,12 @@ static void pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event event)
static int pxa2xx_i2c_rx(I2CSlave *i2c)
{
- PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c);
+ PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
PXA2xxI2CState *s = slave->host;
- if ((s->control & (1 << 14)) || !(s->control & (1 << 6)))
+
+ if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) {
return 0;
+ }
if (s->status & (1 << 0)) { /* RWM */
s->status |= 1 << 6; /* set ITE */
@@ -1307,10 +1305,12 @@ static int pxa2xx_i2c_rx(I2CSlave *i2c)
static int pxa2xx_i2c_tx(I2CSlave *i2c, uint8_t data)
{
- PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c);
+ PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
PXA2xxI2CState *s = slave->host;
- if ((s->control & (1 << 14)) || !(s->control & (1 << 6)))
+
+ if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) {
return 1;
+ }
if (!(s->status & (1 << 0))) { /* RWM */
s->status |= 1 << 7; /* set IRF */
@@ -1325,6 +1325,7 @@ static uint64_t pxa2xx_i2c_read(void *opaque, hwaddr addr,
unsigned size)
{
PXA2xxI2CState *s = (PXA2xxI2CState *) opaque;
+ I2CSlave *slave;
addr -= s->offset;
switch (addr) {
@@ -1333,7 +1334,8 @@ static uint64_t pxa2xx_i2c_read(void *opaque, hwaddr addr,
case ISR:
return s->status | (i2c_bus_busy(s->bus) << 2);
case ISAR:
- return s->slave->i2c.address;
+ slave = I2C_SLAVE(s->slave);
+ return slave->address;
case IDBR:
return s->data;
case IBMR:
@@ -1408,7 +1410,7 @@ static void pxa2xx_i2c_write(void *opaque, hwaddr addr,
break;
case ISAR:
- i2c_set_slave_address(&s->slave->i2c, value & 0x7f);
+ i2c_set_slave_address(I2C_SLAVE(s->slave), value & 0x7f);
break;
case IDBR:
@@ -1432,7 +1434,7 @@ static const VMStateDescription vmstate_pxa2xx_i2c_slave = {
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
- VMSTATE_I2C_SLAVE(i2c, PXA2xxI2CSlaveState),
+ VMSTATE_I2C_SLAVE(parent_obj, PXA2xxI2CSlaveState),
VMSTATE_END_OF_LIST()
}
};
@@ -1470,7 +1472,7 @@ static void pxa2xx_i2c_slave_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo pxa2xx_i2c_slave_info = {
- .name = "pxa2xx-i2c-slave",
+ .name = TYPE_PXA2XX_I2C_SLAVE,
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(PXA2xxI2CSlaveState),
.class_init = pxa2xx_i2c_slave_class_init,
@@ -1482,7 +1484,7 @@ PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
DeviceState *dev;
SysBusDevice *i2c_dev;
PXA2xxI2CState *s;
- i2c_bus *i2cbus;
+ I2CBus *i2cbus;
dev = qdev_create(NULL, TYPE_PXA2XX_I2C);
qdev_prop_set_uint32(dev, "size", region_size + 1);
@@ -1496,8 +1498,8 @@ PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
s = PXA2XX_I2C(i2c_dev);
/* FIXME: Should the slave device really be on a separate bus? */
i2cbus = i2c_init_bus(dev, "dummy");
- dev = i2c_create_slave(i2cbus, "pxa2xx-i2c-slave", 0);
- s->slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, I2C_SLAVE(dev));
+ dev = i2c_create_slave(i2cbus, TYPE_PXA2XX_I2C_SLAVE, 0);
+ s->slave = PXA2XX_I2C_SLAVE(dev);
s->slave->host = s;
return s;
@@ -1518,7 +1520,7 @@ static int pxa2xx_i2c_initfn(SysBusDevice *sbd)
return 0;
}
-i2c_bus *pxa2xx_i2c_bus(PXA2xxI2CState *s)
+I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s)
{
return s->bus;
}
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
index 46d337c..345fa4a 100644
--- a/hw/arm/pxa2xx_pic.c
+++ b/hw/arm/pxa2xx_pic.c
@@ -217,20 +217,17 @@ static const int pxa2xx_cp_reg_map[0x10] = {
[0xa] = ICPR2,
};
-static int pxa2xx_pic_cp_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t pxa2xx_pic_cp_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
int offset = pxa2xx_cp_reg_map[ri->crn];
- *value = pxa2xx_pic_mem_read(ri->opaque, offset, 4);
- return 0;
+ return pxa2xx_pic_mem_read(ri->opaque, offset, 4);
}
-static int pxa2xx_pic_cp_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void pxa2xx_pic_cp_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
int offset = pxa2xx_cp_reg_map[ri->crn];
pxa2xx_pic_mem_write(ri->opaque, offset, value, 4);
- return 0;
}
#define REGINFO_FOR_PIC_CP(NAME, CRN) \
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 8d845dd..6ef7646 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -60,7 +60,7 @@ static void realview_init(QEMUMachineInitArgs *args,
qemu_irq mmc_irq[2];
PCIBus *pci_bus = NULL;
NICInfo *nd;
- i2c_bus *i2c;
+ I2CBus *i2c;
int n;
int done_nic = 0;
qemu_irq cpu_irq[4];
@@ -255,7 +255,7 @@ static void realview_init(QEMUMachineInitArgs *args,
}
dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
- i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
+ i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
i2c_create_slave(i2c, "ds1338", 0x68);
/* Memory map for RealView Emulation Baseboard: */
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index ba17283..2decff1 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -734,7 +734,7 @@ static void spitz_wm8750_addr(void *opaque, int line, int level)
static void spitz_i2c_setup(PXA2xxState *cpu)
{
/* Attach the CPU on one end of our I2C bus. */
- i2c_bus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
+ I2CBus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
DeviceState *wm;
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 3170d69..d6cc77b 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -692,7 +692,7 @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq,
typedef struct {
SysBusDevice parent_obj;
- i2c_bus *bus;
+ I2CBus *bus;
qemu_irq irq;
MemoryRegion iomem;
uint32_t msa;
@@ -868,7 +868,7 @@ static int stellaris_i2c_init(SysBusDevice *sbd)
{
DeviceState *dev = DEVICE(sbd);
stellaris_i2c_state *s = STELLARIS_I2C(dev);
- i2c_bus *bus;
+ I2CBus *bus;
sysbus_init_irq(sbd, &s->irq);
bus = i2c_init_bus(dev, "i2c");
@@ -1213,7 +1213,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
qemu_irq adc;
int sram_size;
int flash_size;
- i2c_bus *i2c;
+ I2CBus *i2c;
DeviceState *dev;
int i;
int j;
@@ -1256,7 +1256,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
if (board->dc2 & (1 << 12)) {
dev = sysbus_create_simple(TYPE_STELLARIS_I2C, 0x40020000, pic[8]);
- i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
+ i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
if (board->peripherals & BP_OLED_I2C) {
i2c_create_slave(i2c, "ssd0303", 0x3d);
}
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index c00d8c2..2069f55 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -132,15 +132,20 @@ static int tosa_ssp_init(SSISlave *dev)
return 0;
}
+#define TYPE_TOSA_DAC "tosa_dac"
+#define TOSA_DAC(obj) OBJECT_CHECK(TosaDACState, (obj), TYPE_TOSA_DAC)
+
typedef struct {
- I2CSlave i2c;
+ I2CSlave parent_obj;
+
int len;
char buf[3];
} TosaDACState;
static int tosa_dac_send(I2CSlave *i2c, uint8_t data)
{
- TosaDACState *s = FROM_I2C_SLAVE(TosaDACState, i2c);
+ TosaDACState *s = TOSA_DAC(i2c);
+
s->buf[s->len] = data;
if (s->len ++ > 2) {
#ifdef VERBOSE
@@ -159,7 +164,8 @@ static int tosa_dac_send(I2CSlave *i2c, uint8_t data)
static void tosa_dac_event(I2CSlave *i2c, enum i2c_event event)
{
- TosaDACState *s = FROM_I2C_SLAVE(TosaDACState, i2c);
+ TosaDACState *s = TOSA_DAC(i2c);
+
s->len = 0;
switch (event) {
case I2C_START_SEND:
@@ -194,8 +200,8 @@ static int tosa_dac_init(I2CSlave *i2c)
static void tosa_tg_init(PXA2xxState *cpu)
{
- i2c_bus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
- i2c_create_slave(bus, "tosa_dac", DAC_BASE);
+ I2CBus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
+ i2c_create_slave(bus, TYPE_TOSA_DAC, DAC_BASE);
ssi_create_slave(cpu->ssp[1], "tosa-ssp");
}
@@ -271,7 +277,7 @@ static void tosa_dac_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo tosa_dac_info = {
- .name = "tosa_dac",
+ .name = TYPE_TOSA_DAC,
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(TosaDACState),
.class_init = tosa_dac_class_init,
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index aef2bde..e5493b4 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -185,7 +185,7 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id)
DeviceState *pl041;
PCIBus *pci_bus;
NICInfo *nd;
- i2c_bus *i2c;
+ I2CBus *i2c;
int n;
int done_smc = 0;
DriveInfo *dinfo;
@@ -288,7 +288,7 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id)
sysbus_create_simple("pl031", 0x101e8000, pic[10]);
dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
- i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
+ i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
i2c_create_slave(i2c, "ds1338", 0x68);
/* Add PL041 AACI Interface to the LM4549 codec */
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 97367b1..67c1be8 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -193,15 +193,20 @@ static const TypeInfo zipit_lcd_info = {
.class_init = zipit_lcd_class_init,
};
-typedef struct {
- I2CSlave i2c;
+#define TYPE_AER915 "aer915"
+#define AER915(obj) OBJECT_CHECK(AER915State, (obj), TYPE_AER915)
+
+typedef struct AER915State {
+ I2CSlave parent_obj;
+
int len;
uint8_t buf[3];
} AER915State;
static int aer915_send(I2CSlave *i2c, uint8_t data)
{
- AER915State *s = FROM_I2C_SLAVE(AER915State, i2c);
+ AER915State *s = AER915(i2c);
+
s->buf[s->len] = data;
if (s->len++ > 2) {
DPRINTF("%s: message too long (%i bytes)\n",
@@ -219,7 +224,8 @@ static int aer915_send(I2CSlave *i2c, uint8_t data)
static void aer915_event(I2CSlave *i2c, enum i2c_event event)
{
- AER915State *s = FROM_I2C_SLAVE(AER915State, i2c);
+ AER915State *s = AER915(i2c);
+
switch (event) {
case I2C_START_SEND:
s->len = 0;
@@ -238,8 +244,8 @@ static void aer915_event(I2CSlave *i2c, enum i2c_event event)
static int aer915_recv(I2CSlave *slave)
{
+ AER915State *s = AER915(slave);
int retval = 0x00;
- AER915State *s = FROM_I2C_SLAVE(AER915State, slave);
switch (s->buf[0]) {
/* Return hardcoded battery voltage,
@@ -290,7 +296,7 @@ static void aer915_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo aer915_info = {
- .name = "aer915",
+ .name = TYPE_AER915,
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(AER915State),
.class_init = aer915_class_init,
@@ -308,7 +314,7 @@ static void z2_init(QEMUMachineInitArgs *args)
DriveInfo *dinfo;
int be;
void *z2_lcd;
- i2c_bus *bus;
+ I2CBus *bus;
DeviceState *wm;
if (!cpu_model) {
@@ -351,7 +357,7 @@ static void z2_init(QEMUMachineInitArgs *args)
type_register_static(&aer915_info);
z2_lcd = ssi_create_slave(mpu->ssp[1], "zipit-lcd");
bus = pxa2xx_i2c_bus(mpu->i2c[0]);
- i2c_create_slave(bus, "aer915", 0x55);
+ i2c_create_slave(bus, TYPE_AER915, 0x55);
wm = i2c_create_slave(bus, "wm8750", 0x1b);
mpu->i2s->opaque = wm;
mpu->i2s->codec_out = wm8750_dac_dat;
diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c
index e88d2dd..28eed81 100644
--- a/hw/audio/adlib.c
+++ b/hw/audio/adlib.c
@@ -354,7 +354,7 @@ static void adlib_realizefn (DeviceState *dev, Error **errp)
}
static Property adlib_properties[] = {
- DEFINE_PROP_HEX32 ("iobase", AdlibState, port, 0x220),
+ DEFINE_PROP_UINT32 ("iobase", AdlibState, port, 0x220),
DEFINE_PROP_UINT32 ("freq", AdlibState, freq, 44100),
DEFINE_PROP_END_OF_LIST (),
};
diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c
index 666096b..a0ec17a 100644
--- a/hw/audio/cs4231a.c
+++ b/hw/audio/cs4231a.c
@@ -673,7 +673,7 @@ static int cs4231a_init (ISABus *bus)
}
static Property cs4231a_properties[] = {
- DEFINE_PROP_HEX32 ("iobase", CSState, port, 0x534),
+ DEFINE_PROP_UINT32 ("iobase", CSState, port, 0x534),
DEFINE_PROP_UINT32 ("irq", CSState, irq, 9),
DEFINE_PROP_UINT32 ("dma", CSState, dma, 3),
DEFINE_PROP_END_OF_LIST (),
diff --git a/hw/audio/gus.c b/hw/audio/gus.c
index 71be3c6..e29a571 100644
--- a/hw/audio/gus.c
+++ b/hw/audio/gus.c
@@ -304,7 +304,7 @@ static int GUS_init (ISABus *bus)
static Property gus_properties[] = {
DEFINE_PROP_UINT32 ("freq", GUSState, freq, 44100),
- DEFINE_PROP_HEX32 ("iobase", GUSState, port, 0x240),
+ DEFINE_PROP_UINT32 ("iobase", GUSState, port, 0x240),
DEFINE_PROP_UINT32 ("irq", GUSState, emu.gusirq, 7),
DEFINE_PROP_UINT32 ("dma", GUSState, emu.gusdma, 3),
DEFINE_PROP_END_OF_LIST (),
diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c
index f980d66..1d81bbe 100644
--- a/hw/audio/pcspk.c
+++ b/hw/audio/pcspk.c
@@ -181,7 +181,7 @@ static void pcspk_realizefn(DeviceState *dev, Error **errp)
}
static Property pcspk_properties[] = {
- DEFINE_PROP_HEX32("iobase", PCSpkState, iobase, -1),
+ DEFINE_PROP_UINT32("iobase", PCSpkState, iobase, -1),
DEFINE_PROP_PTR("pit", PCSpkState, pit),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index db79131..bb24e00 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -1399,8 +1399,8 @@ static int SB16_init (ISABus *bus)
}
static Property sb16_properties[] = {
- DEFINE_PROP_HEX32 ("version", SB16State, ver, 0x0405), /* 4.5 */
- DEFINE_PROP_HEX32 ("iobase", SB16State, port, 0x220),
+ DEFINE_PROP_UINT32 ("version", SB16State, ver, 0x0405), /* 4.5 */
+ DEFINE_PROP_UINT32 ("iobase", SB16State, port, 0x220),
DEFINE_PROP_UINT32 ("irq", SB16State, irq, 5),
DEFINE_PROP_UINT32 ("dma", SB16State, dma, 1),
DEFINE_PROP_UINT32 ("dma16", SB16State, hdma, 5),
diff --git a/hw/audio/wm8750.c b/hw/audio/wm8750.c
index 6b5a349..c18f245 100644
--- a/hw/audio/wm8750.c
+++ b/hw/audio/wm8750.c
@@ -23,8 +23,12 @@ typedef struct {
int dac_hz;
} WMRate;
-typedef struct {
- I2CSlave i2c;
+#define TYPE_WM8750 "wm8750"
+#define WM8750(obj) OBJECT_CHECK(WM8750State, (obj), TYPE_WM8750)
+
+typedef struct WM8750State {
+ I2CSlave parent_obj;
+
uint8_t i2c_data[2];
int i2c_len;
QEMUSoundCard card;
@@ -256,7 +260,8 @@ static void wm8750_clk_update(WM8750State *s, int ext)
static void wm8750_reset(I2CSlave *i2c)
{
- WM8750State *s = (WM8750State *) i2c;
+ WM8750State *s = WM8750(i2c);
+
s->rate = &wm_rate_table[0];
s->enable = 0;
wm8750_clk_update(s, 1);
@@ -299,7 +304,7 @@ static void wm8750_reset(I2CSlave *i2c)
static void wm8750_event(I2CSlave *i2c, enum i2c_event event)
{
- WM8750State *s = (WM8750State *) i2c;
+ WM8750State *s = WM8750(i2c);
switch (event) {
case I2C_START_SEND:
@@ -356,7 +361,7 @@ static void wm8750_event(I2CSlave *i2c, enum i2c_event event)
static int wm8750_tx(I2CSlave *i2c, uint8_t data)
{
- WM8750State *s = (WM8750State *) i2c;
+ WM8750State *s = WM8750(i2c);
uint8_t cmd;
uint16_t value;
@@ -542,7 +547,7 @@ static int wm8750_tx(I2CSlave *i2c, uint8_t data)
break;
case WM8750_RESET: /* Reset */
- wm8750_reset(&s->i2c);
+ wm8750_reset(I2C_SLAVE(s));
break;
#ifdef VERBOSE
@@ -604,17 +609,17 @@ static const VMStateDescription vmstate_wm8750 = {
VMSTATE_UINT8(format, WM8750State),
VMSTATE_UINT8(power, WM8750State),
VMSTATE_UINT8(rate_vmstate, WM8750State),
- VMSTATE_I2C_SLAVE(i2c, WM8750State),
+ VMSTATE_I2C_SLAVE(parent_obj, WM8750State),
VMSTATE_END_OF_LIST()
}
};
static int wm8750_init(I2CSlave *i2c)
{
- WM8750State *s = FROM_I2C_SLAVE(WM8750State, i2c);
+ WM8750State *s = WM8750(i2c);
AUD_register_card(CODEC, &s->card);
- wm8750_reset(&s->i2c);
+ wm8750_reset(I2C_SLAVE(s));
return 0;
}
@@ -622,8 +627,9 @@ static int wm8750_init(I2CSlave *i2c)
#if 0
static void wm8750_fini(I2CSlave *i2c)
{
- WM8750State *s = (WM8750State *) i2c;
- wm8750_reset(&s->i2c);
+ WM8750State *s = WM8750(i2c);
+
+ wm8750_reset(I2C_SLAVE(s));
AUD_remove_card(&s->card);
g_free(s);
}
@@ -632,7 +638,8 @@ static void wm8750_fini(I2CSlave *i2c)
void wm8750_data_req_set(DeviceState *dev,
void (*data_req)(void *, int, int), void *opaque)
{
- WM8750State *s = FROM_I2C_SLAVE(WM8750State, I2C_SLAVE(dev));
+ WM8750State *s = WM8750(dev);
+
s->data_req = data_req;
s->opaque = opaque;
}
@@ -702,7 +709,7 @@ static void wm8750_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo wm8750_info = {
- .name = "wm8750",
+ .name = TYPE_WM8750,
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(WM8750State),
.class_init = wm8750_class_init,
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 592b58f..1651007 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2216,7 +2216,7 @@ static const VMStateDescription vmstate_isa_fdc ={
};
static Property isa_fdc_properties[] = {
- DEFINE_PROP_HEX32("iobase", FDCtrlISABus, iobase, 0x3f0),
+ DEFINE_PROP_UINT32("iobase", FDCtrlISABus, iobase, 0x3f0),
DEFINE_PROP_UINT32("irq", FDCtrlISABus, irq, 6),
DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs),
diff --git a/hw/block/nand.c b/hw/block/nand.c
index a871ce0..6d7c804 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -632,7 +632,7 @@ DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id)
if (nand_flash_ids[chip_id].size == 0) {
hw_error("%s: Unsupported NAND chip ID.\n", __FUNCTION__);
}
- dev = qdev_create(NULL, "nand");
+ dev = DEVICE(object_new(TYPE_NAND));
qdev_prop_set_uint8(dev, "manufacturer_id", manf_id);
qdev_prop_set_uint8(dev, "chip_id", chip_id);
if (bdrv) {
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
index be2a7d9..317385d 100644
--- a/hw/char/Makefile.objs
+++ b/hw/char/Makefile.objs
@@ -1,4 +1,4 @@
-common-obj-$(CONFIG_IPACK) += tpci200.o ipoctal232.o ipack.o
+common-obj-$(CONFIG_IPACK) += ipoctal232.o
common-obj-$(CONFIG_ESCC) += escc.o
common-obj-$(CONFIG_PARALLEL) += parallel.o
common-obj-$(CONFIG_PL011) += pl011.o
diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c
index 02d0d57..36f1c4a 100644
--- a/hw/char/debugcon.c
+++ b/hw/char/debugcon.c
@@ -110,9 +110,9 @@ static void debugcon_isa_realizefn(DeviceState *dev, Error **errp)
}
static Property debugcon_isa_properties[] = {
- DEFINE_PROP_HEX32("iobase", ISADebugconState, iobase, 0xe9),
+ DEFINE_PROP_UINT32("iobase", ISADebugconState, iobase, 0xe9),
DEFINE_PROP_CHR("chardev", ISADebugconState, state.chr),
- DEFINE_PROP_HEX32("readback", ISADebugconState, state.readback, 0xe9),
+ DEFINE_PROP_UINT32("readback", ISADebugconState, state.readback, 0xe9),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/char/ipoctal232.c b/hw/char/ipoctal232.c
index 88e2cca..f9c388e 100644
--- a/hw/char/ipoctal232.c
+++ b/hw/char/ipoctal232.c
@@ -8,7 +8,7 @@
* later version.
*/
-#include "ipack.h"
+#include "hw/ipack/ipack.h"
#include "qemu/bitops.h"
#include "sysemu/char.h"
@@ -108,7 +108,8 @@ struct SCC2698Block {
};
struct IPOctalState {
- IPackDevice dev;
+ IPackDevice parent_obj;
+
SCC2698Channel ch[N_CHANNELS];
SCC2698Block blk[N_BLOCKS];
uint8_t irq_vector;
@@ -154,7 +155,7 @@ static const VMStateDescription vmstate_ipoctal = {
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
- VMSTATE_IPACK_DEVICE(dev, IPOctalState),
+ VMSTATE_IPACK_DEVICE(parent_obj, IPOctalState),
VMSTATE_STRUCT_ARRAY(ch, IPOctalState, N_CHANNELS, 1,
vmstate_scc2698_channel, SCC2698Channel),
VMSTATE_STRUCT_ARRAY(blk, IPOctalState, N_BLOCKS, 1,
@@ -172,6 +173,7 @@ static const uint8_t id_prom_data[] = {
static void update_irq(IPOctalState *dev, unsigned block)
{
+ IPackDevice *idev = IPACK_DEVICE(dev);
/* Blocks A and B interrupt on INT0#, C and D on INT1#.
Thus, to get the status we have to check two blocks. */
SCC2698Block *blk0 = &dev->blk[block];
@@ -179,9 +181,9 @@ static void update_irq(IPOctalState *dev, unsigned block)
unsigned intno = block / 2;
if ((blk0->isr & blk0->imr) || (blk1->isr & blk1->imr)) {
- qemu_irq_raise(dev->dev.irq[intno]);
+ qemu_irq_raise(idev->irq[intno]);
} else {
- qemu_irq_lower(dev->dev.irq[intno]);
+ qemu_irq_lower(idev->irq[intno]);
}
}
@@ -534,9 +536,9 @@ static void hostdev_event(void *opaque, int event)
}
}
-static int ipoctal_init(IPackDevice *ip)
+static void ipoctal_realize(DeviceState *dev, Error **errp)
{
- IPOctalState *s = IPOCTAL(ip);
+ IPOctalState *s = IPOCTAL(dev);
unsigned i;
for (i = 0; i < N_CHANNELS; i++) {
@@ -552,8 +554,6 @@ static int ipoctal_init(IPackDevice *ip)
DPRINTF("Could not redirect channel %u, no chardev set\n", i);
}
}
-
- return 0;
}
static Property ipoctal_properties[] = {
@@ -573,7 +573,7 @@ static void ipoctal_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
IPackDeviceClass *ic = IPACK_DEVICE_CLASS(klass);
- ic->init = ipoctal_init;
+ ic->realize = ipoctal_realize;
ic->io_read = io_read;
ic->io_write = io_write;
ic->id_read = id_read;
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index 7a3b264..7ac90a5 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -595,7 +595,7 @@ bool parallel_mm_init(MemoryRegion *address_space,
static Property parallel_isa_properties[] = {
DEFINE_PROP_UINT32("index", ISAParallelState, index, -1),
- DEFINE_PROP_HEX32("iobase", ISAParallelState, iobase, -1),
+ DEFINE_PROP_UINT32("iobase", ISAParallelState, iobase, -1),
DEFINE_PROP_UINT32("irq", ISAParallelState, isairq, 7),
DEFINE_PROP_CHR("chardev", ISAParallelState, state.chr),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index 5cb77b3..c9fcb27 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -88,7 +88,7 @@ static const VMStateDescription vmstate_isa_serial = {
static Property serial_isa_properties[] = {
DEFINE_PROP_UINT32("index", ISASerialState, index, -1),
- DEFINE_PROP_HEX32("iobase", ISASerialState, iobase, -1),
+ DEFINE_PROP_UINT32("iobase", ISASerialState, iobase, -1),
DEFINE_PROP_UINT32("irq", ISASerialState, isairq, -1),
DEFINE_PROP_CHR("chardev", ISASerialState, state.chr),
DEFINE_PROP_UINT32("wakeup", ISASerialState, state.wakeup, 0),
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 3f29b49..5f5957e 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -109,7 +109,8 @@ static void set_drive(Object *obj, Visitor *v, void *opaque,
}
PropertyInfo qdev_prop_drive = {
- .name = "drive",
+ .name = "str",
+ .legacy_name = "drive",
.get = get_drive,
.set = set_drive,
.release = release_drive,
@@ -164,7 +165,8 @@ static void set_chr(Object *obj, Visitor *v, void *opaque,
}
PropertyInfo qdev_prop_chr = {
- .name = "chr",
+ .name = "str",
+ .legacy_name = "chr",
.get = get_chr,
.set = set_chr,
.release = release_chr,
@@ -242,7 +244,8 @@ static void set_netdev(Object *obj, Visitor *v, void *opaque,
}
PropertyInfo qdev_prop_netdev = {
- .name = "netdev",
+ .name = "str",
+ .legacy_name = "netdev",
.get = get_netdev,
.set = set_netdev,
};
@@ -321,7 +324,8 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque,
}
PropertyInfo qdev_prop_vlan = {
- .name = "vlan",
+ .name = "int32",
+ .legacy_name = "vlan",
.print = print_vlan,
.get = get_vlan,
.set = set_vlan,
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index b949f0e..77d0c66 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -74,13 +74,6 @@ static void bit_prop_set(DeviceState *dev, Property *props, bool val)
}
}
-static int prop_print_bit(DeviceState *dev, Property *prop, char *dest,
- size_t len)
-{
- uint32_t *p = qdev_get_prop_ptr(dev, prop);
- return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
-}
-
static void prop_get_bit(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
@@ -114,9 +107,8 @@ static void prop_set_bit(Object *obj, Visitor *v, void *opaque,
}
PropertyInfo qdev_prop_bit = {
- .name = "boolean",
+ .name = "bool",
.legacy_name = "on/off",
- .print = prop_print_bit,
.get = prop_get_bit,
.set = prop_set_bit,
};
@@ -149,7 +141,7 @@ static void set_bool(Object *obj, Visitor *v, void *opaque,
}
PropertyInfo qdev_prop_bool = {
- .name = "boolean",
+ .name = "bool",
.get = get_bool,
.set = set_bool,
};
@@ -187,40 +179,6 @@ PropertyInfo qdev_prop_uint8 = {
.set = set_uint8,
};
-/* --- 8bit hex value --- */
-
-static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
-{
- uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
- char *end;
-
- if (str[0] != '0' || str[1] != 'x') {
- return -EINVAL;
- }
-
- *ptr = strtoul(str, &end, 16);
- if ((*end != '\0') || (end == str)) {
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
- uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
- return snprintf(dest, len, "0x%" PRIx8, *ptr);
-}
-
-PropertyInfo qdev_prop_hex8 = {
- .name = "uint8",
- .legacy_name = "hex8",
- .parse = parse_hex8,
- .print = print_hex8,
- .get = get_uint8,
- .set = set_uint8,
-};
-
/* --- 16bit integer --- */
static void get_uint16(Object *obj, Visitor *v, void *opaque,
@@ -318,40 +276,6 @@ PropertyInfo qdev_prop_int32 = {
.set = set_int32,
};
-/* --- 32bit hex value --- */
-
-static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
-{
- uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
- char *end;
-
- if (str[0] != '0' || str[1] != 'x') {
- return -EINVAL;
- }
-
- *ptr = strtoul(str, &end, 16);
- if ((*end != '\0') || (end == str)) {
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
- uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
- return snprintf(dest, len, "0x%" PRIx32, *ptr);
-}
-
-PropertyInfo qdev_prop_hex32 = {
- .name = "uint32",
- .legacy_name = "hex32",
- .parse = parse_hex32,
- .print = print_hex32,
- .get = get_uint32,
- .set = set_uint32,
-};
-
/* --- 64bit integer --- */
static void get_uint64(Object *obj, Visitor *v, void *opaque,
@@ -385,40 +309,6 @@ PropertyInfo qdev_prop_uint64 = {
.set = set_uint64,
};
-/* --- 64bit hex value --- */
-
-static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
-{
- uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
- char *end;
-
- if (str[0] != '0' || str[1] != 'x') {
- return -EINVAL;
- }
-
- *ptr = strtoull(str, &end, 16);
- if ((*end != '\0') || (end == str)) {
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
- uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
- return snprintf(dest, len, "0x%" PRIx64, *ptr);
-}
-
-PropertyInfo qdev_prop_hex64 = {
- .name = "uint64",
- .legacy_name = "hex64",
- .parse = parse_hex64,
- .print = print_hex64,
- .get = get_uint64,
- .set = set_uint64,
-};
-
/* --- string --- */
static void release_string(Object *obj, const char *name, void *opaque)
@@ -427,16 +317,6 @@ static void release_string(Object *obj, const char *name, void *opaque)
g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
}
-static int print_string(DeviceState *dev, Property *prop, char *dest,
- size_t len)
-{
- char **ptr = qdev_get_prop_ptr(dev, prop);
- if (!*ptr) {
- return snprintf(dest, len, "<null>");
- }
- return snprintf(dest, len, "\"%s\"", *ptr);
-}
-
static void get_string(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
@@ -478,8 +358,7 @@ static void set_string(Object *obj, Visitor *v, void *opaque,
}
PropertyInfo qdev_prop_string = {
- .name = "string",
- .print = print_string,
+ .name = "str",
.release = release_string,
.get = get_string,
.set = set_string,
@@ -563,41 +442,31 @@ inval:
}
PropertyInfo qdev_prop_macaddr = {
- .name = "macaddr",
+ .name = "str",
+ .legacy_name = "macaddr",
.get = get_mac,
.set = set_mac,
};
/* --- lost tick policy --- */
-static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
- [LOST_TICK_DISCARD] = "discard",
- [LOST_TICK_DELAY] = "delay",
- [LOST_TICK_MERGE] = "merge",
- [LOST_TICK_SLEW] = "slew",
- [LOST_TICK_MAX] = NULL,
-};
-
QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
PropertyInfo qdev_prop_losttickpolicy = {
.name = "LostTickPolicy",
- .enum_table = lost_tick_policy_table,
+ .enum_table = LostTickPolicy_lookup,
.get = get_enum,
.set = set_enum,
};
/* --- BIOS CHS translation */
-static const char *bios_chs_trans_table[] = {
- [BIOS_ATA_TRANSLATION_AUTO] = "auto",
- [BIOS_ATA_TRANSLATION_NONE] = "none",
- [BIOS_ATA_TRANSLATION_LBA] = "lba",
-};
+QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
PropertyInfo qdev_prop_bios_chs_trans = {
- .name = "bios-chs-trans",
- .enum_table = bios_chs_trans_table,
+ .name = "BiosAtaTranslation",
+ .legacy_name = "bios-chs-trans",
+ .enum_table = BiosAtaTranslation_lookup,
.get = get_enum,
.set = set_enum,
};
@@ -715,7 +584,8 @@ static void set_blocksize(Object *obj, Visitor *v, void *opaque,
}
PropertyInfo qdev_prop_blocksize = {
- .name = "blocksize",
+ .name = "uint16",
+ .legacy_name = "blocksize",
.get = get_uint16,
.set = set_blocksize,
};
@@ -822,7 +692,8 @@ inval:
}
PropertyInfo qdev_prop_pci_host_devaddr = {
- .name = "pci-host-devaddr",
+ .name = "str",
+ .legacy_name = "pci-host-devaddr",
.get = get_pci_host_devaddr,
.set = set_pci_host_devaddr,
};
@@ -987,20 +858,6 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
}
}
-void qdev_prop_parse(DeviceState *dev, const char *name, const char *value,
- Error **errp)
-{
- char *legacy_name;
-
- legacy_name = g_strdup_printf("legacy-%s", name);
- if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
- object_property_parse(OBJECT(dev), value, legacy_name, errp);
- } else {
- object_property_parse(OBJECT(dev), value, name, errp);
- }
- g_free(legacy_name);
-}
-
void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
{
object_property_set_bool(OBJECT(dev), value, name, &error_abort);
@@ -1093,7 +950,7 @@ void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
if (strcmp(typename, prop->driver) != 0) {
continue;
}
- qdev_prop_parse(dev, prop->property, prop->value, &err);
+ object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
if (err != NULL) {
error_propagate(errp, err);
return;
@@ -1140,39 +997,8 @@ static void set_size(Object *obj, Visitor *v, void *opaque,
visit_type_size(v, ptr, name, errp);
}
-static int parse_size(DeviceState *dev, Property *prop, const char *str)
-{
- uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
-
- if (str != NULL) {
- parse_option_size(prop->name, str, ptr, &error_abort);
- }
- return 0;
-}
-
-static int print_size(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
- static const char suffixes[] = { 'B', 'K', 'M', 'G', 'T' };
- uint64_t div, val = *(uint64_t *)qdev_get_prop_ptr(dev, prop);
- int i;
-
- /* Compute floor(log2(val)). */
- i = 64 - clz64(val);
-
- /* Find the power of 1024 that we'll display as the units. */
- i /= 10;
- if (i >= ARRAY_SIZE(suffixes)) {
- i = ARRAY_SIZE(suffixes) - 1;
- }
- div = 1ULL << (i * 10);
-
- return snprintf(dest, len, "%0.03f%c", (double)val/div, suffixes[i]);
-}
-
PropertyInfo qdev_prop_size = {
.name = "size",
- .parse = parse_size,
- .print = print_size,
.get = get_size,
.set = set_size,
};
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 64b66e0..c0b857f 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -588,31 +588,6 @@ static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
visit_type_str(v, &ptr, name, errp);
}
-static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
-{
- DeviceState *dev = DEVICE(obj);
- Property *prop = opaque;
- Error *local_err = NULL;
- char *ptr = NULL;
- int ret;
-
- if (dev->realized) {
- qdev_prop_set_after_realize(dev, name, errp);
- return;
- }
-
- visit_type_str(v, &ptr, name, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- ret = prop->info->parse(dev, prop, ptr);
- error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
- g_free(ptr);
-}
-
/**
* @qdev_add_legacy_property - adds a legacy property
*
@@ -625,25 +600,20 @@ static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
void qdev_property_add_legacy(DeviceState *dev, Property *prop,
Error **errp)
{
- gchar *name, *type;
+ gchar *name;
/* Register pointer properties as legacy properties */
- if (!prop->info->print && !prop->info->parse &&
- (prop->info->set || prop->info->get)) {
+ if (!prop->info->print && prop->info->get) {
return;
}
name = g_strdup_printf("legacy-%s", prop->name);
- type = g_strdup_printf("legacy<%s>",
- prop->info->legacy_name ?: prop->info->name);
-
- object_property_add(OBJECT(dev), name, type,
+ object_property_add(OBJECT(dev), name, "str",
prop->info->print ? qdev_get_legacy_property : prop->info->get,
- prop->info->parse ? qdev_set_legacy_property : prop->info->set,
+ NULL,
NULL,
prop, errp);
- g_free(type);
g_free(name);
}
diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c
index 7082171..bc909bb 100644
--- a/hw/display/g364fb.c
+++ b/hw/display/g364fb.c
@@ -524,7 +524,7 @@ static void g364fb_sysbus_reset(DeviceState *d)
}
static Property g364fb_sysbus_properties[] = {
- DEFINE_PROP_HEX32("vram_size", G364SysBusState, g364.vram_size,
+ DEFINE_PROP_UINT32("vram_size", G364SysBusState, g364.vram_size,
8 * 1024 * 1024),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/display/ssd0303.c b/hw/display/ssd0303.c
index beea5bf..89804e1 100644
--- a/hw/display/ssd0303.c
+++ b/hw/display/ssd0303.c
@@ -41,8 +41,12 @@ enum ssd0303_cmd {
SSD0303_CMD_SKIP1
};
+#define TYPE_SSD0303 "ssd0303"
+#define SSD0303(obj) OBJECT_CHECK(ssd0303_state, (obj), TYPE_SSD0303)
+
typedef struct {
- I2CSlave i2c;
+ I2CSlave parent_obj;
+
QemuConsole *con;
int row;
int col;
@@ -65,8 +69,9 @@ static int ssd0303_recv(I2CSlave *i2c)
static int ssd0303_send(I2CSlave *i2c, uint8_t data)
{
- ssd0303_state *s = (ssd0303_state *)i2c;
+ ssd0303_state *s = SSD0303(i2c);
enum ssd0303_cmd old_cmd_state;
+
switch (s->mode) {
case SSD0303_IDLE:
DPRINTF("byte 0x%02x\n", data);
@@ -175,7 +180,8 @@ static int ssd0303_send(I2CSlave *i2c, uint8_t data)
static void ssd0303_event(I2CSlave *i2c, enum i2c_event event)
{
- ssd0303_state *s = (ssd0303_state *)i2c;
+ ssd0303_state *s = SSD0303(i2c);
+
switch (event) {
case I2C_FINISH:
s->mode = SSD0303_IDLE;
@@ -279,7 +285,7 @@ static const VMStateDescription vmstate_ssd0303 = {
VMSTATE_UINT32(mode, ssd0303_state),
VMSTATE_UINT32(cmd_state, ssd0303_state),
VMSTATE_BUFFER(framebuffer, ssd0303_state),
- VMSTATE_I2C_SLAVE(i2c, ssd0303_state),
+ VMSTATE_I2C_SLAVE(parent_obj, ssd0303_state),
VMSTATE_END_OF_LIST()
}
};
@@ -291,7 +297,7 @@ static const GraphicHwOps ssd0303_ops = {
static int ssd0303_init(I2CSlave *i2c)
{
- ssd0303_state *s = FROM_I2C_SLAVE(ssd0303_state, i2c);
+ ssd0303_state *s = SSD0303(i2c);
s->con = graphic_console_init(DEVICE(i2c), &ssd0303_ops, s);
qemu_console_resize(s->con, 96 * MAGNIFY, 16 * MAGNIFY);
@@ -311,7 +317,7 @@ static void ssd0303_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo ssd0303_info = {
- .name = "ssd0303",
+ .name = TYPE_SSD0303,
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(ssd0303_state),
.class_init = ssd0303_class_init,
diff --git a/hw/display/tcx.c b/hw/display/tcx.c
index 873b82c..e60769c 100644
--- a/hw/display/tcx.c
+++ b/hw/display/tcx.c
@@ -617,11 +617,11 @@ static int tcx_init1(SysBusDevice *dev)
}
static Property tcx_properties[] = {
- DEFINE_PROP_HEX32("vram_size", TCXState, vram_size, -1),
+ DEFINE_PROP_UINT32("vram_size", TCXState, vram_size, -1),
DEFINE_PROP_UINT16("width", TCXState, width, -1),
DEFINE_PROP_UINT16("height", TCXState, height, -1),
DEFINE_PROP_UINT16("depth", TCXState, depth, -1),
- DEFINE_PROP_HEX64("prom_addr", TCXState, prom_addr, -1),
+ DEFINE_PROP_UINT64("prom_addr", TCXState, prom_addr, -1),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c
index a5b891f..dc7a767 100644
--- a/hw/dma/i82374.c
+++ b/hw/dma/i82374.c
@@ -149,7 +149,7 @@ static void i82374_isa_realize(DeviceState *dev, Error **errp)
}
static Property i82374_properties[] = {
- DEFINE_PROP_HEX32("iobase", ISAi82374State, iobase, 0x400),
+ DEFINE_PROP_UINT32("iobase", ISAi82374State, iobase, 0x400),
DEFINE_PROP_END_OF_LIST()
};
diff --git a/hw/dma/sun4m_iommu.c b/hw/dma/sun4m_iommu.c
index 723f66d..899d454 100644
--- a/hw/dma/sun4m_iommu.c
+++ b/hw/dma/sun4m_iommu.c
@@ -362,7 +362,7 @@ static int iommu_init1(SysBusDevice *dev)
}
static Property iommu_properties[] = {
- DEFINE_PROP_HEX32("version", IOMMUState, version, 0),
+ DEFINE_PROP_UINT32("version", IOMMUState, version, 0),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/gpio/max7310.c b/hw/gpio/max7310.c
index 59b2877..cfcd89c 100644
--- a/hw/gpio/max7310.c
+++ b/hw/gpio/max7310.c
@@ -9,8 +9,12 @@
#include "hw/i2c/i2c.h"
-typedef struct {
- I2CSlave i2c;
+#define TYPE_MAX7310 "max7310"
+#define MAX7310(obj) OBJECT_CHECK(MAX7310State, (obj), TYPE_MAX7310)
+
+typedef struct MAX7310State {
+ I2CSlave parent_obj;
+
int i2c_command_byte;
int len;
@@ -25,7 +29,8 @@ typedef struct {
static void max7310_reset(DeviceState *dev)
{
- MAX7310State *s = FROM_I2C_SLAVE(MAX7310State, I2C_SLAVE(dev));
+ MAX7310State *s = MAX7310(dev);
+
s->level &= s->direction;
s->direction = 0xff;
s->polarity = 0xf0;
@@ -35,7 +40,7 @@ static void max7310_reset(DeviceState *dev)
static int max7310_rx(I2CSlave *i2c)
{
- MAX7310State *s = (MAX7310State *) i2c;
+ MAX7310State *s = MAX7310(i2c);
switch (s->command) {
case 0x00: /* Input port */
@@ -70,7 +75,7 @@ static int max7310_rx(I2CSlave *i2c)
static int max7310_tx(I2CSlave *i2c, uint8_t data)
{
- MAX7310State *s = (MAX7310State *) i2c;
+ MAX7310State *s = MAX7310(i2c);
uint8_t diff;
int line;
@@ -125,7 +130,7 @@ static int max7310_tx(I2CSlave *i2c, uint8_t data)
static void max7310_event(I2CSlave *i2c, enum i2c_event event)
{
- MAX7310State *s = (MAX7310State *) i2c;
+ MAX7310State *s = MAX7310(i2c);
s->len = 0;
switch (event) {
@@ -156,7 +161,7 @@ static const VMStateDescription vmstate_max7310 = {
VMSTATE_UINT8(polarity, MAX7310State),
VMSTATE_UINT8(status, MAX7310State),
VMSTATE_UINT8(command, MAX7310State),
- VMSTATE_I2C_SLAVE(i2c, MAX7310State),
+ VMSTATE_I2C_SLAVE(parent_obj, MAX7310State),
VMSTATE_END_OF_LIST()
}
};
@@ -177,7 +182,7 @@ static void max7310_gpio_set(void *opaque, int line, int level)
* but also accepts sequences that are not SMBus so return an I2C device. */
static int max7310_init(I2CSlave *i2c)
{
- MAX7310State *s = FROM_I2C_SLAVE(MAX7310State, i2c);
+ MAX7310State *s = MAX7310(i2c);
qdev_init_gpio_in(&i2c->qdev, max7310_gpio_set, 8);
qdev_init_gpio_out(&i2c->qdev, s->handler, 8);
@@ -199,7 +204,7 @@ static void max7310_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo max7310_info = {
- .name = "max7310",
+ .name = TYPE_MAX7310,
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(MAX7310State),
.class_init = max7310_class_init,
diff --git a/hw/i2c/bitbang_i2c.c b/hw/i2c/bitbang_i2c.c
index ca59456..6d1bb03 100644
--- a/hw/i2c/bitbang_i2c.c
+++ b/hw/i2c/bitbang_i2c.c
@@ -46,7 +46,7 @@ typedef enum bitbang_i2c_state {
} bitbang_i2c_state;
struct bitbang_i2c_interface {
- i2c_bus *bus;
+ I2CBus *bus;
bitbang_i2c_state state;
int last_data;
int last_clock;
@@ -170,7 +170,7 @@ int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level)
abort();
}
-bitbang_i2c_interface *bitbang_i2c_init(i2c_bus *bus)
+bitbang_i2c_interface *bitbang_i2c_init(I2CBus *bus)
{
bitbang_i2c_interface *s;
@@ -213,7 +213,7 @@ static int gpio_i2c_init(SysBusDevice *sbd)
{
DeviceState *dev = DEVICE(sbd);
GPIOI2CState *s = GPIO_I2C(dev);
- i2c_bus *bus;
+ I2CBus *bus;
memory_region_init(&s->dummy_iomem, OBJECT(s), "gpio_i2c", 0);
sysbus_init_mmio(sbd, &s->dummy_iomem);
diff --git a/hw/i2c/bitbang_i2c.h b/hw/i2c/bitbang_i2c.h
index 2866ac3..3a7126d 100644
--- a/hw/i2c/bitbang_i2c.h
+++ b/hw/i2c/bitbang_i2c.h
@@ -8,7 +8,7 @@ typedef struct bitbang_i2c_interface bitbang_i2c_interface;
#define BITBANG_I2C_SDA 0
#define BITBANG_I2C_SCL 1
-bitbang_i2c_interface *bitbang_i2c_init(i2c_bus *bus);
+bitbang_i2c_interface *bitbang_i2c_init(I2CBus *bus);
int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level);
#endif
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index c97e7f7..efd8b4f 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -9,7 +9,7 @@
#include "hw/i2c/i2c.h"
-struct i2c_bus
+struct I2CBus
{
BusState qbus;
I2CSlave *current_dev;
@@ -23,24 +23,24 @@ static Property i2c_props[] = {
};
#define TYPE_I2C_BUS "i2c-bus"
-#define I2C_BUS(obj) OBJECT_CHECK(i2c_bus, (obj), TYPE_I2C_BUS)
+#define I2C_BUS(obj) OBJECT_CHECK(I2CBus, (obj), TYPE_I2C_BUS)
static const TypeInfo i2c_bus_info = {
.name = TYPE_I2C_BUS,
.parent = TYPE_BUS,
- .instance_size = sizeof(i2c_bus),
+ .instance_size = sizeof(I2CBus),
};
static void i2c_bus_pre_save(void *opaque)
{
- i2c_bus *bus = opaque;
+ I2CBus *bus = opaque;
bus->saved_address = bus->current_dev ? bus->current_dev->address : -1;
}
static int i2c_bus_post_load(void *opaque, int version_id)
{
- i2c_bus *bus = opaque;
+ I2CBus *bus = opaque;
/* The bus is loaded before attached devices, so load and save the
current device id. Devices will check themselves as loaded. */
@@ -56,15 +56,15 @@ static const VMStateDescription vmstate_i2c_bus = {
.pre_save = i2c_bus_pre_save,
.post_load = i2c_bus_post_load,
.fields = (VMStateField []) {
- VMSTATE_UINT8(saved_address, i2c_bus),
+ VMSTATE_UINT8(saved_address, I2CBus),
VMSTATE_END_OF_LIST()
}
};
/* Create a new I2C bus. */
-i2c_bus *i2c_init_bus(DeviceState *parent, const char *name)
+I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
{
- i2c_bus *bus;
+ I2CBus *bus;
bus = I2C_BUS(qbus_create(TYPE_I2C_BUS, parent, name));
vmstate_register(NULL, -1, &vmstate_i2c_bus, bus);
@@ -77,14 +77,14 @@ void i2c_set_slave_address(I2CSlave *dev, uint8_t address)
}
/* Return nonzero if bus is busy. */
-int i2c_bus_busy(i2c_bus *bus)
+int i2c_bus_busy(I2CBus *bus)
{
return bus->current_dev != NULL;
}
/* Returns non-zero if the address is not valid. */
/* TODO: Make this handle multiple masters. */
-int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv)
+int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
{
BusChild *kid;
I2CSlave *slave = NULL;
@@ -113,7 +113,7 @@ int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv)
return 0;
}
-void i2c_end_transfer(i2c_bus *bus)
+void i2c_end_transfer(I2CBus *bus)
{
I2CSlave *dev = bus->current_dev;
I2CSlaveClass *sc;
@@ -130,7 +130,7 @@ void i2c_end_transfer(i2c_bus *bus)
bus->current_dev = NULL;
}
-int i2c_send(i2c_bus *bus, uint8_t data)
+int i2c_send(I2CBus *bus, uint8_t data)
{
I2CSlave *dev = bus->current_dev;
I2CSlaveClass *sc;
@@ -147,7 +147,7 @@ int i2c_send(i2c_bus *bus, uint8_t data)
return -1;
}
-int i2c_recv(i2c_bus *bus)
+int i2c_recv(I2CBus *bus)
{
I2CSlave *dev = bus->current_dev;
I2CSlaveClass *sc;
@@ -164,7 +164,7 @@ int i2c_recv(i2c_bus *bus)
return -1;
}
-void i2c_nack(i2c_bus *bus)
+void i2c_nack(I2CBus *bus)
{
I2CSlave *dev = bus->current_dev;
I2CSlaveClass *sc;
@@ -182,7 +182,7 @@ void i2c_nack(i2c_bus *bus)
static int i2c_slave_post_load(void *opaque, int version_id)
{
I2CSlave *dev = opaque;
- i2c_bus *bus;
+ I2CBus *bus;
bus = I2C_BUS(qdev_get_parent_bus(DEVICE(dev)));
if (bus->saved_address == dev->address) {
bus->current_dev = dev;
@@ -210,7 +210,7 @@ static int i2c_slave_qdev_init(DeviceState *dev)
return sc->init(s);
}
-DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr)
+DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr)
{
DeviceState *dev;
diff --git a/hw/i2c/exynos4210_i2c.c b/hw/i2c/exynos4210_i2c.c
index ce5f849..fb99dfd 100644
--- a/hw/i2c/exynos4210_i2c.c
+++ b/hw/i2c/exynos4210_i2c.c
@@ -83,7 +83,7 @@ typedef struct Exynos4210I2CState {
SysBusDevice parent_obj;
MemoryRegion iomem;
- i2c_bus *bus;
+ I2CBus *bus;
qemu_irq irq;
uint8_t i2ccon;
diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c
index 2d8e2b7..d63278d 100644
--- a/hw/i2c/omap_i2c.c
+++ b/hw/i2c/omap_i2c.c
@@ -30,7 +30,7 @@ typedef struct OMAPI2CState {
MemoryRegion iomem;
qemu_irq irq;
qemu_irq drq[2];
- i2c_bus *bus;
+ I2CBus *bus;
uint8_t revision;
void *iclk;
@@ -491,7 +491,7 @@ static void omap_i2c_register_types(void)
type_register_static(&omap_i2c_info);
}
-i2c_bus *omap_i2c_bus(DeviceState *omap_i2c)
+I2CBus *omap_i2c_bus(DeviceState *omap_i2c)
{
OMAPI2CState *s = OMAP_I2C(omap_i2c);
return s->bus;
diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c
index c98e447..9f50067 100644
--- a/hw/i2c/pm_smbus.c
+++ b/hw/i2c/pm_smbus.c
@@ -59,7 +59,7 @@ static void smb_transaction(PMSMBus *s)
uint8_t read = s->smb_addr & 0x01;
uint8_t cmd = s->smb_cmd;
uint8_t addr = s->smb_addr >> 1;
- i2c_bus *bus = s->smbus;
+ I2CBus *bus = s->smbus;
SMBUS_DPRINTF("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
/* Transaction isn't exec if STS_DEV_ERR bit set */
diff --git a/hw/i2c/smbus.c b/hw/i2c/smbus.c
index 25d2d04..3febf3c 100644
--- a/hw/i2c/smbus.c
+++ b/hw/i2c/smbus.c
@@ -208,13 +208,13 @@ static int smbus_device_init(I2CSlave *i2c)
}
/* Master device commands. */
-void smbus_quick_command(i2c_bus *bus, uint8_t addr, int read)
+void smbus_quick_command(I2CBus *bus, uint8_t addr, int read)
{
i2c_start_transfer(bus, addr, read);
i2c_end_transfer(bus);
}
-uint8_t smbus_receive_byte(i2c_bus *bus, uint8_t addr)
+uint8_t smbus_receive_byte(I2CBus *bus, uint8_t addr)
{
uint8_t data;
@@ -225,14 +225,14 @@ uint8_t smbus_receive_byte(i2c_bus *bus, uint8_t addr)
return data;
}
-void smbus_send_byte(i2c_bus *bus, uint8_t addr, uint8_t data)
+void smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data)
{
i2c_start_transfer(bus, addr, 0);
i2c_send(bus, data);
i2c_end_transfer(bus);
}
-uint8_t smbus_read_byte(i2c_bus *bus, uint8_t addr, uint8_t command)
+uint8_t smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command)
{
uint8_t data;
i2c_start_transfer(bus, addr, 0);
@@ -244,7 +244,7 @@ uint8_t smbus_read_byte(i2c_bus *bus, uint8_t addr, uint8_t command)
return data;
}
-void smbus_write_byte(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t data)
+void smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data)
{
i2c_start_transfer(bus, addr, 0);
i2c_send(bus, command);
@@ -252,7 +252,7 @@ void smbus_write_byte(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t data)
i2c_end_transfer(bus);
}
-uint16_t smbus_read_word(i2c_bus *bus, uint8_t addr, uint8_t command)
+uint16_t smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command)
{
uint16_t data;
i2c_start_transfer(bus, addr, 0);
@@ -265,7 +265,7 @@ uint16_t smbus_read_word(i2c_bus *bus, uint8_t addr, uint8_t command)
return data;
}
-void smbus_write_word(i2c_bus *bus, uint8_t addr, uint8_t command, uint16_t data)
+void smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data)
{
i2c_start_transfer(bus, addr, 0);
i2c_send(bus, command);
@@ -274,7 +274,7 @@ void smbus_write_word(i2c_bus *bus, uint8_t addr, uint8_t command, uint16_t data
i2c_end_transfer(bus);
}
-int smbus_read_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data)
+int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data)
{
int len;
int i;
@@ -292,7 +292,7 @@ int smbus_read_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data)
return len;
}
-void smbus_write_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data,
+void smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
int len)
{
int i;
diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c
index 0218f8a..86f35c1 100644
--- a/hw/i2c/smbus_eeprom.c
+++ b/hw/i2c/smbus_eeprom.c
@@ -139,7 +139,7 @@ static void smbus_eeprom_register_types(void)
type_init(smbus_eeprom_register_types)
-void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom,
+void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom,
const uint8_t *eeprom_spd, int eeprom_spd_size)
{
int i;
diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
index 8d47eaf..295b62e 100644
--- a/hw/i2c/smbus_ich9.c
+++ b/hw/i2c/smbus_ich9.c
@@ -108,7 +108,7 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data)
dc->cannot_instantiate_with_device_add_yet = true;
}
-i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
+I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
{
PCIDevice *d =
pci_create_simple_multifunction(bus, devfn, true, TYPE_ICH9_SMB_DEVICE);
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
index 02e9f17..3c0c2c1 100644
--- a/hw/i2c/versatile_i2c.c
+++ b/hw/i2c/versatile_i2c.c
@@ -81,7 +81,7 @@ static int versatile_i2c_init(SysBusDevice *sbd)
{
DeviceState *dev = DEVICE(sbd);
VersatileI2CState *s = VERSATILE_I2C(dev);
- i2c_bus *bus;
+ I2CBus *bus;
bus = i2c_init_bus(dev, "i2c");
s->bitbang = bitbang_i2c_init(bus);
diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index 20b6457..59373aa 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -268,9 +268,9 @@ static void kvm_pit_realizefn(DeviceState *dev, Error **errp)
return;
}
switch (s->lost_tick_policy) {
- case LOST_TICK_DELAY:
+ case LOST_TICK_POLICY_DELAY:
break; /* enabled by default */
- case LOST_TICK_DISCARD:
+ case LOST_TICK_POLICY_DISCARD:
if (kvm_check_extension(kvm_state, KVM_CAP_REINJECT_CONTROL)) {
struct kvm_reinject_control control = { .pit_reinject = 0 };
@@ -298,9 +298,9 @@ static void kvm_pit_realizefn(DeviceState *dev, Error **errp)
}
static Property kvm_pit_properties[] = {
- DEFINE_PROP_HEX32("iobase", PITCommonState, iobase, -1),
+ DEFINE_PROP_UINT32("iobase", PITCommonState, iobase, -1),
DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", KVMPITState,
- lost_tick_policy, LOST_TICK_DELAY),
+ lost_tick_policy, LOST_TICK_POLICY_DELAY),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 1acd2b2..d5dc1ef 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -236,7 +236,7 @@ static void pc_init1(QEMUMachineInitArgs *args,
}
if (pci_enabled && acpi_enabled) {
- i2c_bus *smbus;
+ I2CBus *smbus;
smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
/* TODO: Populate SPD eeprom data. */
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index afc24d4..d2cabc1 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -104,8 +104,8 @@ ISADevice *isa_ide_init(ISABus *bus, int iobase, int iobase2, int isairq,
}
static Property isa_ide_properties[] = {
- DEFINE_PROP_HEX32("iobase", ISAIDEState, iobase, 0x1f0),
- DEFINE_PROP_HEX32("iobase2", ISAIDEState, iobase2, 0x3f6),
+ DEFINE_PROP_UINT32("iobase", ISAIDEState, iobase, 0x1f0),
+ DEFINE_PROP_UINT32("iobase2", ISAIDEState, iobase2, 0x3f6),
DEFINE_PROP_UINT32("irq", ISAIDEState, isairq, 14),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 18c4b7e..6e475e6 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -206,7 +206,7 @@ static int ide_drive_initfn(IDEDevice *dev)
#define DEFINE_IDE_DEV_PROPERTIES() \
DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), \
DEFINE_PROP_STRING("ver", IDEDrive, dev.version), \
- DEFINE_PROP_HEX64("wwn", IDEDrive, dev.wwn, 0), \
+ DEFINE_PROP_UINT64("wwn", IDEDrive, dev.wwn, 0), \
DEFINE_PROP_STRING("serial", IDEDrive, dev.serial),\
DEFINE_PROP_STRING("model", IDEDrive, dev.model)
diff --git a/hw/input/lm832x.c b/hw/input/lm832x.c
index f583cf0..4ae1cd9 100644
--- a/hw/input/lm832x.c
+++ b/hw/input/lm832x.c
@@ -23,8 +23,12 @@
#include "qemu/timer.h"
#include "ui/console.h"
+#define TYPE_LM8323 "lm8323"
+#define LM8323(obj) OBJECT_CHECK(LM823KbdState, (obj), TYPE_LM8323)
+
typedef struct {
- I2CSlave i2c;
+ I2CSlave parent_obj;
+
uint8_t i2c_dir;
uint8_t i2c_cycle;
uint8_t reg;
@@ -380,7 +384,7 @@ static void lm_kbd_write(LM823KbdState *s, int reg, int byte, uint8_t value)
static void lm_i2c_event(I2CSlave *i2c, enum i2c_event event)
{
- LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
+ LM823KbdState *s = LM8323(i2c);
switch (event) {
case I2C_START_RECV:
@@ -396,14 +400,14 @@ static void lm_i2c_event(I2CSlave *i2c, enum i2c_event event)
static int lm_i2c_rx(I2CSlave *i2c)
{
- LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
+ LM823KbdState *s = LM8323(i2c);
return lm_kbd_read(s, s->reg, s->i2c_cycle ++);
}
static int lm_i2c_tx(I2CSlave *i2c, uint8_t data)
{
- LM823KbdState *s = (LM823KbdState *) i2c;
+ LM823KbdState *s = LM8323(i2c);
if (!s->i2c_cycle)
s->reg = data;
@@ -431,7 +435,7 @@ static const VMStateDescription vmstate_lm_kbd = {
.minimum_version_id_old = 0,
.post_load = lm_kbd_post_load,
.fields = (VMStateField []) {
- VMSTATE_I2C_SLAVE(i2c, LM823KbdState),
+ VMSTATE_I2C_SLAVE(parent_obj, LM823KbdState),
VMSTATE_UINT8(i2c_dir, LM823KbdState),
VMSTATE_UINT8(i2c_cycle, LM823KbdState),
VMSTATE_UINT8(reg, LM823KbdState),
@@ -460,13 +464,13 @@ static const VMStateDescription vmstate_lm_kbd = {
static int lm8323_init(I2CSlave *i2c)
{
- LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
+ LM823KbdState *s = LM8323(i2c);
s->model = 0x8323;
s->pwm.tm[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm0_tick, s);
s->pwm.tm[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm1_tick, s);
s->pwm.tm[2] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm2_tick, s);
- qdev_init_gpio_out(&i2c->qdev, &s->nirq, 1);
+ qdev_init_gpio_out(DEVICE(i2c), &s->nirq, 1);
lm_kbd_reset(s);
@@ -476,7 +480,7 @@ static int lm8323_init(I2CSlave *i2c)
void lm832x_key_event(DeviceState *dev, int key, int state)
{
- LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, I2C_SLAVE(dev));
+ LM823KbdState *s = LM8323(dev);
if ((s->status & INT_ERROR) && (s->error & ERR_FIFOOVR))
return;
@@ -507,7 +511,7 @@ static void lm8323_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo lm8323_info = {
- .name = "lm8323",
+ .name = TYPE_LM8323,
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(LM823KbdState),
.class_init = lm8323_class_init,
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 93eaa6b..955b8d4 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -189,7 +189,7 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu)
}
s->last_active[irq][cpu] = s->running_irq[cpu];
- if (s->revision == REV_11MPCORE) {
+ if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
/* Clear pending flags for both level and edge triggered interrupts.
* Level triggered IRQs will be reasserted once they become inactive.
*/
diff --git a/hw/intc/i8259_common.c b/hw/intc/i8259_common.c
index 9d29399..61381c4 100644
--- a/hw/intc/i8259_common.c
+++ b/hw/intc/i8259_common.c
@@ -123,9 +123,9 @@ static const VMStateDescription vmstate_pic_common = {
};
static Property pic_properties_common[] = {
- DEFINE_PROP_HEX32("iobase", PICCommonState, iobase, -1),
- DEFINE_PROP_HEX32("elcr_addr", PICCommonState, elcr_addr, -1),
- DEFINE_PROP_HEX8("elcr_mask", PICCommonState, elcr_mask, -1),
+ DEFINE_PROP_UINT32("iobase", PICCommonState, iobase, -1),
+ DEFINE_PROP_UINT32("elcr_addr", PICCommonState, elcr_addr, -1),
+ DEFINE_PROP_UINT8("elcr_mask", PICCommonState, elcr_mask, -1),
DEFINE_PROP_BIT("master", PICCommonState, master, 0, false),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/ipack/Makefile.objs b/hw/ipack/Makefile.objs
new file mode 100644
index 0000000..8b9bdcb
--- /dev/null
+++ b/hw/ipack/Makefile.objs
@@ -0,0 +1,2 @@
+common-obj-$(CONFIG_IPACK) += ipack.o
+common-obj-$(CONFIG_IPACK) += tpci200.o
diff --git a/hw/char/ipack.c b/hw/ipack/ipack.c
index b7e45be..ed63d2a 100644
--- a/hw/char/ipack.c
+++ b/hw/ipack/ipack.c
@@ -8,7 +8,7 @@
* later version.
*/
-#include "ipack.h"
+#include "hw/ipack/ipack.h"
IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot)
{
@@ -34,37 +34,39 @@ void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size,
bus->set_irq = handler;
}
-static int ipack_device_dev_init(DeviceState *qdev)
+static void ipack_device_realize(DeviceState *dev, Error **errp)
{
- IPackBus *bus = IPACK_BUS(qdev_get_parent_bus(qdev));
- IPackDevice *dev = IPACK_DEVICE(qdev);
+ IPackDevice *idev = IPACK_DEVICE(dev);
+ IPackBus *bus = IPACK_BUS(qdev_get_parent_bus(dev));
IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev);
- if (dev->slot < 0) {
- dev->slot = bus->free_slot;
+ if (idev->slot < 0) {
+ idev->slot = bus->free_slot;
}
- if (dev->slot >= bus->n_slots) {
- return -1;
+ if (idev->slot >= bus->n_slots) {
+ error_setg(errp, "Only %" PRIu8 " slots available.", bus->n_slots);
+ return;
}
- bus->free_slot = dev->slot + 1;
+ bus->free_slot = idev->slot + 1;
- dev->irq = qemu_allocate_irqs(bus->set_irq, dev, 2);
+ idev->irq = qemu_allocate_irqs(bus->set_irq, idev, 2);
- return k->init(dev);
+ k->realize(dev, errp);
}
-static int ipack_device_dev_exit(DeviceState *qdev)
+static void ipack_device_unrealize(DeviceState *dev, Error **errp)
{
- IPackDevice *dev = IPACK_DEVICE(qdev);
+ IPackDevice *idev = IPACK_DEVICE(dev);
IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev);
+ Error *err = NULL;
- if (k->exit) {
- k->exit(dev);
+ if (k->unrealize) {
+ k->unrealize(dev, &err);
+ error_propagate(errp, err);
+ return;
}
- qemu_free_irqs(dev->irq);
-
- return 0;
+ qemu_free_irqs(idev->irq);
}
static Property ipack_device_props[] = {
@@ -75,10 +77,11 @@ static Property ipack_device_props[] = {
static void ipack_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
+
set_bit(DEVICE_CATEGORY_INPUT, k->categories);
k->bus_type = TYPE_IPACK_BUS;
- k->init = ipack_device_dev_init;
- k->exit = ipack_device_dev_exit;
+ k->realize = ipack_device_realize;
+ k->unrealize = ipack_device_unrealize;
k->props = ipack_device_props;
}
diff --git a/hw/char/tpci200.c b/hw/ipack/tpci200.c
index a49d2ed..e1b69b4 100644
--- a/hw/char/tpci200.c
+++ b/hw/ipack/tpci200.c
@@ -8,7 +8,7 @@
* later version.
*/
-#include "ipack.h"
+#include "hw/ipack/ipack.h"
#include "hw/pci/pci.h"
#include "qemu/bitops.h"
#include <stdio.h>
diff --git a/hw/isa/pc87312.c b/hw/isa/pc87312.c
index 46a23fb..b352b49 100644
--- a/hw/isa/pc87312.c
+++ b/hw/isa/pc87312.c
@@ -369,7 +369,7 @@ static const VMStateDescription vmstate_pc87312 = {
};
static Property pc87312_properties[] = {
- DEFINE_PROP_HEX32("iobase", PC87312State, iobase, 0x398),
+ DEFINE_PROP_UINT32("iobase", PC87312State, iobase, 0x398),
DEFINE_PROP_UINT8("config", PC87312State, config, 1),
DEFINE_PROP_END_OF_LIST()
};
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index e639357..1a93afd 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -369,8 +369,8 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
return 0;
}
-i2c_bus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
- qemu_irq sci_irq)
+I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
+ qemu_irq sci_irq)
{
PCIDevice *dev;
VT686PMState *s;
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index 9ef3a97..e1551aa 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -276,7 +276,7 @@ static void mips_fulong2e_init(QEMUMachineInitArgs *args)
qemu_irq *cpu_exit_irq;
PCIBus *pci_bus;
ISABus *isa_bus;
- i2c_bus *smbus;
+ I2CBus *smbus;
int i;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
MIPSCPU *cpu;
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 05c8771..ac5ec44 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -900,7 +900,7 @@ void mips_malta_init(QEMUMachineInitArgs *args)
qemu_irq *isa_irq;
qemu_irq *cpu_exit_irq;
int piix4_devfn;
- i2c_bus *smbus;
+ I2CBus *smbus;
int i;
DriveInfo *dinfo;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 627adb9..6a56b07 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -249,7 +249,7 @@ static void applesmc_isa_realize(DeviceState *dev, Error **errp)
}
static Property applesmc_isa_properties[] = {
- DEFINE_PROP_HEX32("iobase", AppleSMCState, iobase,
+ DEFINE_PROP_UINT32("iobase", AppleSMCState, iobase,
APPLESMC_DEFAULT_IOBASE),
DEFINE_PROP_STRING("osk", AppleSMCState, osk),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/misc/debugexit.c b/hw/misc/debugexit.c
index 9db5680..69a1b00 100644
--- a/hw/misc/debugexit.c
+++ b/hw/misc/debugexit.c
@@ -47,8 +47,8 @@ static void debug_exit_realizefn(DeviceState *d, Error **errp)
}
static Property debug_exit_properties[] = {
- DEFINE_PROP_HEX32("iobase", ISADebugExitState, iobase, 0x501),
- DEFINE_PROP_HEX32("iosize", ISADebugExitState, iosize, 0x02),
+ DEFINE_PROP_UINT32("iobase", ISADebugExitState, iobase, 0x501),
+ DEFINE_PROP_UINT32("iosize", ISADebugExitState, iosize, 0x02),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/misc/eccmemctl.c b/hw/misc/eccmemctl.c
index 96a69d4..549431c 100644
--- a/hw/misc/eccmemctl.c
+++ b/hw/misc/eccmemctl.c
@@ -314,7 +314,7 @@ static int ecc_init1(SysBusDevice *dev)
}
static Property ecc_properties[] = {
- DEFINE_PROP_HEX32("version", ECCState, version, -1),
+ DEFINE_PROP_UINT32("version", ECCState, version, -1),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c
index 26b83ce..c660e58 100644
--- a/hw/net/ne2000-isa.c
+++ b/hw/net/ne2000-isa.c
@@ -86,7 +86,7 @@ static void isa_ne2000_realizefn(DeviceState *dev, Error **errp)
}
static Property ne2000_isa_properties[] = {
- DEFINE_PROP_HEX32("iobase", ISANE2000State, iobase, 0x300),
+ DEFINE_PROP_UINT32("iobase", ISANE2000State, iobase, 0x300),
DEFINE_PROP_UINT32("irq", ISANE2000State, isairq, 9),
DEFINE_NIC_PROPERTIES(ISANE2000State, ne2000.c),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index ee96c16..cb36dc2 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -584,8 +584,8 @@ static void fw_cfg_realize(DeviceState *dev, Error **errp)
}
static Property fw_cfg_properties[] = {
- DEFINE_PROP_HEX32("ctl_iobase", FWCfgState, ctl_iobase, -1),
- DEFINE_PROP_HEX32("data_iobase", FWCfgState, data_iobase, -1),
+ DEFINE_PROP_UINT32("ctl_iobase", FWCfgState, ctl_iobase, -1),
+ DEFINE_PROP_UINT32("data_iobase", FWCfgState, data_iobase, -1),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/pci/pci-hotplug-old.c b/hw/pci/pci-hotplug-old.c
index 8dbc3c1..cf2caeb 100644
--- a/hw/pci/pci-hotplug-old.c
+++ b/hw/pci/pci-hotplug-old.c
@@ -90,7 +90,7 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
qemu_opt_set(opts, "type", "nic");
ret = net_client_init(opts, 0, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return NULL;
@@ -322,7 +322,7 @@ static int pci_device_hot_remove(Monitor *mon, const char *pci_addr)
}
qdev_unplug(&d->qdev, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
monitor_printf(mon, "%s\n", error_get_pretty(local_err));
error_free(local_err);
return -1;
diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 2dd5284..ea747f0 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -10,9 +10,9 @@ obj-y += ppc4xx_pci.o
# PReP
obj-$(CONFIG_PREP) += prep.o
# OldWorld PowerMac
-obj-y += mac_oldworld.o
+obj-$(CONFIG_MAC) += mac_oldworld.o
# NewWorld PowerMac
-obj-y += mac_newworld.o
+obj-$(CONFIG_MAC) += mac_newworld.o
# e500
obj-$(CONFIG_E500) += e500.o mpc8544ds.o e500plat.o
obj-$(CONFIG_E500) += mpc8544_guts.o ppce500_spin.o
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index ec00300..4c7c3ae 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -651,14 +651,14 @@ static void spapr_phb_reset(DeviceState *qdev)
static Property spapr_phb_properties[] = {
DEFINE_PROP_INT32("index", sPAPRPHBState, index, -1),
- DEFINE_PROP_HEX64("buid", sPAPRPHBState, buid, -1),
- DEFINE_PROP_HEX32("liobn", sPAPRPHBState, dma_liobn, -1),
- DEFINE_PROP_HEX64("mem_win_addr", sPAPRPHBState, mem_win_addr, -1),
- DEFINE_PROP_HEX64("mem_win_size", sPAPRPHBState, mem_win_size,
- SPAPR_PCI_MMIO_WIN_SIZE),
- DEFINE_PROP_HEX64("io_win_addr", sPAPRPHBState, io_win_addr, -1),
- DEFINE_PROP_HEX64("io_win_size", sPAPRPHBState, io_win_size,
- SPAPR_PCI_IO_WIN_SIZE),
+ DEFINE_PROP_UINT64("buid", sPAPRPHBState, buid, -1),
+ DEFINE_PROP_UINT32("liobn", sPAPRPHBState, dma_liobn, -1),
+ DEFINE_PROP_UINT64("mem_win_addr", sPAPRPHBState, mem_win_addr, -1),
+ DEFINE_PROP_UINT64("mem_win_size", sPAPRPHBState, mem_win_size,
+ SPAPR_PCI_MMIO_WIN_SIZE),
+ DEFINE_PROP_UINT64("io_win_addr", sPAPRPHBState, io_win_addr, -1),
+ DEFINE_PROP_UINT64("io_win_size", sPAPRPHBState, io_win_size,
+ SPAPR_PCI_IO_WIN_SIZE),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 59570e2..e6e1ffd 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -2195,7 +2195,7 @@ static Property megasas_properties[] = {
DEFINE_PROP_UINT32("max_cmds", MegasasState, fw_cmds,
MEGASAS_DEFAULT_FRAMES),
DEFINE_PROP_STRING("hba_serial", MegasasState, hba_serial),
- DEFINE_PROP_HEX64("sas_address", MegasasState, sas_addr, 0),
+ DEFINE_PROP_UINT64("sas_address", MegasasState, sas_addr, 0),
#ifdef USE_MSIX
DEFINE_PROP_BIT("use_msix", MegasasState, flags,
MEGASAS_FLAG_USE_MSIX, false),
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index a8d0f15..b4fadd2 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2535,7 +2535,7 @@ static Property scsi_hd_properties[] = {
SCSI_DISK_F_REMOVABLE, false),
DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
SCSI_DISK_F_DPOFUA, false),
- DEFINE_PROP_HEX64("wwn", SCSIDiskState, wwn, 0),
+ DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
DEFAULT_MAX_UNMAP_SIZE),
DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
@@ -2583,7 +2583,7 @@ static const TypeInfo scsi_hd_info = {
static Property scsi_cd_properties[] = {
DEFINE_SCSI_DISK_PROPERTIES(),
- DEFINE_PROP_HEX64("wwn", SCSIDiskState, wwn, 0),
+ DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
DEFINE_PROP_END_OF_LIST(),
};
@@ -2646,7 +2646,7 @@ static Property scsi_disk_properties[] = {
SCSI_DISK_F_REMOVABLE, false),
DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
SCSI_DISK_F_DPOFUA, false),
- DEFINE_PROP_HEX64("wwn", SCSIDiskState, wwn, 0),
+ DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
DEFAULT_MAX_UNMAP_SIZE),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index a0b90ba..843e697 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1233,9 +1233,9 @@ const VMStateDescription sdhci_vmstate = {
/* Capabilities registers provide information on supported features of this
* specific host controller implementation */
static Property sdhci_properties[] = {
- DEFINE_PROP_HEX32("capareg", SDHCIState, capareg,
+ DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
SDHC_CAPAB_REG_DEFAULT),
- DEFINE_PROP_HEX32("maxcurr", SDHCIState, maxcurr, 0),
+ DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/timer/ds1338.c b/hw/timer/ds1338.c
index 8987cdc..bb2f8ee 100644
--- a/hw/timer/ds1338.c
+++ b/hw/timer/ds1338.c
@@ -23,8 +23,12 @@
#define HOURS_PM 0x20
#define CTRL_OSF 0x20
-typedef struct {
- I2CSlave i2c;
+#define TYPE_DS1338 "ds1338"
+#define DS1338(obj) OBJECT_CHECK(DS1338State, (obj), TYPE_DS1338)
+
+typedef struct DS1338State {
+ I2CSlave parent_obj;
+
int64_t offset;
uint8_t wday_offset;
uint8_t nvram[NVRAM_SIZE];
@@ -38,7 +42,7 @@ static const VMStateDescription vmstate_ds1338 = {
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
- VMSTATE_I2C_SLAVE(i2c, DS1338State),
+ VMSTATE_I2C_SLAVE(parent_obj, DS1338State),
VMSTATE_INT64(offset, DS1338State),
VMSTATE_UINT8_V(wday_offset, DS1338State, 2),
VMSTATE_UINT8_ARRAY(nvram, DS1338State, NVRAM_SIZE),
@@ -90,7 +94,7 @@ static void inc_regptr(DS1338State *s)
static void ds1338_event(I2CSlave *i2c, enum i2c_event event)
{
- DS1338State *s = FROM_I2C_SLAVE(DS1338State, i2c);
+ DS1338State *s = DS1338(i2c);
switch (event) {
case I2C_START_RECV:
@@ -111,7 +115,7 @@ static void ds1338_event(I2CSlave *i2c, enum i2c_event event)
static int ds1338_recv(I2CSlave *i2c)
{
- DS1338State *s = FROM_I2C_SLAVE(DS1338State, i2c);
+ DS1338State *s = DS1338(i2c);
uint8_t res;
res = s->nvram[s->ptr];
@@ -121,7 +125,8 @@ static int ds1338_recv(I2CSlave *i2c)
static int ds1338_send(I2CSlave *i2c, uint8_t data)
{
- DS1338State *s = FROM_I2C_SLAVE(DS1338State, i2c);
+ DS1338State *s = DS1338(i2c);
+
if (s->addr_byte) {
s->ptr = data & (NVRAM_SIZE - 1);
s->addr_byte = false;
@@ -198,7 +203,7 @@ static int ds1338_init(I2CSlave *i2c)
static void ds1338_reset(DeviceState *dev)
{
- DS1338State *s = FROM_I2C_SLAVE(DS1338State, I2C_SLAVE(dev));
+ DS1338State *s = DS1338(dev);
/* The clock is running and synchronized with the host */
s->offset = 0;
@@ -222,7 +227,7 @@ static void ds1338_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo ds1338_info = {
- .name = "ds1338",
+ .name = TYPE_DS1338,
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(DS1338State),
.class_init = ds1338_class_init,
diff --git a/hw/timer/i8254.c b/hw/timer/i8254.c
index cdbf481..28152d8 100644
--- a/hw/timer/i8254.c
+++ b/hw/timer/i8254.c
@@ -342,7 +342,7 @@ static void pit_realizefn(DeviceState *dev, Error **err)
}
static Property pit_properties[] = {
- DEFINE_PROP_HEX32("iobase", PITCommonState, iobase, -1),
+ DEFINE_PROP_UINT32("iobase", PITCommonState, iobase, -1),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
index 3cfb18a..7cf8684 100644
--- a/hw/timer/m48t59.c
+++ b/hw/timer/m48t59.c
@@ -741,7 +741,7 @@ static int m48t59_init1(SysBusDevice *dev)
static Property m48t59_isa_properties[] = {
DEFINE_PROP_UINT32("size", M48t59ISAState, state.size, -1),
DEFINE_PROP_UINT32("model", M48t59ISAState, state.model, -1),
- DEFINE_PROP_HEX32( "io_base", M48t59ISAState, state.io_base, 0),
+ DEFINE_PROP_UINT32("io_base", M48t59ISAState, state.io_base, 0),
DEFINE_PROP_END_OF_LIST(),
};
@@ -766,7 +766,7 @@ static const TypeInfo m48t59_isa_info = {
static Property m48t59_properties[] = {
DEFINE_PROP_UINT32("size", M48t59SysBusState, state.size, -1),
DEFINE_PROP_UINT32("model", M48t59SysBusState, state.model, -1),
- DEFINE_PROP_HEX32( "io_base", M48t59SysBusState, state.io_base, 0),
+ DEFINE_PROP_UINT32("io_base", M48t59SysBusState, state.io_base, 0),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 6fb124f..8509309 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -185,7 +185,7 @@ static void rtc_periodic_timer(void *opaque)
if (s->cmos_data[RTC_REG_B] & REG_B_PIE) {
s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
#ifdef TARGET_I386
- if (s->lost_tick_policy == LOST_TICK_SLEW) {
+ if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {
if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT)
s->irq_reinject_on_ack_count = 0;
apic_reset_irq_delivered();
@@ -708,7 +708,7 @@ static int rtc_post_load(void *opaque, int version_id)
#ifdef TARGET_I386
if (version_id >= 2) {
- if (s->lost_tick_policy == LOST_TICK_SLEW) {
+ if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {
rtc_coalesced_timer_update(s);
}
}
@@ -749,7 +749,7 @@ static void rtc_notify_clock_reset(Notifier *notifier, void *data)
periodic_timer_update(s, now);
check_update_timer(s);
#ifdef TARGET_I386
- if (s->lost_tick_policy == LOST_TICK_SLEW) {
+ if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {
rtc_coalesced_timer_update(s);
}
#endif
@@ -774,7 +774,7 @@ static void rtc_reset(void *opaque)
qemu_irq_lower(s->irq);
#ifdef TARGET_I386
- if (s->lost_tick_policy == LOST_TICK_SLEW) {
+ if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {
s->irq_coalesced = 0;
}
#endif
@@ -835,11 +835,11 @@ static void rtc_realizefn(DeviceState *dev, Error **errp)
#ifdef TARGET_I386
switch (s->lost_tick_policy) {
- case LOST_TICK_SLEW:
+ case LOST_TICK_POLICY_SLEW:
s->coalesced_timer =
timer_new_ns(rtc_clock, rtc_coalesced_timer, s);
break;
- case LOST_TICK_DISCARD:
+ case LOST_TICK_POLICY_DISCARD:
break;
default:
error_setg(errp, "Invalid lost tick policy.");
@@ -890,7 +890,7 @@ ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
static Property mc146818rtc_properties[] = {
DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980),
DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", RTCState,
- lost_tick_policy, LOST_TICK_DISCARD),
+ lost_tick_policy, LOST_TICK_POLICY_DISCARD),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/timer/twl92230.c b/hw/timer/twl92230.c
index f3ea365..85d5990 100644
--- a/hw/timer/twl92230.c
+++ b/hw/timer/twl92230.c
@@ -27,8 +27,11 @@
#define VERBOSE 1
-typedef struct {
- I2CSlave i2c;
+#define TYPE_TWL92230 "twl92230"
+#define TWL92230(obj) OBJECT_CHECK(MenelausState, (obj), TYPE_TWL92230)
+
+typedef struct MenelausState {
+ I2CSlave parent_obj;
int firstbyte;
uint8_t reg;
@@ -127,7 +130,8 @@ static void menelaus_rtc_hz(void *opaque)
static void menelaus_reset(I2CSlave *i2c)
{
- MenelausState *s = (MenelausState *) i2c;
+ MenelausState *s = TWL92230(i2c);
+
s->reg = 0x00;
s->vcore[0] = 0x0c; /* XXX: X-loader needs 0x8c? check! */
@@ -492,8 +496,9 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value)
break;
case MENELAUS_DEVICE_OFF:
- if (value & 1)
- menelaus_reset(&s->i2c);
+ if (value & 1) {
+ menelaus_reset(I2C_SLAVE(s));
+ }
break;
case MENELAUS_OSC_CTRL:
@@ -708,7 +713,7 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value)
static void menelaus_event(I2CSlave *i2c, enum i2c_event event)
{
- MenelausState *s = (MenelausState *) i2c;
+ MenelausState *s = TWL92230(i2c);
if (event == I2C_START_SEND)
s->firstbyte = 1;
@@ -716,7 +721,8 @@ static void menelaus_event(I2CSlave *i2c, enum i2c_event event)
static int menelaus_tx(I2CSlave *i2c, uint8_t data)
{
- MenelausState *s = (MenelausState *) i2c;
+ MenelausState *s = TWL92230(i2c);
+
/* Interpret register address byte */
if (s->firstbyte) {
s->reg = data;
@@ -729,7 +735,7 @@ static int menelaus_tx(I2CSlave *i2c, uint8_t data)
static int menelaus_rx(I2CSlave *i2c)
{
- MenelausState *s = (MenelausState *) i2c;
+ MenelausState *s = TWL92230(i2c);
return menelaus_read(s, s->reg ++);
}
@@ -834,23 +840,24 @@ static const VMStateDescription vmstate_menelaus = {
VMSTATE_STRUCT(rtc.alm, MenelausState, 0, vmstate_menelaus_tm,
struct tm),
VMSTATE_UINT8(pwrbtn_state, MenelausState),
- VMSTATE_I2C_SLAVE(i2c, MenelausState),
+ VMSTATE_I2C_SLAVE(parent_obj, MenelausState),
VMSTATE_END_OF_LIST()
}
};
static int twl92230_init(I2CSlave *i2c)
{
- MenelausState *s = FROM_I2C_SLAVE(MenelausState, i2c);
+ DeviceState *dev = DEVICE(i2c);
+ MenelausState *s = TWL92230(i2c);
s->rtc.hz_tm = timer_new_ms(rtc_clock, menelaus_rtc_hz, s);
/* Three output pins plus one interrupt pin. */
- qdev_init_gpio_out(&i2c->qdev, s->out, 4);
+ qdev_init_gpio_out(dev, s->out, 4);
/* Three input pins plus one power-button pin. */
- qdev_init_gpio_in(&i2c->qdev, menelaus_gpio_set, 4);
+ qdev_init_gpio_in(dev, menelaus_gpio_set, 4);
- menelaus_reset(&s->i2c);
+ menelaus_reset(i2c);
return 0;
}
@@ -868,7 +875,7 @@ static void twl92230_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo twl92230_info = {
- .name = "twl92230",
+ .name = TYPE_TWL92230,
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(MenelausState),
.class_init = twl92230_class_init,
diff --git a/hw/usb/desc.c b/hw/usb/desc.c
index f133ddb..ab48691 100644
--- a/hw/usb/desc.c
+++ b/hw/usb/desc.c
@@ -759,7 +759,7 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
* We return the same value that a configured device would return if
* it used the first configuration.
*/
- if (config->bmAttributes & 0x40) {
+ if (config->bmAttributes & USB_CFG_ATT_SELFPOWER) {
data[0] |= 1 << USB_DEVICE_SELF_POWERED;
}
if (dev->remote_wakeup) {
diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c
index c5420eb..bfebfe9 100644
--- a/hw/usb/dev-audio.c
+++ b/hw/usb/dev-audio.c
@@ -224,7 +224,7 @@ static const USBDescDevice desc_device = {
.bNumInterfaces = 2,
.bConfigurationValue = DEV_CONFIG_VALUE,
.iConfiguration = STRING_CONFIG,
- .bmAttributes = 0xc0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
.bMaxPower = 0x32,
.nif = ARRAY_SIZE(desc_iface),
.ifs = desc_iface,
diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c
index 7f292b1..a9661d2 100644
--- a/hw/usb/dev-bluetooth.c
+++ b/hw/usb/dev-bluetooth.c
@@ -229,7 +229,7 @@ static const USBDescDevice desc_device_bluetooth = {
{
.bNumInterfaces = 2,
.bConfigurationValue = 1,
- .bmAttributes = 0xc0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
.bMaxPower = 0,
.nif = ARRAY_SIZE(desc_iface_bluetooth),
.ifs = desc_iface_bluetooth,
diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c
index 2966066..f36e617 100644
--- a/hw/usb/dev-hid.c
+++ b/hw/usb/dev-hid.c
@@ -202,7 +202,7 @@ static const USBDescDevice desc_device_mouse = {
.bNumInterfaces = 1,
.bConfigurationValue = 1,
.iConfiguration = STR_CONFIG_MOUSE,
- .bmAttributes = 0xa0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
.bMaxPower = 50,
.nif = 1,
.ifs = &desc_iface_mouse,
@@ -219,7 +219,7 @@ static const USBDescDevice desc_device_tablet = {
.bNumInterfaces = 1,
.bConfigurationValue = 1,
.iConfiguration = STR_CONFIG_TABLET,
- .bmAttributes = 0xa0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
.bMaxPower = 50,
.nif = 1,
.ifs = &desc_iface_tablet,
@@ -236,7 +236,7 @@ static const USBDescDevice desc_device_tablet2 = {
.bNumInterfaces = 1,
.bConfigurationValue = 1,
.iConfiguration = STR_CONFIG_TABLET,
- .bmAttributes = 0xa0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
.bMaxPower = 50,
.nif = 1,
.ifs = &desc_iface_tablet2,
@@ -253,7 +253,7 @@ static const USBDescDevice desc_device_keyboard = {
.bNumInterfaces = 1,
.bConfigurationValue = 1,
.iConfiguration = STR_CONFIG_KEYBOARD,
- .bmAttributes = 0xa0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
.bMaxPower = 50,
.nif = 1,
.ifs = &desc_iface_keyboard,
diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index 58647b4..bc03531 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -119,7 +119,8 @@ static const USBDescDevice desc_device_hub = {
{
.bNumInterfaces = 1,
.bConfigurationValue = 1,
- .bmAttributes = 0xe0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER |
+ USB_CFG_ATT_WAKEUP,
.nif = 1,
.ifs = &desc_iface_hub,
},
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 4c532b7..518d536 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -266,7 +266,7 @@ static const USBDescDevice desc_device_net = {
.bNumInterfaces = 2,
.bConfigurationValue = DEV_RNDIS_CONFIG_VALUE,
.iConfiguration = STRING_RNDIS,
- .bmAttributes = 0xc0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
.bMaxPower = 0x32,
.nif = ARRAY_SIZE(desc_iface_rndis),
.ifs = desc_iface_rndis,
@@ -274,7 +274,7 @@ static const USBDescDevice desc_device_net = {
.bNumInterfaces = 2,
.bConfigurationValue = DEV_CONFIG_VALUE,
.iConfiguration = STRING_CDC,
- .bmAttributes = 0xc0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
.bMaxPower = 0x32,
.nif = ARRAY_SIZE(desc_iface_cdc),
.ifs = desc_iface_cdc,
@@ -1391,7 +1391,7 @@ static USBDevice *usb_net_init(USBBus *bus, const char *cmdline)
qemu_opt_set(opts, "model", "usb");
idx = net_client_init(opts, 0, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return NULL;
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 0b150d4..d360614 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -144,7 +144,7 @@ static const USBDescDevice desc_device = {
{
.bNumInterfaces = 1,
.bConfigurationValue = 1,
- .bmAttributes = 0x80,
+ .bmAttributes = USB_CFG_ATT_ONE,
.bMaxPower = 50,
.nif = 1,
.ifs = &desc_iface0,
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 8c7a61e..470e69f 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -463,7 +463,8 @@ static const USBDescDevice desc_device = {
{
.bNumInterfaces = 1,
.bConfigurationValue = 1,
- .bmAttributes = 0xe0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER |
+ USB_CFG_ATT_WAKEUP,
.bMaxPower = 50,
.nif = 1,
.ifs = &desc_iface0,
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index c434c56..2852669 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -117,7 +117,7 @@ static const USBDescDevice desc_device_full = {
.bNumInterfaces = 1,
.bConfigurationValue = 1,
.iConfiguration = STR_CONFIG_FULL,
- .bmAttributes = 0xc0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
.nif = 1,
.ifs = &desc_iface_full,
},
@@ -152,7 +152,7 @@ static const USBDescDevice desc_device_high = {
.bNumInterfaces = 1,
.bConfigurationValue = 1,
.iConfiguration = STR_CONFIG_HIGH,
- .bmAttributes = 0xc0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
.nif = 1,
.ifs = &desc_iface_high,
},
@@ -189,7 +189,7 @@ static const USBDescDevice desc_device_super = {
.bNumInterfaces = 1,
.bConfigurationValue = 1,
.iConfiguration = STR_CONFIG_SUPER,
- .bmAttributes = 0xc0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
.nif = 1,
.ifs = &desc_iface_super,
},
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
index 997b715..9832385 100644
--- a/hw/usb/dev-uas.c
+++ b/hw/usb/dev-uas.c
@@ -286,7 +286,7 @@ static const USBDescDevice desc_device_high = {
.bNumInterfaces = 1,
.bConfigurationValue = 1,
.iConfiguration = STR_CONFIG_HIGH,
- .bmAttributes = 0xc0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
.nif = 1,
.ifs = &desc_iface_high,
},
@@ -302,7 +302,7 @@ static const USBDescDevice desc_device_super = {
.bNumInterfaces = 1,
.bConfigurationValue = 1,
.iConfiguration = STR_CONFIG_SUPER,
- .bmAttributes = 0xc0,
+ .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
.nif = 1,
.ifs = &desc_iface_super,
},
diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c
index 1b09235..1b73fd0 100644
--- a/hw/usb/dev-wacom.c
+++ b/hw/usb/dev-wacom.c
@@ -107,7 +107,7 @@ static const USBDescDevice desc_device_wacom = {
{
.bNumInterfaces = 1,
.bConfigurationValue = 1,
- .bmAttributes = 0x80,
+ .bmAttributes = USB_CFG_ATT_ONE,
.bMaxPower = 40,
.nif = 1,
.ifs = &desc_iface_wacom,
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index ad814b5..0820244 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -252,9 +252,11 @@ static bool uhci_queue_verify(UHCIQueue *queue, uint32_t qh_addr, UHCI_TD *td,
uint32_t td_addr, bool queuing)
{
UHCIAsync *first = QTAILQ_FIRST(&queue->asyncs);
+ uint32_t queue_token_addr = (queue->token >> 8) & 0x7f;
return queue->qh_addr == qh_addr &&
queue->token == uhci_queue_token(td) &&
+ queue_token_addr == queue->ep->dev->addr &&
(queuing || !(td->ctrl & TD_CTRL_ACTIVE) || first == NULL ||
first->td_addr == td_addr);
}
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 0fa814e..ef3177a 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -807,7 +807,7 @@ static inline int xhci_running(XHCIState *xhci)
static void xhci_die(XHCIState *xhci)
{
xhci->usbsts |= USBSTS_HCE;
- fprintf(stderr, "xhci: asserted controller error\n");
+ DPRINTF("xhci: asserted controller error\n");
}
static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v)
@@ -854,8 +854,8 @@ static void xhci_events_update(XHCIState *xhci, int v)
erdp = xhci_addr64(intr->erdp_low, intr->erdp_high);
if (erdp < intr->er_start ||
erdp >= (intr->er_start + TRB_SIZE*intr->er_size)) {
- fprintf(stderr, "xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp);
- fprintf(stderr, "xhci: ER[%d] at "DMA_ADDR_FMT" len %d\n",
+ DPRINTF("xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp);
+ DPRINTF("xhci: ER[%d] at "DMA_ADDR_FMT" len %d\n",
v, intr->er_start, intr->er_size);
xhci_die(xhci);
return;
@@ -923,7 +923,7 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v)
if (intr->er_full) {
DPRINTF("xhci_event(): ER full, queueing\n");
if (((intr->ev_buffer_put+1) % EV_QUEUE) == intr->ev_buffer_get) {
- fprintf(stderr, "xhci: event queue full, dropping event!\n");
+ DPRINTF("xhci: event queue full, dropping event!\n");
return;
}
intr->ev_buffer[intr->ev_buffer_put++] = *event;
@@ -936,8 +936,8 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v)
erdp = xhci_addr64(intr->erdp_low, intr->erdp_high);
if (erdp < intr->er_start ||
erdp >= (intr->er_start + TRB_SIZE*intr->er_size)) {
- fprintf(stderr, "xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp);
- fprintf(stderr, "xhci: ER[%d] at "DMA_ADDR_FMT" len %d\n",
+ DPRINTF("xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp);
+ DPRINTF("xhci: ER[%d] at "DMA_ADDR_FMT" len %d\n",
v, intr->er_start, intr->er_size);
xhci_die(xhci);
return;
@@ -954,7 +954,7 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v)
#endif
intr->er_full = 1;
if (((intr->ev_buffer_put+1) % EV_QUEUE) == intr->ev_buffer_get) {
- fprintf(stderr, "xhci: event queue full, dropping event!\n");
+ DPRINTF("xhci: event queue full, dropping event!\n");
return;
}
intr->ev_buffer[intr->ev_buffer_put++] = *event;
@@ -1072,7 +1072,7 @@ static void xhci_er_reset(XHCIState *xhci, int v)
}
/* cache the (sole) event ring segment location */
if (intr->erstsz != 1) {
- fprintf(stderr, "xhci: invalid value for ERSTSZ: %d\n", intr->erstsz);
+ DPRINTF("xhci: invalid value for ERSTSZ: %d\n", intr->erstsz);
xhci_die(xhci);
return;
}
@@ -1082,7 +1082,7 @@ static void xhci_er_reset(XHCIState *xhci, int v)
le32_to_cpus(&seg.addr_high);
le32_to_cpus(&seg.size);
if (seg.size < 16 || seg.size > 4096) {
- fprintf(stderr, "xhci: invalid value for segment size: %d\n", seg.size);
+ DPRINTF("xhci: invalid value for segment size: %d\n", seg.size);
xhci_die(xhci);
return;
}
@@ -1248,7 +1248,7 @@ static TRBCCode xhci_alloc_device_streams(XHCIState *xhci, unsigned int slotid,
r = usb_device_alloc_streams(eps[0]->dev, eps, nr_eps, req_nr_streams);
if (r != 0) {
- fprintf(stderr, "xhci: alloc streams failed\n");
+ DPRINTF("xhci: alloc streams failed\n");
return CC_RESOURCE_ERROR;
}
@@ -1532,7 +1532,7 @@ static TRBCCode xhci_stop_ep(XHCIState *xhci, unsigned int slotid,
assert(slotid >= 1 && slotid <= xhci->numslots);
if (epid < 1 || epid > 31) {
- fprintf(stderr, "xhci: bad ep %d\n", epid);
+ DPRINTF("xhci: bad ep %d\n", epid);
return CC_TRB_ERROR;
}
@@ -1544,7 +1544,7 @@ static TRBCCode xhci_stop_ep(XHCIState *xhci, unsigned int slotid,
}
if (xhci_ep_nuke_xfers(xhci, slotid, epid, CC_STOPPED) > 0) {
- fprintf(stderr, "xhci: FIXME: endpoint stopped w/ xfers running, "
+ DPRINTF("xhci: FIXME: endpoint stopped w/ xfers running, "
"data might be lost\n");
}
@@ -1569,7 +1569,7 @@ static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid,
assert(slotid >= 1 && slotid <= xhci->numslots);
if (epid < 1 || epid > 31) {
- fprintf(stderr, "xhci: bad ep %d\n", epid);
+ DPRINTF("xhci: bad ep %d\n", epid);
return CC_TRB_ERROR;
}
@@ -1583,13 +1583,13 @@ static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid,
epctx = slot->eps[epid-1];
if (epctx->state != EP_HALTED) {
- fprintf(stderr, "xhci: reset EP while EP %d not halted (%d)\n",
+ DPRINTF("xhci: reset EP while EP %d not halted (%d)\n",
epid, epctx->state);
return CC_CONTEXT_STATE_ERROR;
}
if (xhci_ep_nuke_xfers(xhci, slotid, epid, 0) > 0) {
- fprintf(stderr, "xhci: FIXME: endpoint reset w/ xfers running, "
+ DPRINTF("xhci: FIXME: endpoint reset w/ xfers running, "
"data might be lost\n");
}
@@ -1626,7 +1626,7 @@ static TRBCCode xhci_set_ep_dequeue(XHCIState *xhci, unsigned int slotid,
assert(slotid >= 1 && slotid <= xhci->numslots);
if (epid < 1 || epid > 31) {
- fprintf(stderr, "xhci: bad ep %d\n", epid);
+ DPRINTF("xhci: bad ep %d\n", epid);
return CC_TRB_ERROR;
}
@@ -1643,7 +1643,7 @@ static TRBCCode xhci_set_ep_dequeue(XHCIState *xhci, unsigned int slotid,
epctx = slot->eps[epid-1];
if (epctx->state != EP_STOPPED) {
- fprintf(stderr, "xhci: set EP dequeue pointer while EP %d not stopped\n", epid);
+ DPRINTF("xhci: set EP dequeue pointer while EP %d not stopped\n", epid);
return CC_CONTEXT_STATE_ERROR;
}
@@ -1685,7 +1685,7 @@ static int xhci_xfer_create_sgl(XHCITransfer *xfer, int in_xfer)
switch (TRB_TYPE(*trb)) {
case TR_DATA:
if ((!(trb->control & TRB_TR_DIR)) != (!in_xfer)) {
- fprintf(stderr, "xhci: data direction mismatch for TR_DATA\n");
+ DPRINTF("xhci: data direction mismatch for TR_DATA\n");
goto err;
}
/* fallthrough */
@@ -1695,7 +1695,7 @@ static int xhci_xfer_create_sgl(XHCITransfer *xfer, int in_xfer)
chunk = trb->status & 0x1ffff;
if (trb->control & TRB_TR_IDT) {
if (chunk > 8 || in_xfer) {
- fprintf(stderr, "xhci: invalid immediate data TRB\n");
+ DPRINTF("xhci: invalid immediate data TRB\n");
goto err;
}
qemu_sglist_add(&xfer->sgl, trb->addr, chunk);
@@ -1824,7 +1824,7 @@ static int xhci_setup_packet(XHCITransfer *xfer)
} else {
ep = xhci_epid_to_usbep(xhci, xfer->slotid, xfer->epid);
if (!ep) {
- fprintf(stderr, "xhci: slot %d has no device\n",
+ DPRINTF("xhci: slot %d has no device\n",
xfer->slotid);
return -1;
}
@@ -1887,7 +1887,7 @@ static int xhci_complete_packet(XHCITransfer *xfer)
xhci_stall_ep(xfer);
break;
default:
- fprintf(stderr, "%s: FIXME: status = %d\n", __func__,
+ DPRINTF("%s: FIXME: status = %d\n", __func__,
xfer->packet.status);
FIXME("unhandled USB_RET_*");
}
@@ -1911,21 +1911,21 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
/* do some sanity checks */
if (TRB_TYPE(*trb_setup) != TR_SETUP) {
- fprintf(stderr, "xhci: ep0 first TD not SETUP: %d\n",
+ DPRINTF("xhci: ep0 first TD not SETUP: %d\n",
TRB_TYPE(*trb_setup));
return -1;
}
if (TRB_TYPE(*trb_status) != TR_STATUS) {
- fprintf(stderr, "xhci: ep0 last TD not STATUS: %d\n",
+ DPRINTF("xhci: ep0 last TD not STATUS: %d\n",
TRB_TYPE(*trb_status));
return -1;
}
if (!(trb_setup->control & TRB_TR_IDT)) {
- fprintf(stderr, "xhci: Setup TRB doesn't have IDT set\n");
+ DPRINTF("xhci: Setup TRB doesn't have IDT set\n");
return -1;
}
if ((trb_setup->status & 0x1ffff) != 8) {
- fprintf(stderr, "xhci: Setup TRB has bad length (%d)\n",
+ DPRINTF("xhci: Setup TRB has bad length (%d)\n",
(trb_setup->status & 0x1ffff));
return -1;
}
@@ -1974,10 +1974,10 @@ static void xhci_calc_iso_kick(XHCIState *xhci, XHCITransfer *xfer,
xfer->mfindex_kick = asap;
}
} else {
- xfer->mfindex_kick = (xfer->trbs[0].control >> TRB_TR_FRAMEID_SHIFT)
- & TRB_TR_FRAMEID_MASK;
+ xfer->mfindex_kick = ((xfer->trbs[0].control >> TRB_TR_FRAMEID_SHIFT)
+ & TRB_TR_FRAMEID_MASK) << 3;
xfer->mfindex_kick |= mfindex & ~0x3fff;
- if (xfer->mfindex_kick < mfindex) {
+ if (xfer->mfindex_kick + 0x100 < mfindex) {
xfer->mfindex_kick += 0x4000;
}
}
@@ -2038,9 +2038,7 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
}
break;
default:
- fprintf(stderr, "xhci: unknown or unhandled EP "
- "(type %d, in %d, ep %02x)\n",
- epctx->type, xfer->in_xfer, xfer->epid);
+ trace_usb_xhci_unimplemented("endpoint type", epctx->type);
return -1;
}
@@ -2078,12 +2076,12 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
assert(epid >= 1 && epid <= 31);
if (!xhci->slots[slotid-1].enabled) {
- fprintf(stderr, "xhci: xhci_kick_ep for disabled slot %d\n", slotid);
+ DPRINTF("xhci: xhci_kick_ep for disabled slot %d\n", slotid);
return;
}
epctx = xhci->slots[slotid-1].eps[epid-1];
if (!epctx) {
- fprintf(stderr, "xhci: xhci_kick_ep for disabled endpoint %d,%d\n",
+ DPRINTF("xhci: xhci_kick_ep for disabled endpoint %d,%d\n",
epid, slotid);
return;
}
@@ -2188,14 +2186,14 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE;
ep = xfer->packet.ep;
} else {
- fprintf(stderr, "xhci: error firing CTL transfer\n");
+ DPRINTF("xhci: error firing CTL transfer\n");
}
} else {
if (xhci_fire_transfer(xhci, xfer, epctx) >= 0) {
epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE;
} else {
if (!xfer->timed_xfer) {
- fprintf(stderr, "xhci: error firing data transfer\n");
+ DPRINTF("xhci: error firing data transfer\n");
}
}
}
@@ -2298,7 +2296,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
xhci_dma_read_u32s(xhci, ictx, ictl_ctx, sizeof(ictl_ctx));
if (ictl_ctx[0] != 0x0 || ictl_ctx[1] != 0x3) {
- fprintf(stderr, "xhci: invalid input context control %08x %08x\n",
+ DPRINTF("xhci: invalid input context control %08x %08x\n",
ictl_ctx[0], ictl_ctx[1]);
return CC_TRB_ERROR;
}
@@ -2314,14 +2312,14 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
uport = xhci_lookup_uport(xhci, slot_ctx);
if (uport == NULL) {
- fprintf(stderr, "xhci: port not found\n");
+ DPRINTF("xhci: port not found\n");
return CC_TRB_ERROR;
}
trace_usb_xhci_slot_address(slotid, uport->path);
dev = uport->dev;
if (!dev || !dev->attached) {
- fprintf(stderr, "xhci: port %s not connected\n", uport->path);
+ DPRINTF("xhci: port %s not connected\n", uport->path);
return CC_USB_TRANSACTION_ERROR;
}
@@ -2330,7 +2328,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
continue;
}
if (xhci->slots[i].uport == uport) {
- fprintf(stderr, "xhci: port %s already assigned to slot %d\n",
+ DPRINTF("xhci: port %s already assigned to slot %d\n",
uport->path, i+1);
return CC_TRB_ERROR;
}
@@ -2414,7 +2412,7 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
xhci_dma_read_u32s(xhci, ictx, ictl_ctx, sizeof(ictl_ctx));
if ((ictl_ctx[0] & 0x3) != 0x0 || (ictl_ctx[1] & 0x3) != 0x1) {
- fprintf(stderr, "xhci: invalid input context control %08x %08x\n",
+ DPRINTF("xhci: invalid input context control %08x %08x\n",
ictl_ctx[0], ictl_ctx[1]);
return CC_TRB_ERROR;
}
@@ -2423,7 +2421,7 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
xhci_dma_read_u32s(xhci, octx, slot_ctx, sizeof(slot_ctx));
if (SLOT_STATE(slot_ctx[3]) < SLOT_ADDRESSED) {
- fprintf(stderr, "xhci: invalid slot state %08x\n", slot_ctx[3]);
+ DPRINTF("xhci: invalid slot state %08x\n", slot_ctx[3]);
return CC_CONTEXT_STATE_ERROR;
}
@@ -2496,7 +2494,7 @@ static TRBCCode xhci_evaluate_slot(XHCIState *xhci, unsigned int slotid,
xhci_dma_read_u32s(xhci, ictx, ictl_ctx, sizeof(ictl_ctx));
if (ictl_ctx[0] != 0x0 || ictl_ctx[1] & ~0x3) {
- fprintf(stderr, "xhci: invalid input context control %08x %08x\n",
+ DPRINTF("xhci: invalid input context control %08x %08x\n",
ictl_ctx[0], ictl_ctx[1]);
return CC_TRB_ERROR;
}
@@ -2575,11 +2573,11 @@ static unsigned int xhci_get_slot(XHCIState *xhci, XHCIEvent *event, XHCITRB *tr
unsigned int slotid;
slotid = (trb->control >> TRB_CR_SLOTID_SHIFT) & TRB_CR_SLOTID_MASK;
if (slotid < 1 || slotid > xhci->numslots) {
- fprintf(stderr, "xhci: bad slot id %d\n", slotid);
+ DPRINTF("xhci: bad slot id %d\n", slotid);
event->ccode = CC_TRB_ERROR;
return 0;
} else if (!xhci->slots[slotid-1].enabled) {
- fprintf(stderr, "xhci: slot id %d not enabled\n", slotid);
+ DPRINTF("xhci: slot id %d not enabled\n", slotid);
event->ccode = CC_SLOT_NOT_ENABLED_ERROR;
return 0;
}
@@ -2695,7 +2693,7 @@ static void xhci_process_commands(XHCIState *xhci)
}
}
if (i >= xhci->numslots) {
- fprintf(stderr, "xhci: no device slots available\n");
+ DPRINTF("xhci: no device slots available\n");
event.ccode = CC_NO_SLOTS_ERROR;
} else {
slotid = i+1;
@@ -2887,7 +2885,7 @@ static void xhci_reset(DeviceState *dev)
trace_usb_xhci_reset();
if (!(xhci->usbsts & USBSTS_HCH)) {
- fprintf(stderr, "xhci: reset while running!\n");
+ DPRINTF("xhci: reset while running!\n");
}
xhci->usbcmd = 0;
@@ -3065,7 +3063,7 @@ static void xhci_port_write(void *ptr, hwaddr reg,
/* windows does this for some reason, don't spam stderr */
break;
default:
- fprintf(stderr, "%s: ignore pls write (old %d, new %d)\n",
+ DPRINTF("%s: ignore pls write (old %d, new %d)\n",
__func__, old_pls, new_pls);
break;
}
@@ -3316,7 +3314,7 @@ static void xhci_doorbell_write(void *ptr, hwaddr reg,
trace_usb_xhci_doorbell_write(reg, val);
if (!xhci_running(xhci)) {
- fprintf(stderr, "xhci: wrote doorbell while xHC stopped or paused\n");
+ DPRINTF("xhci: wrote doorbell while xHC stopped or paused\n");
return;
}
@@ -3326,16 +3324,16 @@ static void xhci_doorbell_write(void *ptr, hwaddr reg,
if (val == 0) {
xhci_process_commands(xhci);
} else {
- fprintf(stderr, "xhci: bad doorbell 0 write: 0x%x\n",
+ DPRINTF("xhci: bad doorbell 0 write: 0x%x\n",
(uint32_t)val);
}
} else {
epid = val & 0xff;
streamid = (val >> 16) & 0xffff;
if (reg > xhci->numslots) {
- fprintf(stderr, "xhci: bad doorbell %d\n", (int)reg);
+ DPRINTF("xhci: bad doorbell %d\n", (int)reg);
} else if (epid > 31) {
- fprintf(stderr, "xhci: bad doorbell %d write: 0x%x\n",
+ DPRINTF("xhci: bad doorbell %d write: 0x%x\n",
(int)reg, (uint32_t)val);
} else {
xhci_kick_ep(xhci, reg, epid, streamid);
@@ -3636,7 +3634,7 @@ static int usb_xhci_post_load(void *opaque, int version_id)
slot->uport = xhci_lookup_uport(xhci, slot_ctx);
assert(slot->uport && slot->uport->dev);
- for (epid = 1; epid <= 32; epid++) {
+ for (epid = 1; epid <= 31; epid++) {
pctx = slot->ctx + 32 * epid;
xhci_dma_read_u32s(xhci, pctx, ep_ctx, sizeof(ep_ctx));
state = ep_ctx[0] & EP_STATE_MASK;
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index fd320cd8..57bed09 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -1324,8 +1324,8 @@ static Property usb_host_dev_properties[] = {
DEFINE_PROP_UINT32("hostbus", USBHostDevice, match.bus_num, 0),
DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr, 0),
DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
- DEFINE_PROP_HEX32("vendorid", USBHostDevice, match.vendor_id, 0),
- DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
+ DEFINE_PROP_UINT32("vendorid", USBHostDevice, match.vendor_id, 0),
+ DEFINE_PROP_UINT32("productid", USBHostDevice, match.product_id, 0),
DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames, 32),
DEFINE_PROP_INT32("bootindex", USBHostDevice, bootindex, -1),
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 30c9f2b..7b91841 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1063,7 +1063,7 @@ static const TypeInfo virtio_pci_info = {
/* virtio-blk-pci */
static Property virtio_blk_pci_properties[] = {
- DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
+ DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
@@ -1275,7 +1275,7 @@ static void balloon_pci_stats_set_poll_interval(Object *obj, struct Visitor *v,
static Property virtio_balloon_pci_properties[] = {
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
- DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
+ DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1376,7 +1376,7 @@ static Property virtio_serial_pci_properties[] = {
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
- DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
+ DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtIOSerialPCI, vdev.serial),
DEFINE_PROP_END_OF_LIST(),
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 806ae13..4b4df88 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -249,11 +249,14 @@ void float_raise( int8 flags STATUS_PARAM);
| Using these differs from negating an input or output before calling
| the muladd function in that this means that a NaN doesn't have its
| sign bit inverted before it is propagated.
+| We also support halving the result before rounding, as a special
+| case to support the ARM fused-sqrt-step instruction FRSQRTS.
*----------------------------------------------------------------------------*/
enum {
float_muladd_negate_c = 1,
float_muladd_negate_product = 2,
float_muladd_negate_result = 4,
+ float_muladd_halve_result = 8,
};
/*----------------------------------------------------------------------------
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
index bb9a1dd..5c1820f 100644
--- a/include/hw/arm/exynos4210.h
+++ b/include/hw/arm/exynos4210.h
@@ -97,7 +97,7 @@ typedef struct Exynos4210State {
MemoryRegion dram1_mem;
MemoryRegion boot_secondary;
MemoryRegion bootreg_mem;
- i2c_bus *i2c_if[EXYNOS4210_I2C_NUMBER];
+ I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
} Exynos4210State;
void exynos4210_write_secondary(ARMCPU *cpu,
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
index 188cda8..b9655ee 100644
--- a/include/hw/arm/omap.h
+++ b/include/hw/arm/omap.h
@@ -765,7 +765,7 @@ void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover);
void omap_mmc_enable(struct omap_mmc_s *s, int enable);
/* omap_i2c.c */
-i2c_bus *omap_i2c_bus(DeviceState *omap_i2c);
+I2CBus *omap_i2c_bus(DeviceState *omap_i2c);
# define cpu_is_omap310(cpu) (cpu->mpu_model == omap310)
# define cpu_is_omap1510(cpu) (cpu->mpu_model == omap1510)
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
index 7ca330a..c507906 100644
--- a/include/hw/arm/pxa.h
+++ b/include/hw/arm/pxa.h
@@ -116,7 +116,7 @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp,
typedef struct PXA2xxI2CState PXA2xxI2CState;
PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
qemu_irq irq, uint32_t page_size);
-i2c_bus *pxa2xx_i2c_bus(PXA2xxI2CState *s);
+I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s);
typedef struct PXA2xxI2SState PXA2xxI2SState;
typedef struct PXA2xxFIrState PXA2xxFIrState;
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index dd11532..7c3d6c8 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -65,12 +65,6 @@ int blkconf_geometry(BlockConf *conf, int *trans,
/* Hard disk geometry */
-#define BIOS_ATA_TRANSLATION_AUTO 0
-#define BIOS_ATA_TRANSLATION_NONE 1
-#define BIOS_ATA_TRANSLATION_LBA 2
-#define BIOS_ATA_TRANSLATION_LARGE 3
-#define BIOS_ATA_TRANSLATION_RECHS 4
-
void hd_geometry_guess(BlockDriverState *bs,
uint32_t *pcyls, uint32_t *pheads, uint32_t *psecs,
int *ptrans);
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
index 461392f..4986ebc 100644
--- a/include/hw/i2c/i2c.h
+++ b/include/hw/i2c/i2c.h
@@ -50,18 +50,16 @@ struct I2CSlave
uint8_t address;
};
-i2c_bus *i2c_init_bus(DeviceState *parent, const char *name);
+I2CBus *i2c_init_bus(DeviceState *parent, const char *name);
void i2c_set_slave_address(I2CSlave *dev, uint8_t address);
-int i2c_bus_busy(i2c_bus *bus);
-int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv);
-void i2c_end_transfer(i2c_bus *bus);
-void i2c_nack(i2c_bus *bus);
-int i2c_send(i2c_bus *bus, uint8_t data);
-int i2c_recv(i2c_bus *bus);
-
-#define FROM_I2C_SLAVE(type, dev) DO_UPCAST(type, i2c, dev)
-
-DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr);
+int i2c_bus_busy(I2CBus *bus);
+int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv);
+void i2c_end_transfer(I2CBus *bus);
+void i2c_nack(I2CBus *bus);
+int i2c_send(I2CBus *bus, uint8_t data);
+int i2c_recv(I2CBus *bus);
+
+DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr);
/* wm8750.c */
void wm8750_data_req_set(DeviceState *dev,
diff --git a/include/hw/i2c/pm_smbus.h b/include/hw/i2c/pm_smbus.h
index e3069bf..926603f 100644
--- a/include/hw/i2c/pm_smbus.h
+++ b/include/hw/i2c/pm_smbus.h
@@ -2,7 +2,7 @@
#define PM_SMBUS_H
typedef struct PMSMBus {
- i2c_bus *smbus;
+ I2CBus *smbus;
MemoryRegion io;
uint8_t smb_stat;
diff --git a/include/hw/i2c/smbus.h b/include/hw/i2c/smbus.h
index d764d75..63f0cc4 100644
--- a/include/hw/i2c/smbus.h
+++ b/include/hw/i2c/smbus.h
@@ -66,18 +66,18 @@ struct SMBusDevice {
};
/* Master device commands. */
-void smbus_quick_command(i2c_bus *bus, uint8_t addr, int read);
-uint8_t smbus_receive_byte(i2c_bus *bus, uint8_t addr);
-void smbus_send_byte(i2c_bus *bus, uint8_t addr, uint8_t data);
-uint8_t smbus_read_byte(i2c_bus *bus, uint8_t addr, uint8_t command);
-void smbus_write_byte(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t data);
-uint16_t smbus_read_word(i2c_bus *bus, uint8_t addr, uint8_t command);
-void smbus_write_word(i2c_bus *bus, uint8_t addr, uint8_t command, uint16_t data);
-int smbus_read_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data);
-void smbus_write_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data,
+void smbus_quick_command(I2CBus *bus, uint8_t addr, int read);
+uint8_t smbus_receive_byte(I2CBus *bus, uint8_t addr);
+void smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data);
+uint8_t smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command);
+void smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data);
+uint16_t smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command);
+void smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data);
+int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data);
+void smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
int len);
-void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom,
+void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom,
const uint8_t *eeprom_spd, int size);
#endif
diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
index 4a68b35..9e4a0e4 100644
--- a/include/hw/i386/ich9.h
+++ b/include/hw/i386/ich9.h
@@ -20,7 +20,7 @@ int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx);
PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin);
void ich9_lpc_pm_init(PCIDevice *pci_lpc);
PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus);
-i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
+I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
#define ICH9_CC_SIZE (16 * 1024) /* 16KB */
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 3e1e81b..9010246 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -165,9 +165,9 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
/* acpi_piix.c */
-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, FWCfgState *fw_cfg);
+I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
+ qemu_irq sci_irq, qemu_irq smi_irq,
+ int kvm_enabled, FWCfgState *fw_cfg);
void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
/* hpet.c */
diff --git a/hw/char/ipack.h b/include/hw/ipack/ipack.h
index f8dc0f2..e95ffe8 100644
--- a/hw/char/ipack.h
+++ b/include/hw/ipack/ipack.h
@@ -19,7 +19,9 @@ typedef struct IPackBus IPackBus;
#define IPACK_BUS(obj) OBJECT_CHECK(IPackBus, (obj), TYPE_IPACK_BUS)
struct IPackBus {
- BusState qbus;
+ /*< private >*/
+ BusState parent_obj;
+
/* All fields are private */
uint8_t n_slots;
uint8_t free_slot;
@@ -38,10 +40,12 @@ typedef struct IPackDeviceClass IPackDeviceClass;
OBJECT_GET_CLASS(IPackDeviceClass, (obj), TYPE_IPACK_DEVICE)
struct IPackDeviceClass {
+ /*< private >*/
DeviceClass parent_class;
+ /*< public >*/
- int (*init)(IPackDevice *dev);
- int (*exit)(IPackDevice *dev);
+ DeviceRealize realize;
+ DeviceUnrealize unrealize;
uint16_t (*io_read)(IPackDevice *dev, uint8_t addr);
void (*io_write)(IPackDevice *dev, uint8_t addr, uint16_t val);
@@ -60,7 +64,10 @@ struct IPackDeviceClass {
};
struct IPackDevice {
- DeviceState qdev;
+ /*< private >*/
+ DeviceState parent_obj;
+ /*< public >*/
+
int32_t slot;
/* IRQ objects for the IndustryPack INT0# and INT1# */
qemu_irq *irq;
diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h
index 6ef876d..471b5e9 100644
--- a/include/hw/isa/vt82c686.h
+++ b/include/hw/isa/vt82c686.h
@@ -5,7 +5,7 @@
ISABus *vt82c686b_init(PCIBus * bus, int devfn);
void vt82c686b_ac97_init(PCIBus *bus, int devfn);
void vt82c686b_mc97_init(PCIBus *bus, int devfn);
-i2c_bus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
- qemu_irq sci_irq);
+I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
+ qemu_irq sci_irq);
#endif
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 08d329d..276b336 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -217,7 +217,6 @@ struct PropertyInfo {
const char *name;
const char *legacy_name;
const char **enum_table;
- int (*parse)(DeviceState *dev, Property *prop, const char *str);
int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
ObjectPropertyAccessor *get;
ObjectPropertyAccessor *set;
diff --git a/include/hw/qdev-dma.h b/include/hw/qdev-dma.h
index 6812735..8cfb0f3 100644
--- a/include/hw/qdev-dma.h
+++ b/include/hw/qdev-dma.h
@@ -7,4 +7,4 @@
* See the COPYING file in the top-level directory.
*/
#define DEFINE_PROP_DMAADDR(_n, _s, _f, _d) \
- DEFINE_PROP_HEX64(_n, _s, _f, _d)
+ DEFINE_PROP_UINT64(_n, _s, _f, _d)
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 77c6f7c..0c0babf 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -12,9 +12,6 @@ extern PropertyInfo qdev_prop_uint16;
extern PropertyInfo qdev_prop_uint32;
extern PropertyInfo qdev_prop_int32;
extern PropertyInfo qdev_prop_uint64;
-extern PropertyInfo qdev_prop_hex8;
-extern PropertyInfo qdev_prop_hex32;
-extern PropertyInfo qdev_prop_hex64;
extern PropertyInfo qdev_prop_size;
extern PropertyInfo qdev_prop_string;
extern PropertyInfo qdev_prop_chr;
@@ -111,12 +108,6 @@ extern PropertyInfo qdev_prop_arraylen;
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_int32, int32_t)
#define DEFINE_PROP_UINT64(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
-#define DEFINE_PROP_HEX8(_n, _s, _f, _d) \
- DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex8, uint8_t)
-#define DEFINE_PROP_HEX32(_n, _s, _f, _d) \
- DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex32, uint32_t)
-#define DEFINE_PROP_HEX64(_n, _s, _f, _d) \
- DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex64, uint64_t)
#define DEFINE_PROP_SIZE(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_size, uint64_t)
#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \
@@ -168,8 +159,6 @@ extern PropertyInfo qdev_prop_arraylen;
/* Set properties between creation and init. */
void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
-void qdev_prop_parse(DeviceState *dev, const char *name, const char *value,
- Error **errp);
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_uint16(DeviceState *dev, const char *name, uint16_t value);
diff --git a/include/hw/usb.h b/include/hw/usb.h
index 3ef7af7..1919bdc 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -157,6 +157,11 @@
#define USB_DEV_CAP_USB2_EXT 0x02
#define USB_DEV_CAP_SUPERSPEED 0x03
+#define USB_CFG_ATT_ONE (1 << 7) /* should always be set */
+#define USB_CFG_ATT_SELFPOWER (1 << 6)
+#define USB_CFG_ATT_WAKEUP (1 << 5)
+#define USB_CFG_ATT_BATTERY (1 << 4)
+
#define USB_ENDPOINT_XFER_CONTROL 0
#define USB_ENDPOINT_XFER_ISOC 1
#define USB_ENDPOINT_XFER_BULK 2
diff --git a/include/qapi/string-output-visitor.h b/include/qapi/string-output-visitor.h
index ec81e42..d99717f 100644
--- a/include/qapi/string-output-visitor.h
+++ b/include/qapi/string-output-visitor.h
@@ -17,7 +17,7 @@
typedef struct StringOutputVisitor StringOutputVisitor;
-StringOutputVisitor *string_output_visitor_new(void);
+StringOutputVisitor *string_output_visitor_new(bool human);
void string_output_visitor_cleanup(StringOutputVisitor *v);
char *string_output_get_string(StringOutputVisitor *v);
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 17c2959..46c2bea 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -261,14 +261,6 @@ typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size)
typedef uint64_t pcibus_t;
-typedef enum LostTickPolicy {
- LOST_TICK_DISCARD,
- LOST_TICK_DELAY,
- LOST_TICK_MERGE,
- LOST_TICK_SLEW,
- LOST_TICK_MAX
-} LostTickPolicy;
-
typedef struct PCIHostDeviceAddress {
unsigned int domain;
unsigned int bus;
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 5b4e333..83c9b16 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -43,7 +43,7 @@ typedef struct QemuConsole QemuConsole;
typedef struct CharDriverState CharDriverState;
typedef struct MACAddr MACAddr;
typedef struct NetClientState NetClientState;
-typedef struct i2c_bus i2c_bus;
+typedef struct I2CBus I2CBus;
typedef struct ISABus ISABus;
typedef struct ISADevice ISADevice;
typedef struct SMBusDevice SMBusDevice;
diff --git a/include/qom/object.h b/include/qom/object.h
index e0ff212..9c7c361 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -946,12 +946,13 @@ void object_property_parse(Object *obj, const char *string,
* object_property_print:
* @obj: the object
* @name: the name of the property
+ * @human: if true, print for human consumption
* @errp: returns an error if this function fails
*
* Returns a string representation of the value of the property. The
* caller shall free the string.
*/
-char *object_property_print(Object *obj, const char *name,
+char *object_property_print(Object *obj, const char *name, bool human,
Error **errp);
/**
diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h
index 6aca8e4..28f4875 100644
--- a/include/sysemu/qtest.h
+++ b/include/sysemu/qtest.h
@@ -15,6 +15,7 @@
#define QTEST_H
#include "qemu-common.h"
+#include "qapi/error.h"
extern bool qtest_allowed;
@@ -26,7 +27,7 @@ static inline bool qtest_enabled(void)
bool qtest_driver(void);
int qtest_init_accel(void);
-void qtest_init(const char *qtest_chrdev, const char *qtest_log);
+void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);
static inline int qtest_available(void)
{
diff --git a/linux-user/alpha/syscall_nr.h b/linux-user/alpha/syscall_nr.h
index d52d76e..625f301 100644
--- a/linux-user/alpha/syscall_nr.h
+++ b/linux-user/alpha/syscall_nr.h
@@ -433,3 +433,10 @@
#define TARGET_NR_open_by_handle_at 498
#define TARGET_NR_clock_adjtime 499
#define TARGET_NR_syncfs 500
+#define TARGET_NR_setns 501
+#define TARGET_NR_accept4 502
+#define TARGET_NR_sendmmsg 503
+#define TARGET_NR_process_vm_readv 504
+#define TARGET_NR_process_vm_writev 505
+#define TARGET_NR_kcmp 506
+#define TARGET_NR_finit_module 507
diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h
index 42d6855..bef847c 100644
--- a/linux-user/arm/syscall_nr.h
+++ b/linux-user/arm/syscall_nr.h
@@ -378,3 +378,9 @@
#define TARGET_NR_open_by_handle_at (371)
#define TARGET_NR_clock_adjtime (372)
#define TARGET_NR_syncfs (373)
+#define TARGET_NR_sendmmsg (374)
+#define TARGET_NR_setns (375)
+#define TARGET_NR_process_vm_readv (376)
+#define TARGET_NR_process_vm_writev (377)
+#define TARGET_NR_kcmp (378)
+#define TARGET_NR_finit_module (379)
diff --git a/linux-user/cris/syscall_nr.h b/linux-user/cris/syscall_nr.h
index 98f1a0b..694bd02 100644
--- a/linux-user/cris/syscall_nr.h
+++ b/linux-user/cris/syscall_nr.h
@@ -335,3 +335,4 @@
#define TARGET_NR_inotify_init1 332
#define TARGET_NR_preadv 333
#define TARGET_NR_pwritev 334
+#define TARGET_NR_setns 335
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 5902f16..c0687e3 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2636,6 +2636,16 @@ static void fill_thread_info(struct elf_note_info *info, const CPUArchState *env
info->notes_size += note_size(&ets->notes[0]);
}
+static void init_note_info(struct elf_note_info *info)
+{
+ /* Initialize the elf_note_info structure so that it is at
+ * least safe to call free_note_info() on it. Must be
+ * called before calling fill_note_info().
+ */
+ memset(info, 0, sizeof (*info));
+ QTAILQ_INIT(&info->thread_list);
+}
+
static int fill_note_info(struct elf_note_info *info,
long signr, const CPUArchState *env)
{
@@ -2644,10 +2654,6 @@ static int fill_note_info(struct elf_note_info *info,
TaskState *ts = (TaskState *)env->opaque;
int i;
- (void) memset(info, 0, sizeof (*info));
-
- QTAILQ_INIT(&info->thread_list);
-
info->notes = g_malloc0(NUMNOTES * sizeof (struct memelfnote));
if (info->notes == NULL)
return (-ENOMEM);
@@ -2781,6 +2787,8 @@ static int elf_core_dump(int signr, const CPUArchState *env)
int segs = 0;
int fd = -1;
+ init_note_info(&info);
+
errno = 0;
getrlimit(RLIMIT_CORE, &dumpsize);
if (dumpsize.rlim_cur == 0)
diff --git a/linux-user/i386/syscall_nr.h b/linux-user/i386/syscall_nr.h
index f080305..c8f7302 100644
--- a/linux-user/i386/syscall_nr.h
+++ b/linux-user/i386/syscall_nr.h
@@ -347,3 +347,9 @@
#define TARGET_NR_open_by_handle_at 342
#define TARGET_NR_clock_adjtime 343
#define TARGET_NR_syncfs 344
+#define TARGET_NR_sendmmsg 345
+#define TARGET_NR_setns 346
+#define TARGET_NR_process_vm_readv 347
+#define TARGET_NR_process_vm_writev 348
+#define TARGET_NR_kcmp 349
+#define TARGET_NR_finit_module 350
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 7381012..309fb21 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -77,6 +77,7 @@
IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
IOCTL(BLKBSZGET, IOC_R, MK_PTR(TYPE_INT))
+ IOCTL(BLKPG, IOC_W, MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg)))
#ifdef FIBMAP
IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
#endif
diff --git a/linux-user/m68k/syscall_nr.h b/linux-user/m68k/syscall_nr.h
index 4d0937e..25f8521 100644
--- a/linux-user/m68k/syscall_nr.h
+++ b/linux-user/m68k/syscall_nr.h
@@ -344,3 +344,8 @@
#define TARGET_NR_open_by_handle_at 341
#define TARGET_NR_clock_adjtime 342
#define TARGET_NR_syncfs 343
+#define TARGET_NR_setns 344
+#define TARGET_NR_process_vm_readv 345
+#define TARGET_NR_process_vm_writev 346
+#define TARGET_NR_kcmp 347
+#define TARGET_NR_finit_module 348
diff --git a/linux-user/main.c b/linux-user/main.c
index cabc9e1..9192977 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -953,7 +953,8 @@ static int do_strex_a64(CPUARMState *env)
goto finish;
}
}
- val = env->xregs[rt];
+ /* handle the zero register */
+ val = rt == 31 ? 0 : env->xregs[rt];
switch (size) {
case 0:
segv = put_user_u8(val, addr);
@@ -972,7 +973,8 @@ static int do_strex_a64(CPUARMState *env)
goto error;
}
if (is_pair) {
- val = env->xregs[rt2];
+ /* handle the zero register */
+ val = rt2 == 31 ? 0 : env->xregs[rt2];
if (size == 2) {
segv = put_user_u32(val, addr + 4);
} else {
diff --git a/linux-user/microblaze/syscall_nr.h b/linux-user/microblaze/syscall_nr.h
index f1fe0e7..6f530f9 100644
--- a/linux-user/microblaze/syscall_nr.h
+++ b/linux-user/microblaze/syscall_nr.h
@@ -376,4 +376,9 @@
#define TARGET_NR_open_by_handle_at 372
#define TARGET_NR_clock_adjtime 373
#define TARGET_NR_syncfs 374
-
+#define TARGET_NR_setns 375
+#define TARGET_NR_sendmmsg 376
+#define TARGET_NR_process_vm_readv 377
+#define TARGET_NR_process_vm_writev 378
+#define TARGET_NR_kcmp 379
+#define TARGET_NR_finit_module 380
diff --git a/linux-user/mips/syscall_nr.h b/linux-user/mips/syscall_nr.h
index fbdc348..2d1a13e 100644
--- a/linux-user/mips/syscall_nr.h
+++ b/linux-user/mips/syscall_nr.h
@@ -345,3 +345,9 @@
#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 340)
#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 341)
#define TARGET_NR_syncfs (TARGET_NR_Linux + 342)
+#define TARGET_NR_sendmmsg (TARGET_NR_Linux + 343)
+#define TARGET_NR_setns (TARGET_NR_Linux + 344)
+#define TARGET_NR_process_vm_readv (TARGET_NR_Linux + 345)
+#define TARGET_NR_process_vm_writev (TARGET_NR_Linux + 346)
+#define TARGET_NR_kcmp (TARGET_NR_Linux + 347)
+#define TARGET_NR_finit_module (TARGET_NR_Linux + 348)
diff --git a/linux-user/mips64/syscall_nr.h b/linux-user/mips64/syscall_nr.h
index 0f4a6b1..004232a 100644
--- a/linux-user/mips64/syscall_nr.h
+++ b/linux-user/mips64/syscall_nr.h
@@ -310,6 +310,12 @@
#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 304)
#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 305)
#define TARGET_NR_syncfs (TARGET_NR_Linux + 306)
+#define TARGET_NR_sendmmsg (TARGET_NR_Linux + 307)
+#define TARGET_NR_setns (TARGET_NR_Linux + 308)
+#define TARGET_NR_process_vm_readv (TARGET_NR_Linux + 309)
+#define TARGET_NR_process_vm_writev (TARGET_NR_Linux + 310)
+#define TARGET_NR_kcmp (TARGET_NR_Linux + 311)
+#define TARGET_NR_finit_module (TARGET_NR_Linux + 312)
#else
/*
* Linux 64-bit syscalls are in the range from 5000 to 5999.
@@ -617,4 +623,11 @@
#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 299)
#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 300)
#define TARGET_NR_syncfs (TARGET_NR_Linux + 301)
+#define TARGET_NR_sendmmsg (TARGET_NR_Linux + 302)
+#define TARGET_NR_setns (TARGET_NR_Linux + 303)
+#define TARGET_NR_process_vm_readv (TARGET_NR_Linux + 304)
+#define TARGET_NR_process_vm_writev (TARGET_NR_Linux + 305)
+#define TARGET_NR_kcmp (TARGET_NR_Linux + 306)
+#define TARGET_NR_finit_module (TARGET_NR_Linux + 307)
+#define TARGET_NR_getdents64 (TARGET_NR_Linux + 308)
#endif
diff --git a/linux-user/openrisc/syscall_nr.h b/linux-user/openrisc/syscall_nr.h
index f4ac91e..4c386ea 100644
--- a/linux-user/openrisc/syscall_nr.h
+++ b/linux-user/openrisc/syscall_nr.h
@@ -378,9 +378,13 @@
#define TARGET_NR_syncfs 267
#define TARGET_NR_setns 268
#define TARGET_NR_sendmmsg 269
+#define TARGET_NR_process_vm_readv 270
+#define TARGET_NR_process_vm_writev 271
+#define TARGET_NR_kcmp 272
+#define TARGET_NR_finit_module 273
#undef TARGET_NR_syscalls
-#define TARGET_NR_syscalls 270
+#define TARGET_NR_syscalls 274
/*
* All syscalls below here should go away really,
diff --git a/linux-user/ppc/syscall_nr.h b/linux-user/ppc/syscall_nr.h
index 0673b7d..1e1736e 100644
--- a/linux-user/ppc/syscall_nr.h
+++ b/linux-user/ppc/syscall_nr.h
@@ -362,3 +362,9 @@
#define TARGET_NR_open_by_handle_at 346
#define TARGET_NR_clock_adjtime 347
#define TARGET_NR_syncfs 348
+#define TARGET_NR_sendmmsg 349
+#define TARGET_NR_setns 350
+#define TARGET_NR_process_vm_readv 351
+#define TARGET_NR_process_vm_writev 352
+#define TARGET_NR_finit_module 353
+#define TARGET_NR_kcmp 354
diff --git a/linux-user/s390x/syscall_nr.h b/linux-user/s390x/syscall_nr.h
index d4529ac..7c0b8b2 100644
--- a/linux-user/s390x/syscall_nr.h
+++ b/linux-user/s390x/syscall_nr.h
@@ -265,6 +265,12 @@
#define TARGET_NR_open_by_handle_at 336
#define TARGET_NR_clock_adjtime 337
#define TARGET_NR_syncfs 338
+#define TARGET_NR_setns 339
+#define TARGET_NR_process_vm_readv 340
+#define TARGET_NR_process_vm_writev 341
+#define TARGET_NR_s390_runtime_instr 342
+#define TARGET_NR_kcmp 343
+#define TARGET_NR_finit_module 344
/*
* There are some system calls that are not present on 64 bit, some
@@ -355,4 +361,3 @@
#define TARGET_NR_newfstatat 293
#endif
-
diff --git a/linux-user/sh4/syscall_nr.h b/linux-user/sh4/syscall_nr.h
index 365db58..bdf8742 100644
--- a/linux-user/sh4/syscall_nr.h
+++ b/linux-user/sh4/syscall_nr.h
@@ -366,3 +366,9 @@
#define TARGET_NR_open_by_handle_at 360
#define TARGET_NR_clock_adjtime 361
#define TARGET_NR_syncfs 362
+#define TARGET_NR_sendmmsg 363
+#define TARGET_NR_setns 364
+#define TARGET_NR_process_vm_readv 365
+#define TARGET_NR_process_vm_writev 366
+#define TARGET_NR_kcmp 367
+#define TARGET_NR_finit_module 368
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 82e8592..04638e2 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -420,6 +420,7 @@ static void QEMU_NORETURN force_sig(int target_sig)
* it to arrive. */
sigfillset(&act.sa_mask);
act.sa_handler = SIG_DFL;
+ act.sa_flags = 0;
sigaction(host_sig, &act, NULL);
/* For some reason raise(host_sig) doesn't send the signal when
diff --git a/linux-user/sparc/syscall_nr.h b/linux-user/sparc/syscall_nr.h
index 534e6e9..181cd32 100644
--- a/linux-user/sparc/syscall_nr.h
+++ b/linux-user/sparc/syscall_nr.h
@@ -302,3 +302,10 @@
#define TARGET_NR_open_by_handle_at 333
#define TARGET_NR_clock_adjtime 334
#define TARGET_NR_syncfs 335
+#define TARGET_NR_sendmmsg 336
+#define TARGET_NR_setns 337
+#define TARGET_NR_process_vm_readv 338
+#define TARGET_NR_process_vm_writev 339
+#define TARGET_NR_kern_features 340
+#define TARGET_NR_kcmp 341
+#define TARGET_NR_finit_module 342
diff --git a/linux-user/sparc64/syscall_nr.h b/linux-user/sparc64/syscall_nr.h
index 70988b2..34a984c 100644
--- a/linux-user/sparc64/syscall_nr.h
+++ b/linux-user/sparc64/syscall_nr.h
@@ -334,3 +334,10 @@
#define TARGET_NR_open_by_handle_at 333
#define TARGET_NR_clock_adjtime 334
#define TARGET_NR_syncfs 335
+#define TARGET_NR_sendmmsg 336
+#define TARGET_NR_setns 337
+#define TARGET_NR_process_vm_readv 338
+#define TARGET_NR_process_vm_writev 339
+#define TARGET_NR_kern_features 340
+#define TARGET_NR_kcmp 341
+#define TARGET_NR_finit_module 342
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f370087..1407b7a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -107,6 +107,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#include <linux/reboot.h>
#include <linux/route.h>
#include <linux/filter.h>
+#include <linux/blkpg.h>
#include "linux_loop.h"
#include "cpu-uname.h"
@@ -1707,6 +1708,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
struct iovec *vec;
abi_ulong total_len, max_len;
int i;
+ int err = 0;
if (count == 0) {
errno = 0;
@@ -1726,7 +1728,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
target_vec = lock_user(VERIFY_READ, target_addr,
count * sizeof(struct target_iovec), 1);
if (target_vec == NULL) {
- errno = EFAULT;
+ err = EFAULT;
goto fail2;
}
@@ -1740,7 +1742,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
abi_long len = tswapal(target_vec[i].iov_len);
if (len < 0) {
- errno = EINVAL;
+ err = EINVAL;
goto fail;
} else if (len == 0) {
/* Zero length pointer is ignored. */
@@ -1748,7 +1750,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
} else {
vec[i].iov_base = lock_user(type, base, len, copy);
if (!vec[i].iov_base) {
- errno = EFAULT;
+ err = EFAULT;
goto fail;
}
if (len > max_len - total_len) {
@@ -1763,9 +1765,10 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
return vec;
fail:
- free(vec);
- fail2:
unlock_user(target_vec, target_addr, 0);
+ fail2:
+ free(vec);
+ errno = err;
return NULL;
}
@@ -2427,10 +2430,15 @@ static inline abi_long target_to_host_semarray(int semid, unsigned short **host_
nsems = semid_ds.sem_nsems;
*host_array = malloc(nsems*sizeof(unsigned short));
+ if (!*host_array) {
+ return -TARGET_ENOMEM;
+ }
array = lock_user(VERIFY_READ, target_addr,
nsems*sizeof(unsigned short), 1);
- if (!array)
+ if (!array) {
+ free(*host_array);
return -TARGET_EFAULT;
+ }
for(i=0; i<nsems; i++) {
__get_user((*host_array)[i], &array[i]);
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index ae30476..3c8869e 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -901,6 +901,7 @@ struct target_pollfd {
#define TARGET_BLKSECTSET TARGET_IO(0x12,102)/* set max sectors per request (ll_rw_blk.c) */
#define TARGET_BLKSECTGET TARGET_IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */
#define TARGET_BLKSSZGET TARGET_IO(0x12,104)/* get block device sector size */
+#define TARGET_BLKPG TARGET_IO(0x12,105)/* Partition table and disk geometry handling */
/* A jump here: 108-111 have been used for various private purposes. */
#define TARGET_BLKBSZGET TARGET_IOR(0x12, 112, abi_ulong)
#define TARGET_BLKBSZSET TARGET_IOW(0x12, 113, abi_ulong)
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index 44b6a58..9d0c92d 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -240,3 +240,16 @@ STRUCT(fiemap,
TYPE_INT, /* fm_mapped_extents */
TYPE_INT, /* fm_extent_count */
TYPE_INT) /* fm_reserved */
+
+STRUCT(blkpg_partition,
+ TYPE_LONGLONG, /* start */
+ TYPE_LONGLONG, /* length */
+ TYPE_INT, /* pno */
+ MK_ARRAY(TYPE_CHAR, BLKPG_DEVNAMELTH), /* devname */
+ MK_ARRAY(TYPE_CHAR, BLKPG_VOLNAMELTH)) /* volname */
+
+STRUCT(blkpg_ioctl_arg,
+ TYPE_INT, /* op */
+ TYPE_INT, /* flags */
+ TYPE_INT, /* datalen */
+ MK_PTR(MK_STRUCT(STRUCT_blkpg_partition))) /* data */
diff --git a/linux-user/x86_64/syscall_nr.h b/linux-user/x86_64/syscall_nr.h
index 947e961..7c59e3a 100644
--- a/linux-user/x86_64/syscall_nr.h
+++ b/linux-user/x86_64/syscall_nr.h
@@ -305,3 +305,10 @@
#define TARGET_NR_open_by_handle_at 304
#define TARGET_NR_clock_adjtime 305
#define TARGET_NR_syncfs 306
+#define TARGET_NR_sendmmsg 307
+#define TARGET_NR_setns 308
+#define TARGET_NR_getcpu 309
+#define TARGET_NR_process_vm_readv 310
+#define TARGET_NR_process_vm_writev 311
+#define TARGET_NR_kcmp 312
+#define TARGET_NR_finit_module 313
diff --git a/monitor.c b/monitor.c
index 690c152..de90fba 100644
--- a/monitor.c
+++ b/monitor.c
@@ -56,6 +56,7 @@
#include "qapi/qmp/qjson.h"
#include "qapi/qmp/json-streamer.h"
#include "qapi/qmp/json-parser.h"
+#include <qom/object_interfaces.h>
#include "qemu/osdep.h"
#include "cpu.h"
#include "trace.h"
@@ -4254,6 +4255,87 @@ static const char *next_arg_type(const char *typestr)
return (p != NULL ? ++p : typestr);
}
+static void device_add_completion(ReadLineState *rs, const char *str)
+{
+ GSList *list, *elt;
+ size_t len;
+
+ len = strlen(str);
+ readline_set_completion_index(rs, len);
+ list = elt = object_class_get_list(TYPE_DEVICE, false);
+ while (elt) {
+ const char *name;
+ DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data,
+ TYPE_DEVICE);
+ name = object_class_get_name(OBJECT_CLASS(dc));
+ if (!strncmp(name, str, len)) {
+ readline_add_completion(rs, name);
+ }
+ elt = elt->next;
+ }
+ g_slist_free(list);
+}
+
+static void object_add_completion(ReadLineState *rs, const char *str)
+{
+ GSList *list, *elt;
+ size_t len;
+
+ len = strlen(str);
+ readline_set_completion_index(rs, len);
+ list = elt = object_class_get_list(TYPE_USER_CREATABLE, false);
+ while (elt) {
+ const char *name;
+
+ name = object_class_get_name(OBJECT_CLASS(elt->data));
+ if (!strncmp(name, str, len) && strcmp(name, TYPE_USER_CREATABLE)) {
+ readline_add_completion(rs, name);
+ }
+ elt = elt->next;
+ }
+ g_slist_free(list);
+}
+
+static void device_del_completion(ReadLineState *rs, BusState *bus,
+ const char *str, size_t len)
+{
+ BusChild *kid;
+
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ DeviceState *dev = kid->child;
+ BusState *dev_child;
+
+ if (dev->id && !strncmp(str, dev->id, len)) {
+ readline_add_completion(rs, dev->id);
+ }
+
+ QLIST_FOREACH(dev_child, &dev->child_bus, sibling) {
+ device_del_completion(rs, dev_child, str, len);
+ }
+ }
+}
+
+static void object_del_completion(ReadLineState *rs, const char *str)
+{
+ ObjectPropertyInfoList *list, *start;
+ size_t len;
+
+ len = strlen(str);
+ readline_set_completion_index(rs, len);
+
+ start = list = qmp_qom_list("/objects", NULL);
+ while (list) {
+ ObjectPropertyInfo *info = list->value;
+
+ if (!strncmp(info->type, "child<", 5)
+ && !strncmp(info->name, str, len)) {
+ readline_add_completion(rs, info->name);
+ }
+ list = list->next;
+ }
+ qapi_free_ObjectPropertyInfoList(start);
+}
+
static void monitor_find_completion_by_table(Monitor *mon,
const mon_cmd_t *cmd_table,
char **args,
@@ -4317,6 +4399,13 @@ static void monitor_find_completion_by_table(Monitor *mon,
readline_set_completion_index(mon->rs, strlen(str));
bdrv_iterate(block_completion_it, &mbs);
break;
+ case 'O':
+ if (!strcmp(cmd->name, "device_add") && nb_args == 2) {
+ device_add_completion(mon->rs, str);
+ } else if (!strcmp(cmd->name, "object_add") && nb_args == 2) {
+ object_add_completion(mon->rs, str);
+ }
+ break;
case 's':
case 'S':
if (!strcmp(cmd->name, "sendkey")) {
@@ -4330,6 +4419,12 @@ static void monitor_find_completion_by_table(Monitor *mon,
} else if (!strcmp(cmd->name, "help|?")) {
monitor_find_completion_by_table(mon, cmd_table,
&args[1], nb_args - 1);
+ } else if (!strcmp(cmd->name, "device_del") && nb_args == 2) {
+ size_t len = strlen(str);
+ readline_set_completion_index(mon->rs, len);
+ device_del_completion(mon->rs, sysbus_get_default(), str, len);
+ } else if (!strcmp(cmd->name, "object_del") && nb_args == 2) {
+ object_del_completion(mon->rs, str);
}
break;
default:
diff --git a/net/net.c b/net/net.c
index 2c3af20..41b3883 100644
--- a/net/net.c
+++ b/net/net.c
@@ -882,7 +882,7 @@ void net_host_device_add(Monitor *mon, const QDict *qdict)
qemu_opt_set(opts, "type", device);
net_client_init(opts, 0, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
monitor_printf(mon, "adding host network device %s failed\n", device);
@@ -918,17 +918,17 @@ int qmp_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret)
QemuOpts *opts;
opts_list = qemu_find_opts_err("netdev", &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
goto exit_err;
}
opts = qemu_opts_from_qdict(opts_list, qdict, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
goto exit_err;
}
netdev_add(opts, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qemu_opts_del(opts);
goto exit_err;
}
@@ -1152,7 +1152,7 @@ static int net_init_client(QemuOpts *opts, void *dummy)
Error *local_err = NULL;
net_client_init(opts, 0, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return -1;
@@ -1167,7 +1167,7 @@ static int net_init_netdev(QemuOpts *opts, void *dummy)
int ret;
ret = net_client_init(opts, 1, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return -1;
diff --git a/qapi-schema.json b/qapi-schema.json
index 7cfb5e5..473c096 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -28,7 +28,65 @@
'data': [ 'GenericError', 'CommandNotFound', 'DeviceEncrypted',
'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap' ] }
+
+##
+# LostTickPolicy:
+#
+# Policy for handling lost ticks in timer devices.
+#
+# @discard: throw away the missed tick(s) and continue with future injection
+# normally. Guest time may be delayed, unless the OS has explicit
+# handling of lost ticks
+#
+# @delay: continue to deliver ticks at the normal rate. Guest time will be
+# delayed due to the late tick
+#
+# @merge: merge the missed tick(s) into one tick and inject. Guest time
+# may be delayed, depending on how the OS reacts to the merging
+# of ticks
+#
+# @slew: deliver ticks at a higher rate to catch up with the missed tick. The
+# guest time should not be delayed once catchup is complete.
+#
+# Since: 2.0
##
+{ 'enum': 'LostTickPolicy',
+ 'data': ['discard', 'delay', 'merge', 'slew' ] }
+
+##
+# BiosAtaTranslation:
+#
+# Policy that BIOS should use to interpret cylinder/head/sector
+# addresses. Note that Bochs BIOS and SeaBIOS will not actually
+# translate logical CHS to physical; instead, they will use logical
+# block addressing.
+#
+# @auto: If cylinder/heads/sizes are passed, choose between none and LBA
+# depending on the size of the disk. If they are not passed,
+# choose none if QEMU can guess that the disk had 16 or fewer
+# heads, large if QEMU can guess that the disk had 131072 or
+# fewer tracks across all heads (i.e. cylinders*heads<131072),
+# otherwise LBA.
+#
+# @none: The physical disk geometry is equal to the logical geometry.
+#
+# @lba: Assume 63 sectors per track and one of 16, 32, 64, 128 or 255
+# heads (if fewer than 255 are enough to cover the whole disk
+# with 1024 cylinders/head). The number of cylinders/head is
+# then computed based on the number of sectors and heads.
+#
+# @large: The number of cylinders per head is scaled down to 1024
+# by correspondingly scaling up the number of heads.
+#
+# @rechs: Same as @large, but first convert a 16-head geometry to
+# 15-head, by proportionally scaling up the number of
+# cylinders/head.
+#
+# Since: 2.0
+##
+{ 'enum': 'BiosAtaTranslation',
+ 'data': ['auto', 'none', 'lba', 'large', 'rechs']}
+
# @add_client
#
# Allow client connections for VNC, Spice and socket based
@@ -437,6 +495,28 @@
{ 'command': 'query-chardev', 'returns': ['ChardevInfo'] }
##
+# @ChardevBackendInfo:
+#
+# Information about a character device backend
+#
+# @name: The backend name
+#
+# Since: 2.0
+##
+{ 'type': 'ChardevBackendInfo', 'data': {'name': 'str'} }
+
+##
+# @query-chardev-backends:
+#
+# Returns information about character device backends.
+#
+# Returns: a list of @ChardevBackendInfo
+#
+# Since: 2.0
+##
+{ 'command': 'query-chardev-backends', 'returns': ['ChardevBackendInfo'] }
+
+##
# @DataFormat:
#
# An enumeration of data format.
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index 8f1bc41..793548a 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -14,6 +14,7 @@
#include "qapi/string-input-visitor.h"
#include "qapi/visitor-impl.h"
#include "qapi/qmp/qerror.h"
+#include "qemu/option.h"
struct StringInputVisitor
{
@@ -41,6 +42,28 @@ static void parse_type_int(Visitor *v, int64_t *obj, const char *name,
*obj = val;
}
+static void parse_type_size(Visitor *v, uint64_t *obj, const char *name,
+ Error **errp)
+{
+ StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
+ Error *err = NULL;
+ uint64_t val;
+
+ if (siv->string) {
+ parse_option_size(name, siv->string, &val, &err);
+ } else {
+ error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
+ "size");
+ return;
+ }
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ *obj = val;
+}
+
static void parse_type_bool(Visitor *v, bool *obj, const char *name,
Error **errp)
{
@@ -128,6 +151,7 @@ StringInputVisitor *string_input_visitor_new(const char *str)
v->visitor.type_enum = input_type_enum;
v->visitor.type_int = parse_type_int;
+ v->visitor.type_size = parse_type_size;
v->visitor.type_bool = parse_type_bool;
v->visitor.type_str = parse_type_str;
v->visitor.type_number = parse_type_number;
diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
index 921653d..fb1d2e8 100644
--- a/qapi/string-output-visitor.c
+++ b/qapi/string-output-visitor.c
@@ -14,10 +14,13 @@
#include "qapi/string-output-visitor.h"
#include "qapi/visitor-impl.h"
#include "qapi/qmp/qerror.h"
+#include "qemu/host-utils.h"
+#include <math.h>
struct StringOutputVisitor
{
Visitor visitor;
+ bool human;
char *string;
};
@@ -31,7 +34,45 @@ static void print_type_int(Visitor *v, int64_t *obj, const char *name,
Error **errp)
{
StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
- string_output_set(sov, g_strdup_printf("%lld", (long long) *obj));
+ char *out;
+
+ if (sov->human) {
+ out = g_strdup_printf("%lld (%#llx)", (long long) *obj, (long long) *obj);
+ } else {
+ out = g_strdup_printf("%lld", (long long) *obj);
+ }
+ string_output_set(sov, out);
+}
+
+static void print_type_size(Visitor *v, uint64_t *obj, const char *name,
+ Error **errp)
+{
+ StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
+ static const char suffixes[] = { 'B', 'K', 'M', 'G', 'T', 'P', 'E' };
+ uint64_t div, val;
+ char *out;
+ int i;
+
+ if (!sov->human) {
+ out = g_strdup_printf("%"PRIu64, *obj);
+ string_output_set(sov, out);
+ return;
+ }
+
+ val = *obj;
+
+ /* The exponent (returned in i) minus one gives us
+ * floor(log2(val * 1024 / 1000). The correction makes us
+ * switch to the higher power when the integer part is >= 1000.
+ */
+ frexp(val / (1000.0 / 1024.0), &i);
+ i = (i - 1) / 10;
+ assert(i < ARRAY_SIZE(suffixes));
+ div = 1ULL << (i * 10);
+
+ out = g_strdup_printf("%"PRIu64" (%0.3g %c%s)", val,
+ (double)val/div, suffixes[i], i ? "iB" : "");
+ string_output_set(sov, out);
}
static void print_type_bool(Visitor *v, bool *obj, const char *name,
@@ -45,7 +86,14 @@ static void print_type_str(Visitor *v, char **obj, const char *name,
Error **errp)
{
StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
- string_output_set(sov, g_strdup(*obj ? *obj : ""));
+ char *out;
+
+ if (sov->human) {
+ out = *obj ? g_strdup_printf("\"%s\"", *obj) : g_strdup("<null>");
+ } else {
+ out = g_strdup(*obj ? *obj : "");
+ }
+ string_output_set(sov, out);
}
static void print_type_number(Visitor *v, double *obj, const char *name,
@@ -73,14 +121,16 @@ void string_output_visitor_cleanup(StringOutputVisitor *sov)
g_free(sov);
}
-StringOutputVisitor *string_output_visitor_new(void)
+StringOutputVisitor *string_output_visitor_new(bool human)
{
StringOutputVisitor *v;
v = g_malloc0(sizeof(*v));
+ v->human = human;
v->visitor.type_enum = output_type_enum;
v->visitor.type_int = print_type_int;
+ v->visitor.type_size = print_type_size;
v->visitor.type_bool = print_type_bool;
v->visitor.type_str = print_type_str;
v->visitor.type_number = print_type_number;
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 1d3b68d..3a7dc0d 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -145,7 +145,7 @@ static void qdev_print_devinfos(bool show_no_user)
static int set_property(const char *name, const char *value, void *opaque)
{
- DeviceState *dev = opaque;
+ Object *obj = opaque;
Error *err = NULL;
if (strcmp(name, "driver") == 0)
@@ -153,7 +153,7 @@ static int set_property(const char *name, const char *value, void *opaque)
if (strcmp(name, "bus") == 0)
return 0;
- qdev_prop_parse(dev, name, value, &err);
+ object_property_parse(obj, value, name, &err);
if (err != NULL) {
qerror_report_err(err);
error_free(err);
@@ -577,7 +577,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
value = object_property_get_str(OBJECT(dev), legacy_name, &err);
} else {
- value = object_property_print(OBJECT(dev), props->name, &err);
+ value = object_property_print(OBJECT(dev), props->name, true, &err);
}
g_free(legacy_name);
@@ -656,7 +656,7 @@ int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
DeviceState *dev;
opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return -1;
diff --git a/qemu-char.c b/qemu-char.c
index 30c5a6a..4d50838 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2725,7 +2725,7 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
chr = qemu_chr_open_socket_fd(fd, do_nodelay, is_listen, is_telnet,
is_waitconnect, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
goto fail;
}
return chr;
@@ -2938,7 +2938,7 @@ QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
Error *local_err = NULL;
opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return NULL;
@@ -3323,7 +3323,7 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*in
return NULL;
chr = qemu_chr_new_from_opts(opts, init, &err);
- if (error_is_set(&err)) {
+ if (err) {
error_report("%s", error_get_pretty(err));
error_free(err);
}
@@ -3432,6 +3432,25 @@ ChardevInfoList *qmp_query_chardev(Error **errp)
return chr_list;
}
+ChardevBackendInfoList *qmp_query_chardev_backends(Error **errp)
+{
+ ChardevBackendInfoList *backend_list = NULL;
+ CharDriver *c = NULL;
+ GSList *i = NULL;
+
+ for (i = backends; i; i = i->next) {
+ ChardevBackendInfoList *info = g_malloc0(sizeof(*info));
+ c = i->data;
+ info->value = g_malloc0(sizeof(*info->value));
+ info->value->name = g_strdup(c->name);
+
+ info->next = backend_list;
+ backend_list = info;
+ }
+
+ return backend_list;
+}
+
CharDriverState *qemu_chr_find(const char *name)
{
CharDriverState *chr;
diff --git a/qemu-img.c b/qemu-img.c
index 45fcddd..1e5eaf0 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -419,7 +419,7 @@ static int img_create(int argc, char **argv)
bdrv_img_create(filename, fmt, base_filename, base_fmt,
options, img_size, BDRV_O_FLAGS, &local_err, quiet);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_report("%s: %s", filename, error_get_pretty(local_err));
error_free(local_err);
return 1;
@@ -1289,7 +1289,7 @@ static int img_convert(int argc, char **argv)
bdrv_snapshot_load_tmp_by_id_or_name(bs[0], snapshot_name, &local_err);
}
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_report("Failed to load snapshot: %s",
error_get_pretty(local_err));
error_free(local_err);
@@ -1775,7 +1775,7 @@ static ImageInfoList *collect_image_info_list(const char *filename,
}
bdrv_query_image_info(bs, &info, &err);
- if (error_is_set(&err)) {
+ if (err) {
error_report("%s", error_get_pretty(err));
error_free(err);
goto err;
@@ -2184,7 +2184,7 @@ static int img_snapshot(int argc, char **argv)
case SNAPSHOT_DELETE:
bdrv_snapshot_delete_by_id_or_name(bs, snapshot_name, &err);
- if (error_is_set(&err)) {
+ if (err) {
error_report("Could not delete snapshot '%s': (%s)",
snapshot_name, error_get_pretty(err));
error_free(err);
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 8100bee..cae4171 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -108,7 +108,7 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
}
ga_wait_child(pid, &status, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(err, local_err);
return;
}
@@ -181,7 +181,7 @@ void qmp_guest_set_time(int64_t time_ns, Error **errp)
}
ga_wait_child(pid, &status, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return;
}
@@ -669,7 +669,7 @@ static void execute_fsfreeze_hook(FsfreezeHookArg arg, Error **err)
}
ga_wait_child(pid, &status, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(err, local_err);
return;
}
@@ -713,14 +713,14 @@ int64_t qmp_guest_fsfreeze_freeze(Error **err)
slog("guest-fsfreeze called");
execute_fsfreeze_hook(FSFREEZE_HOOK_FREEZE, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(err, local_err);
return -1;
}
QTAILQ_INIT(&mounts);
build_fs_mount_list(&mounts, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(err, local_err);
return -1;
}
@@ -780,7 +780,7 @@ int64_t qmp_guest_fsfreeze_thaw(Error **err)
QTAILQ_INIT(&mounts);
build_fs_mount_list(&mounts, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(err, local_err);
return 0;
}
@@ -861,7 +861,7 @@ void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err)
QTAILQ_INIT(&mounts);
build_fs_mount_list(&mounts, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(err, local_err);
return;
}
@@ -957,7 +957,7 @@ static void bios_supports_mode(const char *pmutils_bin, const char *pmutils_arg,
}
ga_wait_child(pid, &status, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(err, local_err);
goto out;
}
@@ -1034,7 +1034,7 @@ static void guest_suspend(const char *pmutils_bin, const char *sysfile_str,
}
ga_wait_child(pid, &status, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(err, local_err);
goto out;
}
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index a6a0af2..50094dd 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -197,7 +197,7 @@ int64_t qmp_guest_fsfreeze_freeze(Error **err)
error:
qmp_guest_fsfreeze_thaw(&local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
g_debug("cleanup thaw: %s", error_get_pretty(local_err));
error_free(local_err);
}
diff --git a/qmp-commands.hx b/qmp-commands.hx
index cce6b81..8a0e832 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1924,6 +1924,47 @@ EQMP
},
SQMP
+query-chardev-backends
+-------------
+
+List available character device backends.
+
+Each backend is represented by a json-object, the returned value is a json-array
+of all backends.
+
+Each json-object contains:
+
+- "name": backend name (json-string)
+
+Example:
+
+-> { "execute": "query-chardev-backends" }
+<- {
+ "return":[
+ {
+ "name":"udp"
+ },
+ {
+ "name":"tcp"
+ },
+ {
+ "name":"unix"
+ },
+ {
+ "name":"spiceport"
+ }
+ ]
+ }
+
+EQMP
+
+ {
+ .name = "query-chardev-backends",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_chardev_backends,
+ },
+
+SQMP
query-block
-----------
diff --git a/qom/object.c b/qom/object.c
index 62e7e41..660859c 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -948,13 +948,13 @@ void object_property_parse(Object *obj, const char *string,
string_input_visitor_cleanup(mi);
}
-char *object_property_print(Object *obj, const char *name,
+char *object_property_print(Object *obj, const char *name, bool human,
Error **errp)
{
StringOutputVisitor *mo;
char *string;
- mo = string_output_visitor_new();
+ mo = string_output_visitor_new(human);
object_property_get(obj, string_output_get_visitor(mo), name, errp);
string = string_output_get_string(mo);
string_output_visitor_cleanup(mo);
diff --git a/qtest.c b/qtest.c
index a738afc..ae941d6 100644
--- a/qtest.c
+++ b/qtest.c
@@ -507,12 +507,18 @@ int qtest_init_accel(void)
return 0;
}
-void qtest_init(const char *qtest_chrdev, const char *qtest_log)
+void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
{
CharDriverState *chr;
chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
+ if (chr == NULL) {
+ error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
+ qtest_chrdev);
+ return;
+ }
+
qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr);
qemu_chr_fe_set_echo(chr, true);
diff --git a/savevm.c b/savevm.c
index a7dbe18..7329fc5 100644
--- a/savevm.c
+++ b/savevm.c
@@ -880,7 +880,7 @@ static int del_existing_snapshots(Monitor *mon, const char *name)
if (bdrv_can_snapshot(bs) &&
bdrv_snapshot_find(bs, snapshot, name) >= 0) {
bdrv_snapshot_delete_by_id_or_name(bs, name, &err);
- if (error_is_set(&err)) {
+ if (err) {
monitor_printf(mon,
"Error while deleting snapshot on device '%s':"
" %s\n",
@@ -1115,7 +1115,7 @@ void do_delvm(Monitor *mon, const QDict *qdict)
while ((bs1 = bdrv_next(bs1))) {
if (bdrv_can_snapshot(bs1)) {
bdrv_snapshot_delete_by_id_or_name(bs, name, &err);
- if (error_is_set(&err)) {
+ if (err) {
monitor_printf(mon,
"Error while deleting snapshot on device '%s':"
" %s\n",
diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell
index d6b420f..d374b35 100755
--- a/scripts/qmp/qmp-shell
+++ b/scripts/qmp/qmp-shell
@@ -31,6 +31,7 @@
# (QEMU)
import qmp
+import json
import readline
import sys
import pprint
@@ -107,6 +108,8 @@ class QMPShell(qmp.QEMUMonitorProtocol):
value = True
elif opt[1] == 'false':
value = False
+ elif opt[1].startswith('{'):
+ value = json.loads(opt[1])
else:
value = opt[1]
qmpcmd['arguments'][opt[0]] = value
diff --git a/scripts/tracetool/backend/ust.py b/scripts/tracetool/backend/ust.py
index ea36995..41c1c75 100644
--- a/scripts/tracetool/backend/ust.py
+++ b/scripts/tracetool/backend/ust.py
@@ -18,76 +18,65 @@ from tracetool import out
PUBLIC = True
-
def c(events):
- out('#include <ust/marker.h>',
- '#undef mutex_lock',
- '#undef mutex_unlock',
- '#undef inline',
- '#undef wmb',
- '#include "trace.h"')
+ pass
+
+def h(events):
+ out('#include <lttng/tracepoint.h>',
+ '#include "trace/generated-ust-provider.h"',
+ '')
for e in events:
argnames = ", ".join(e.args.names())
if len(e.args) > 0:
- argnames = ', ' + argnames
-
- out('DEFINE_TRACE(ust_%(name)s);',
- '',
- 'static void ust_%(name)s_probe(%(args)s)',
- '{',
- ' trace_mark(ust, %(name)s, %(fmt)s%(argnames)s);',
- '}',
- name = e.name,
- args = e.args,
- fmt = e.fmt,
- argnames = argnames,
- )
-
- else:
- out('DEFINE_TRACE(ust_%(name)s);',
- '',
- 'static void ust_%(name)s_probe(%(args)s)',
- '{',
- ' trace_mark(ust, %(name)s, UST_MARKER_NOARGS);',
- '}',
- name = e.name,
- args = e.args,
- )
-
- # register probes
- out('',
- 'static void __attribute__((constructor)) trace_init(void)',
- '{')
+ argnames = ", " + argnames
- for e in events:
- out(' register_trace_ust_%(name)s(ust_%(name)s_probe);',
+ out('static inline void trace_%(name)s(%(args)s)',
+ '{',
+ ' tracepoint(qemu, %(name)s%(tp_args)s);',
+ '}',
+ '',
name = e.name,
+ args = e.args,
+ tp_args = argnames,
)
- out('}')
-
-
-def h(events):
- out('#include <ust/tracepoint.h>',
- '#undef mutex_lock',
- '#undef mutex_unlock',
- '#undef inline',
- '#undef wmb')
+def ust_events_c(events):
+ pass
+def ust_events_h(events):
for e in events:
if len(e.args) > 0:
- out('DECLARE_TRACE(ust_%(name)s, TP_PROTO(%(args)s), TP_ARGS(%(argnames)s));',
- '#define trace_%(name)s trace_ust_%(name)s',
+ out('TRACEPOINT_EVENT(',
+ ' qemu,',
+ ' %(name)s,',
+ ' TP_ARGS(%(args)s),',
+ ' TP_FIELDS(',
name = e.name,
- args = e.args,
- argnames = ", ".join(e.args.names()),
+ args = ", ".join(", ".join(i) for i in e.args),
)
+ for t,n in e.args:
+ if ('int' in t) or ('long' in t) or ('unsigned' in t) or ('size_t' in t):
+ out(' ctf_integer(' + t + ', ' + n + ', ' + n + ')')
+ elif ('double' in t) or ('float' in t):
+ out(' ctf_float(' + t + ', ' + n + ', ' + n + ')')
+ elif ('char *' in t) or ('char*' in t):
+ out(' ctf_string(' + n + ', ' + n + ')')
+ elif ('void *' in t) or ('void*' in t):
+ out(' ctf_integer_hex(unsigned long, ' + n + ', ' + n + ')')
+
+ out(' )',
+ ')',
+ '')
+
else:
- out('_DECLARE_TRACEPOINT_NOARGS(ust_%(name)s);',
- '#define trace_%(name)s trace_ust_%(name)s',
+ out('TRACEPOINT_EVENT(',
+ ' qemu,',
+ ' %(name)s,',
+ ' TP_ARGS(void),',
+ ' TP_FIELDS()',
+ ')',
+ '',
name = e.name,
- )
-
- out()
+ ) \ No newline at end of file
diff --git a/scripts/tracetool/format/ust_events_c.py b/scripts/tracetool/format/ust_events_c.py
new file mode 100644
index 0000000..116e713
--- /dev/null
+++ b/scripts/tracetool/format/ust_events_c.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Generate .c for LTTng ust event description.
+"""
+
+__author__ = "Mohamad Gebai <mohamad.gebai@polymtl.ca>"
+__copyright__ = "Copyright 2012, Mohamad Gebai <mohamad.gebai@polymtl.ca>"
+__license__ = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__ = "stefanha@redhat.com"
+
+
+from tracetool import out
+
+
+def begin(events):
+ out('/* This file is autogenerated by tracetool, do not edit. */',
+ '',
+ '#define TRACEPOINT_DEFINE',
+ '#define TRACEPOINT_CREATE_PROBES',
+ '',
+ '/* If gcc version 4.7 or older is used, LTTng ust gives a warning when compiling with',
+ ' -Wredundant-decls.',
+ ' */',
+ '#pragma GCC diagnostic ignored "-Wredundant-decls"',
+ '',
+ '#include "generated-ust-provider.h"')
diff --git a/scripts/tracetool/format/ust_events_h.py b/scripts/tracetool/format/ust_events_h.py
new file mode 100644
index 0000000..f206eca
--- /dev/null
+++ b/scripts/tracetool/format/ust_events_h.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Generate .h for LTTng ust event description.
+"""
+
+__author__ = "Mohamad Gebai <mohamad.gebai@polymtl.ca>"
+__copyright__ = "Copyright 2012, Mohamad Gebai <mohamad.gebai@polymtl.ca>"
+__license__ = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__ = "stefanha@redhat.com"
+
+
+from tracetool import out
+
+
+def begin(events):
+ out('/* This file is autogenerated by tracetool, do not edit. */',
+ '',
+ '#undef TRACEPOINT_PROVIDER',
+ '#define TRACEPOINT_PROVIDER qemu',
+ '',
+ '#undef TRACEPOINT_INCLUDE_FILE',
+ '#define TRACEPOINT_INCLUDE_FILE ./generated-ust-provider.h',
+ '',
+ '#if !defined (TRACE__GENERATED_UST_H) || defined(TRACEPOINT_HEADER_MULTI_READ)',
+ '#define TRACE__GENERATED_UST_H',
+ '',
+ '#include "qemu-common.h"',
+ '#include <lttng/tracepoint.h>',
+ '',
+ '/*',
+ ' * LTTng ust 2.0 does not allow you to use TP_ARGS(void) for tracepoints',
+ ' * requiring no arguments. We define these macros introduced in more recent'
+ ' * versions of LTTng ust as a workaround',
+ ' */',
+ '#ifndef _TP_EXPROTO1',
+ '#define _TP_EXPROTO1(a) void',
+ '#endif',
+ '#ifndef _TP_EXDATA_PROTO1',
+ '#define _TP_EXDATA_PROTO1(a) void *__tp_data',
+ '#endif',
+ '#ifndef _TP_EXDATA_VAR1',
+ '#define _TP_EXDATA_VAR1(a) __tp_data',
+ '#endif',
+ '#ifndef _TP_EXVAR1',
+ '#define _TP_EXVAR1(a)',
+ '#endif',
+ '')
+
+def end(events):
+ out('#endif /* TRACE__GENERATED_UST_H */',
+ '',
+ '/* This part must be outside ifdef protection */',
+ '#include <lttng/tracepoint-event.h>')
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 45ad7f0..6e7ce89 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -128,7 +128,7 @@ static void arm_cpu_reset(CPUState *s)
}
}
- if (env->cp15.c1_sys & (1 << 13)) {
+ if (env->cp15.c1_sys & SCTLR_V) {
env->regs[15] = 0xFFFF0000;
}
@@ -681,14 +681,12 @@ static void cortex_a9_initfn(Object *obj)
}
#ifndef CONFIG_USER_ONLY
-static int a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
/* Linux wants the number of processors from here.
* Might as well set the interrupt-controller bit too.
*/
- *value = ((smp_cpus - 1) << 24) | (1 << 23);
- return 0;
+ return ((smp_cpus - 1) << 24) | (1 << 23);
}
#endif
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 383c582..3c8a2db 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -217,11 +217,6 @@ typedef struct CPUARMState {
uint32_t c15_power_control; /* power control */
} cp15;
- /* System registers (AArch64) */
- struct {
- uint64_t tpidr_el0;
- } sr;
-
struct {
uint32_t other_sp;
uint32_t vecbase;
@@ -337,6 +332,58 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
int mmu_idx);
#define cpu_handle_mmu_fault cpu_arm_handle_mmu_fault
+/* SCTLR bit meanings. Several bits have been reused in newer
+ * versions of the architecture; in that case we define constants
+ * for both old and new bit meanings. Code which tests against those
+ * bits should probably check or otherwise arrange that the CPU
+ * is the architectural version it expects.
+ */
+#define SCTLR_M (1U << 0)
+#define SCTLR_A (1U << 1)
+#define SCTLR_C (1U << 2)
+#define SCTLR_W (1U << 3) /* up to v6; RAO in v7 */
+#define SCTLR_SA (1U << 3)
+#define SCTLR_P (1U << 4) /* up to v5; RAO in v6 and v7 */
+#define SCTLR_SA0 (1U << 4) /* v8 onward, AArch64 only */
+#define SCTLR_D (1U << 5) /* up to v5; RAO in v6 */
+#define SCTLR_CP15BEN (1U << 5) /* v7 onward */
+#define SCTLR_L (1U << 6) /* up to v5; RAO in v6 and v7; RAZ in v8 */
+#define SCTLR_B (1U << 7) /* up to v6; RAZ in v7 */
+#define SCTLR_ITD (1U << 7) /* v8 onward */
+#define SCTLR_S (1U << 8) /* up to v6; RAZ in v7 */
+#define SCTLR_SED (1U << 8) /* v8 onward */
+#define SCTLR_R (1U << 9) /* up to v6; RAZ in v7 */
+#define SCTLR_UMA (1U << 9) /* v8 onward, AArch64 only */
+#define SCTLR_F (1U << 10) /* up to v6 */
+#define SCTLR_SW (1U << 10) /* v7 onward */
+#define SCTLR_Z (1U << 11)
+#define SCTLR_I (1U << 12)
+#define SCTLR_V (1U << 13)
+#define SCTLR_RR (1U << 14) /* up to v7 */
+#define SCTLR_DZE (1U << 14) /* v8 onward, AArch64 only */
+#define SCTLR_L4 (1U << 15) /* up to v6; RAZ in v7 */
+#define SCTLR_UCT (1U << 15) /* v8 onward, AArch64 only */
+#define SCTLR_DT (1U << 16) /* up to ??, RAO in v6 and v7 */
+#define SCTLR_nTWI (1U << 16) /* v8 onward */
+#define SCTLR_HA (1U << 17)
+#define SCTLR_IT (1U << 18) /* up to ??, RAO in v6 and v7 */
+#define SCTLR_nTWE (1U << 18) /* v8 onward */
+#define SCTLR_WXN (1U << 19)
+#define SCTLR_ST (1U << 20) /* up to ??, RAZ in v6 */
+#define SCTLR_UWXN (1U << 20) /* v7 onward */
+#define SCTLR_FI (1U << 21)
+#define SCTLR_U (1U << 22)
+#define SCTLR_XP (1U << 23) /* up to v6; v7 onward RAO */
+#define SCTLR_VE (1U << 24) /* up to v7 */
+#define SCTLR_E0E (1U << 24) /* v8 onward, AArch64 only */
+#define SCTLR_EE (1U << 25)
+#define SCTLR_L2 (1U << 26) /* up to v6, RAZ in v7 */
+#define SCTLR_UCI (1U << 26) /* v8 onward, AArch64 only */
+#define SCTLR_NMFI (1U << 27)
+#define SCTLR_TRE (1U << 28)
+#define SCTLR_AFE (1U << 29)
+#define SCTLR_TE (1U << 30)
+
#define CPSR_M (0x1fU)
#define CPSR_T (1U << 5)
#define CPSR_F (1U << 6)
@@ -764,14 +811,30 @@ static inline int arm_current_pl(CPUARMState *env)
typedef struct ARMCPRegInfo ARMCPRegInfo;
-/* Access functions for coprocessor registers. These should return
- * 0 on success, or one of the EXCP_* constants if access should cause
- * an exception (in which case *value is not written).
+typedef enum CPAccessResult {
+ /* Access is permitted */
+ CP_ACCESS_OK = 0,
+ /* Access fails due to a configurable trap or enable which would
+ * result in a categorized exception syndrome giving information about
+ * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
+ * 0xc or 0x18).
+ */
+ CP_ACCESS_TRAP = 1,
+ /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
+ * Note that this is not a catch-all case -- the set of cases which may
+ * result in this failure is specifically defined by the architecture.
+ */
+ CP_ACCESS_TRAP_UNCATEGORIZED = 2,
+} CPAccessResult;
+
+/* Access functions for coprocessor registers. These cannot fail and
+ * may not raise exceptions.
*/
-typedef int CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque,
- uint64_t *value);
-typedef int CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
- uint64_t value);
+typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque);
+typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
+ uint64_t value);
+/* Access permission check functions for coprocessor registers. */
+typedef CPAccessResult CPAccessFn(CPUARMState *env, const ARMCPRegInfo *opaque);
/* Hook function for register reset */
typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
@@ -825,6 +888,12 @@ struct ARMCPRegInfo {
* 2. both readfn and writefn are specified
*/
ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
+ /* Function for making any access checks for this register in addition to
+ * those specified by the 'access' permissions bits. If NULL, no extra
+ * checks required. The access check is performed at runtime, not at
+ * translate time.
+ */
+ CPAccessFn *accessfn;
/* Function for handling reads of this register. If NULL, then reads
* will be done by loading from the offset into CPUARMState specified
* by fieldoffset.
@@ -838,14 +907,14 @@ struct ARMCPRegInfo {
/* Function for doing a "raw" read; used when we need to copy
* coprocessor state to the kernel for KVM or out for
* migration. This only needs to be provided if there is also a
- * readfn and it makes an access permission check.
+ * readfn and it has side effects (for instance clear-on-read bits).
*/
CPReadFn *raw_readfn;
/* Function for doing a "raw" write; used when we need to copy KVM
* kernel coprocessor state into userspace, or for inbound
* migration. This only needs to be provided if there is also a
- * writefn and it makes an access permission check or masks out
- * "unwritable" bits or has write-one-to-clear or similar behaviour.
+ * writefn and it masks out "unwritable" bits or has write-one-to-clear
+ * or similar behaviour.
*/
CPWriteFn *raw_writefn;
/* Function for resetting the register. If NULL, then reset will be done
@@ -880,10 +949,10 @@ static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
/* CPWriteFn that can be used to implement writes-ignored behaviour */
-int arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value);
+void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value);
/* CPReadFn that can be used for read-as-zero behaviour */
-int arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t *value);
+uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri);
/* CPResetFn that does nothing, for use if no reset is required even
* if fieldoffset is non zero.
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index 6ca958a..c2ce33e 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -123,6 +123,32 @@ uint64_t HELPER(vfp_cmped_a64)(float64 x, float64 y, void *fp_status)
return float_rel_to_flags(float64_compare(x, y, fp_status));
}
+float32 HELPER(vfp_mulxs)(float32 a, float32 b, void *fpstp)
+{
+ float_status *fpst = fpstp;
+
+ if ((float32_is_zero(a) && float32_is_infinity(b)) ||
+ (float32_is_infinity(a) && float32_is_zero(b))) {
+ /* 2.0 with the sign bit set to sign(A) XOR sign(B) */
+ return make_float32((1U << 30) |
+ ((float32_val(a) ^ float32_val(b)) & (1U << 31)));
+ }
+ return float32_mul(a, b, fpst);
+}
+
+float64 HELPER(vfp_mulxd)(float64 a, float64 b, void *fpstp)
+{
+ float_status *fpst = fpstp;
+
+ if ((float64_is_zero(a) && float64_is_infinity(b)) ||
+ (float64_is_infinity(a) && float64_is_zero(b))) {
+ /* 2.0 with the sign bit set to sign(A) XOR sign(B) */
+ return make_float64((1ULL << 62) |
+ ((float64_val(a) ^ float64_val(b)) & (1ULL << 63)));
+ }
+ return float64_mul(a, b, fpst);
+}
+
uint64_t HELPER(simd_tbl)(CPUARMState *env, uint64_t result, uint64_t indices,
uint32_t rn, uint32_t numregs)
{
@@ -153,3 +179,82 @@ uint64_t HELPER(simd_tbl)(CPUARMState *env, uint64_t result, uint64_t indices,
}
return result;
}
+
+/* 64bit/double versions of the neon float compare functions */
+uint64_t HELPER(neon_ceq_f64)(float64 a, float64 b, void *fpstp)
+{
+ float_status *fpst = fpstp;
+ return -float64_eq_quiet(a, b, fpst);
+}
+
+uint64_t HELPER(neon_cge_f64)(float64 a, float64 b, void *fpstp)
+{
+ float_status *fpst = fpstp;
+ return -float64_le(b, a, fpst);
+}
+
+uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp)
+{
+ float_status *fpst = fpstp;
+ return -float64_lt(b, a, fpst);
+}
+
+/* Reciprocal step and sqrt step. Note that unlike the A32/T32
+ * versions, these do a fully fused multiply-add or
+ * multiply-add-and-halve.
+ */
+#define float32_two make_float32(0x40000000)
+#define float32_three make_float32(0x40400000)
+#define float32_one_point_five make_float32(0x3fc00000)
+
+#define float64_two make_float64(0x4000000000000000ULL)
+#define float64_three make_float64(0x4008000000000000ULL)
+#define float64_one_point_five make_float64(0x3FF8000000000000ULL)
+
+float32 HELPER(recpsf_f32)(float32 a, float32 b, void *fpstp)
+{
+ float_status *fpst = fpstp;
+
+ a = float32_chs(a);
+ if ((float32_is_infinity(a) && float32_is_zero(b)) ||
+ (float32_is_infinity(b) && float32_is_zero(a))) {
+ return float32_two;
+ }
+ return float32_muladd(a, b, float32_two, 0, fpst);
+}
+
+float64 HELPER(recpsf_f64)(float64 a, float64 b, void *fpstp)
+{
+ float_status *fpst = fpstp;
+
+ a = float64_chs(a);
+ if ((float64_is_infinity(a) && float64_is_zero(b)) ||
+ (float64_is_infinity(b) && float64_is_zero(a))) {
+ return float64_two;
+ }
+ return float64_muladd(a, b, float64_two, 0, fpst);
+}
+
+float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, void *fpstp)
+{
+ float_status *fpst = fpstp;
+
+ a = float32_chs(a);
+ if ((float32_is_infinity(a) && float32_is_zero(b)) ||
+ (float32_is_infinity(b) && float32_is_zero(a))) {
+ return float32_one_point_five;
+ }
+ return float32_muladd(a, b, float32_three, float_muladd_halve_result, fpst);
+}
+
+float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, void *fpstp)
+{
+ float_status *fpst = fpstp;
+
+ a = float64_chs(a);
+ if ((float64_is_infinity(a) && float64_is_zero(b)) ||
+ (float64_is_infinity(b) && float64_is_zero(a))) {
+ return float64_one_point_five;
+ }
+ return float64_muladd(a, b, float64_three, float_muladd_halve_result, fpst);
+}
diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
index 99832ee..ab9933c 100644
--- a/target-arm/helper-a64.h
+++ b/target-arm/helper-a64.h
@@ -27,3 +27,12 @@ DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr)
DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr)
DEF_HELPER_3(vfp_cmped_a64, i64, f64, f64, ptr)
DEF_HELPER_FLAGS_5(simd_tbl, TCG_CALL_NO_RWG_SE, i64, env, i64, i64, i32, i32)
+DEF_HELPER_FLAGS_3(vfp_mulxs, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
+DEF_HELPER_FLAGS_3(vfp_mulxd, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
+DEF_HELPER_FLAGS_3(neon_ceq_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
+DEF_HELPER_FLAGS_3(neon_cge_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
+DEF_HELPER_FLAGS_3(neon_cgt_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
+DEF_HELPER_FLAGS_3(recpsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
+DEF_HELPER_FLAGS_3(recpsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
+DEF_HELPER_FLAGS_3(rsqrtsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
+DEF_HELPER_FLAGS_3(rsqrtsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 5ae08c9..1b111b6 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -107,65 +107,56 @@ static int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
}
}
-static int raw_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t raw_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
if (ri->type & ARM_CP_64BIT) {
- *value = CPREG_FIELD64(env, ri);
+ return CPREG_FIELD64(env, ri);
} else {
- *value = CPREG_FIELD32(env, ri);
+ return CPREG_FIELD32(env, ri);
}
- return 0;
}
-static int raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
if (ri->type & ARM_CP_64BIT) {
CPREG_FIELD64(env, ri) = value;
} else {
CPREG_FIELD32(env, ri) = value;
}
- return 0;
}
-static bool read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *v)
+static uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri)
{
- /* Raw read of a coprocessor register (as needed for migration, etc)
- * return true on success, false if the read is impossible for some reason.
- */
+ /* Raw read of a coprocessor register (as needed for migration, etc). */
if (ri->type & ARM_CP_CONST) {
- *v = ri->resetvalue;
+ return ri->resetvalue;
} else if (ri->raw_readfn) {
- return (ri->raw_readfn(env, ri, v) == 0);
+ return ri->raw_readfn(env, ri);
} else if (ri->readfn) {
- return (ri->readfn(env, ri, v) == 0);
+ return ri->readfn(env, ri);
} else {
- raw_read(env, ri, v);
+ return raw_read(env, ri);
}
- return true;
}
-static bool write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
- int64_t v)
+static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t v)
{
/* Raw write of a coprocessor register (as needed for migration, etc).
- * Return true on success, false if the write is impossible for some reason.
* Note that constant registers are treated as write-ignored; the
* caller should check for success by whether a readback gives the
* value written.
*/
if (ri->type & ARM_CP_CONST) {
- return true;
+ return;
} else if (ri->raw_writefn) {
- return (ri->raw_writefn(env, ri, v) == 0);
+ ri->raw_writefn(env, ri, v);
} else if (ri->writefn) {
- return (ri->writefn(env, ri, v) == 0);
+ ri->writefn(env, ri, v);
} else {
raw_write(env, ri, v);
}
- return true;
}
bool write_cpustate_to_list(ARMCPU *cpu)
@@ -177,7 +168,7 @@ bool write_cpustate_to_list(ARMCPU *cpu)
for (i = 0; i < cpu->cpreg_array_len; i++) {
uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
const ARMCPRegInfo *ri;
- uint64_t v;
+
ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
if (!ri) {
ok = false;
@@ -186,11 +177,7 @@ bool write_cpustate_to_list(ARMCPU *cpu)
if (ri->type & ARM_CP_NO_MIGRATE) {
continue;
}
- if (!read_raw_cp_reg(&cpu->env, ri, &v)) {
- ok = false;
- continue;
- }
- cpu->cpreg_values[i] = v;
+ cpu->cpreg_values[i] = read_raw_cp_reg(&cpu->env, ri);
}
return ok;
}
@@ -203,7 +190,6 @@ bool write_list_to_cpustate(ARMCPU *cpu)
for (i = 0; i < cpu->cpreg_array_len; i++) {
uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
uint64_t v = cpu->cpreg_values[i];
- uint64_t readback;
const ARMCPRegInfo *ri;
ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
@@ -218,9 +204,8 @@ bool write_list_to_cpustate(ARMCPU *cpu)
* (to catch read-only registers and partially read-only
* registers where the incoming migration value doesn't match)
*/
- if (!write_raw_cp_reg(&cpu->env, ri, v) ||
- !read_raw_cp_reg(&cpu->env, ri, &readback) ||
- readback != v) {
+ write_raw_cp_reg(&cpu->env, ri, v);
+ if (read_raw_cp_reg(&cpu->env, ri) != v) {
ok = false;
}
}
@@ -309,14 +294,13 @@ void init_cpreg_list(ARMCPU *cpu)
g_list_free(keys);
}
-static int dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
{
env->cp15.c3 = value;
tlb_flush(env, 1); /* Flush TLB as domain not tracked in TLB */
- return 0;
}
-static int fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
{
if (env->cp15.c13_fcse != value) {
/* Unlike real hardware the qemu TLB uses virtual addresses,
@@ -325,10 +309,10 @@ static int fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
tlb_flush(env, 1);
env->cp15.c13_fcse = value;
}
- return 0;
}
-static int contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+
+static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
if (env->cp15.c13_context != value && !arm_feature(env, ARM_FEATURE_MPU)) {
/* For VMSA (when not using the LPAE long descriptor page table
@@ -338,39 +322,34 @@ static int contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
tlb_flush(env, 1);
}
env->cp15.c13_context = value;
- return 0;
}
-static int tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
/* Invalidate all (TLBIALL) */
tlb_flush(env, 1);
- return 0;
}
-static int tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
/* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */
tlb_flush_page(env, value & TARGET_PAGE_MASK);
- return 0;
}
-static int tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
/* Invalidate by ASID (TLBIASID) */
tlb_flush(env, value == 0);
- return 0;
}
-static int tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
/* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */
tlb_flush_page(env, value & TARGET_PAGE_MASK);
- return 0;
}
static const ARMCPRegInfo cp_reginfo[] = {
@@ -450,14 +429,14 @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = {
REGINFO_SENTINEL
};
-static int cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
if (env->cp15.c1_coproc != value) {
env->cp15.c1_coproc = value;
/* ??? Is this safe when called from within a TB? */
tb_flush(env);
}
- return 0;
}
static const ARMCPRegInfo v6_cp_reginfo[] = {
@@ -485,118 +464,88 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
REGINFO_SENTINEL
};
-
-static int pmreg_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
{
- /* Generic performance monitor register read function for where
- * user access may be allowed by PMUSERENR.
+ /* Perfomance monitor registers user accessibility is controlled
+ * by PMUSERENR.
*/
if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
- return EXCP_UDEF;
+ return CP_ACCESS_TRAP;
}
- *value = CPREG_FIELD32(env, ri);
- return 0;
+ return CP_ACCESS_OK;
}
-static int pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
- if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
- return EXCP_UDEF;
- }
/* only the DP, X, D and E bits are writable */
env->cp15.c9_pmcr &= ~0x39;
env->cp15.c9_pmcr |= (value & 0x39);
- return 0;
}
-static int pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
+static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
- if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
- return EXCP_UDEF;
- }
value &= (1 << 31);
env->cp15.c9_pmcnten |= value;
- return 0;
}
-static int pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
- if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
- return EXCP_UDEF;
- }
value &= (1 << 31);
env->cp15.c9_pmcnten &= ~value;
- return 0;
}
-static int pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
- if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
- return EXCP_UDEF;
- }
env->cp15.c9_pmovsr &= ~value;
- return 0;
}
-static int pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
- if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
- return EXCP_UDEF;
- }
env->cp15.c9_pmxevtyper = value & 0xff;
- return 0;
}
-static int pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+static void pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
env->cp15.c9_pmuserenr = value & 1;
- return 0;
}
-static int pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
/* We have no event counters so only the C bit can be changed */
value &= (1 << 31);
env->cp15.c9_pminten |= value;
- return 0;
}
-static int pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
value &= (1 << 31);
env->cp15.c9_pminten &= ~value;
- return 0;
}
-static int vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
env->cp15.c12_vbar = value & ~0x1Ful;
- return 0;
}
-static int ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
ARMCPU *cpu = arm_env_get_cpu(env);
- *value = cpu->ccsidr[env->cp15.c0_cssel];
- return 0;
+ return cpu->ccsidr[env->cp15.c0_cssel];
}
-static int csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
env->cp15.c0_cssel = value & 0xf;
- return 0;
}
static const ARMCPRegInfo v7_cp_reginfo[] = {
@@ -624,37 +573,41 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
{ .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1,
.access = PL0_RW, .resetvalue = 0,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
- .readfn = pmreg_read, .writefn = pmcntenset_write,
- .raw_readfn = raw_read, .raw_writefn = raw_write },
+ .writefn = pmcntenset_write,
+ .accessfn = pmreg_access,
+ .raw_writefn = raw_write },
{ .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2,
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
- .readfn = pmreg_read, .writefn = pmcntenclr_write,
+ .accessfn = pmreg_access,
+ .writefn = pmcntenclr_write,
.type = ARM_CP_NO_MIGRATE },
{ .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
- .readfn = pmreg_read, .writefn = pmovsr_write,
- .raw_readfn = raw_read, .raw_writefn = raw_write },
- /* Unimplemented so WI. Strictly speaking write accesses in PL0 should
- * respect PMUSERENR.
- */
+ .accessfn = pmreg_access,
+ .writefn = pmovsr_write,
+ .raw_writefn = raw_write },
+ /* Unimplemented so WI. */
{ .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
- .access = PL0_W, .type = ARM_CP_NOP },
+ .access = PL0_W, .accessfn = pmreg_access, .type = ARM_CP_NOP },
/* Since we don't implement any events, writing to PMSELR is UNPREDICTABLE.
- * We choose to RAZ/WI. XXX should respect PMUSERENR.
+ * We choose to RAZ/WI.
*/
{ .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
- .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
- /* Unimplemented, RAZ/WI. XXX PMUSERENR */
+ .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0,
+ .accessfn = pmreg_access },
+ /* Unimplemented, RAZ/WI. */
{ .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0,
- .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+ .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0,
+ .accessfn = pmreg_access },
{ .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
.access = PL0_RW,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmxevtyper),
- .readfn = pmreg_read, .writefn = pmxevtyper_write,
- .raw_readfn = raw_read, .raw_writefn = raw_write },
- /* Unimplemented, RAZ/WI. XXX PMUSERENR */
+ .accessfn = pmreg_access, .writefn = pmxevtyper_write,
+ .raw_writefn = raw_write },
+ /* Unimplemented, RAZ/WI. */
{ .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2,
- .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+ .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0,
+ .accessfn = pmreg_access },
{ .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0,
.access = PL0_R | PL1_RW,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmuserenr),
@@ -689,34 +642,19 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
REGINFO_SENTINEL
};
-static int teecr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
value &= 1;
env->teecr = value;
- return 0;
}
-static int teehbr_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri)
{
- /* This is a helper function because the user access rights
- * depend on the value of the TEECR.
- */
if (arm_current_pl(env) == 0 && (env->teecr & 1)) {
- return EXCP_UDEF;
+ return CP_ACCESS_TRAP;
}
- *value = env->teehbr;
- return 0;
-}
-
-static int teehbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- if (arm_current_pl(env) == 0 && (env->teecr & 1)) {
- return EXCP_UDEF;
- }
- env->teehbr = value;
- return 0;
+ return CP_ACCESS_OK;
}
static const ARMCPRegInfo t2ee_cp_reginfo[] = {
@@ -726,8 +664,7 @@ static const ARMCPRegInfo t2ee_cp_reginfo[] = {
.writefn = teecr_write },
{ .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr),
- .resetvalue = 0, .raw_readfn = raw_read, .raw_writefn = raw_write,
- .readfn = teehbr_read, .writefn = teehbr_write },
+ .accessfn = teehbr_access, .resetvalue = 0 },
REGINFO_SENTINEL
};
@@ -757,6 +694,59 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
#ifndef CONFIG_USER_ONLY
+static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ /* CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero */
+ if (arm_current_pl(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) {
+ return CP_ACCESS_TRAP;
+ }
+ return CP_ACCESS_OK;
+}
+
+static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx)
+{
+ /* CNT[PV]CT: not visible from PL0 if ELO[PV]CTEN is zero */
+ if (arm_current_pl(env) == 0 &&
+ !extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
+ return CP_ACCESS_TRAP;
+ }
+ return CP_ACCESS_OK;
+}
+
+static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx)
+{
+ /* CNT[PV]_CVAL, CNT[PV]_CTL, CNT[PV]_TVAL: not visible from PL0 if
+ * EL0[PV]TEN is zero.
+ */
+ if (arm_current_pl(env) == 0 &&
+ !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
+ return CP_ACCESS_TRAP;
+ }
+ return CP_ACCESS_OK;
+}
+
+static CPAccessResult gt_pct_access(CPUARMState *env,
+ const ARMCPRegInfo *ri)
+{
+ return gt_counter_access(env, GTIMER_PHYS);
+}
+
+static CPAccessResult gt_vct_access(CPUARMState *env,
+ const ARMCPRegInfo *ri)
+{
+ return gt_counter_access(env, GTIMER_VIRT);
+}
+
+static CPAccessResult gt_ptimer_access(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ return gt_timer_access(env, GTIMER_PHYS);
+}
+
+static CPAccessResult gt_vtimer_access(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ return gt_timer_access(env, GTIMER_VIRT);
+}
+
static uint64_t gt_get_countervalue(CPUARMState *env)
{
return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / GTIMER_SCALE;
@@ -802,17 +792,6 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
}
}
-static int gt_cntfrq_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
-{
- /* Not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero */
- if (arm_current_pl(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) {
- return EXCP_UDEF;
- }
- *value = env->cp15.c14_cntfrq;
- return 0;
-}
-
static void gt_cnt_reset(CPUARMState *env, const ARMCPRegInfo *ri)
{
ARMCPU *cpu = arm_env_get_cpu(env);
@@ -821,81 +800,40 @@ static void gt_cnt_reset(CPUARMState *env, const ARMCPRegInfo *ri)
timer_del(cpu->gt_timer[timeridx]);
}
-static int gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
- int timeridx = ri->opc1 & 1;
-
- if (arm_current_pl(env) == 0 &&
- !extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
- return EXCP_UDEF;
- }
- *value = gt_get_countervalue(env);
- return 0;
+ return gt_get_countervalue(env);
}
-static int gt_cval_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
-{
- int timeridx = ri->opc1 & 1;
-
- if (arm_current_pl(env) == 0 &&
- !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
- return EXCP_UDEF;
- }
- *value = env->cp15.c14_timer[timeridx].cval;
- return 0;
-}
-
-static int gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
int timeridx = ri->opc1 & 1;
env->cp15.c14_timer[timeridx].cval = value;
gt_recalc_timer(arm_env_get_cpu(env), timeridx);
- return 0;
}
-static int gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+
+static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
int timeridx = ri->crm & 1;
- if (arm_current_pl(env) == 0 &&
- !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
- return EXCP_UDEF;
- }
- *value = (uint32_t)(env->cp15.c14_timer[timeridx].cval -
- gt_get_countervalue(env));
- return 0;
+ return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
+ gt_get_countervalue(env));
}
-static int gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
int timeridx = ri->crm & 1;
env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) +
+ sextract64(value, 0, 32);
gt_recalc_timer(arm_env_get_cpu(env), timeridx);
- return 0;
}
-static int gt_ctl_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
-{
- int timeridx = ri->crm & 1;
-
- if (arm_current_pl(env) == 0 &&
- !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
- return EXCP_UDEF;
- }
- *value = env->cp15.c14_timer[timeridx].ctl;
- return 0;
-}
-
-static int gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
ARMCPU *cpu = arm_env_get_cpu(env);
int timeridx = ri->crm & 1;
@@ -912,7 +850,6 @@ static int gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
qemu_set_irq(cpu->gt_timer_outputs[timeridx],
(oldval & 4) && (value & 2));
}
- return 0;
}
void arm_gt_ptimer_cb(void *opaque)
@@ -938,7 +875,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
.access = PL1_RW | PL0_R,
.fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
.resetvalue = (1000 * 1000 * 1000) / GTIMER_SCALE,
- .readfn = gt_cntfrq_read, .raw_readfn = raw_read,
+ .accessfn = gt_cntfrq_access,
},
/* overall control: mostly access permissions */
{ .name = "CNTKCTL", .cp = 15, .crn = 14, .crm = 1, .opc1 = 0, .opc2 = 0,
@@ -951,32 +888,36 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
.type = ARM_CP_IO, .access = PL1_RW | PL0_R,
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
.resetvalue = 0,
- .readfn = gt_ctl_read, .writefn = gt_ctl_write,
- .raw_readfn = raw_read, .raw_writefn = raw_write,
+ .accessfn = gt_ptimer_access,
+ .writefn = gt_ctl_write, .raw_writefn = raw_write,
},
{ .name = "CNTV_CTL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 1,
.type = ARM_CP_IO, .access = PL1_RW | PL0_R,
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
.resetvalue = 0,
- .readfn = gt_ctl_read, .writefn = gt_ctl_write,
- .raw_readfn = raw_read, .raw_writefn = raw_write,
+ .accessfn = gt_vtimer_access,
+ .writefn = gt_ctl_write, .raw_writefn = raw_write,
},
/* TimerValue views: a 32 bit downcounting view of the underlying state */
{ .name = "CNTP_TVAL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0,
.type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
+ .accessfn = gt_ptimer_access,
.readfn = gt_tval_read, .writefn = gt_tval_write,
},
{ .name = "CNTV_TVAL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 0,
.type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
+ .accessfn = gt_vtimer_access,
.readfn = gt_tval_read, .writefn = gt_tval_write,
},
/* The counter itself */
{ .name = "CNTPCT", .cp = 15, .crm = 14, .opc1 = 0,
.access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | ARM_CP_IO,
+ .accessfn = gt_pct_access,
.readfn = gt_cnt_read, .resetfn = gt_cnt_reset,
},
{ .name = "CNTVCT", .cp = 15, .crm = 14, .opc1 = 1,
.access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | ARM_CP_IO,
+ .accessfn = gt_vct_access,
.readfn = gt_cnt_read, .resetfn = gt_cnt_reset,
},
/* Comparison value, indicating when the timer goes off */
@@ -985,16 +926,16 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
.type = ARM_CP_64BIT | ARM_CP_IO,
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
.resetvalue = 0,
- .readfn = gt_cval_read, .writefn = gt_cval_write,
- .raw_readfn = raw_read, .raw_writefn = raw_write,
+ .accessfn = gt_ptimer_access,
+ .writefn = gt_cval_write, .raw_writefn = raw_write,
},
{ .name = "CNTV_CVAL", .cp = 15, .crm = 14, .opc1 = 3,
.access = PL1_RW | PL0_R,
.type = ARM_CP_64BIT | ARM_CP_IO,
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
.resetvalue = 0,
- .readfn = gt_cval_read, .writefn = gt_cval_write,
- .raw_readfn = raw_read, .raw_writefn = raw_write,
+ .accessfn = gt_vtimer_access,
+ .writefn = gt_cval_write, .raw_writefn = raw_write,
},
REGINFO_SENTINEL
};
@@ -1010,7 +951,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
#endif
-static int par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
{
if (arm_feature(env, ARM_FEATURE_LPAE)) {
env->cp15.c7_par = value;
@@ -1019,7 +960,6 @@ static int par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
} else {
env->cp15.c7_par = value & 0xfffff1ff;
}
- return 0;
}
#ifndef CONFIG_USER_ONLY
@@ -1035,7 +975,20 @@ static inline bool extended_addresses_enabled(CPUARMState *env)
&& (env->cp15.c2_control & (1U << 31));
}
-static int ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ if (ri->opc2 & 4) {
+ /* Other states are only available with TrustZone; in
+ * a non-TZ implementation these registers don't exist
+ * at all, which is an Uncategorized trap. This underdecoding
+ * is safe because the reginfo is NO_MIGRATE.
+ */
+ return CP_ACCESS_TRAP_UNCATEGORIZED;
+ }
+ return CP_ACCESS_OK;
+}
+
+static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
{
hwaddr phys_addr;
target_ulong page_size;
@@ -1043,10 +996,6 @@ static int ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
int ret, is_user = ri->opc2 & 2;
int access_type = ri->opc2 & 1;
- if (ri->opc2 & 4) {
- /* Other states are only available with TrustZone */
- return EXCP_UDEF;
- }
ret = get_phys_addr(env, value, access_type, is_user,
&phys_addr, &prot, &page_size);
if (extended_addresses_enabled(env)) {
@@ -1088,7 +1037,6 @@ static int ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
}
env->cp15.c7_par_hi = 0;
}
- return 0;
}
#endif
@@ -1099,7 +1047,8 @@ static const ARMCPRegInfo vapa_cp_reginfo[] = {
.writefn = par_write },
#ifndef CONFIG_USER_ONLY
{ .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY,
- .access = PL1_W, .writefn = ats_write, .type = ARM_CP_NO_MIGRATE },
+ .access = PL1_W, .accessfn = ats_access,
+ .writefn = ats_write, .type = ARM_CP_NO_MIGRATE },
#endif
REGINFO_SENTINEL
};
@@ -1134,52 +1083,26 @@ static uint32_t extended_mpu_ap_bits(uint32_t val)
return ret;
}
-static int pmsav5_data_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void pmsav5_data_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
env->cp15.c5_data = extended_mpu_ap_bits(value);
- return 0;
}
-static int pmsav5_data_ap_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t pmsav5_data_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
- *value = simple_mpu_ap_bits(env->cp15.c5_data);
- return 0;
+ return simple_mpu_ap_bits(env->cp15.c5_data);
}
-static int pmsav5_insn_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void pmsav5_insn_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
env->cp15.c5_insn = extended_mpu_ap_bits(value);
- return 0;
}
-static int pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
- *value = simple_mpu_ap_bits(env->cp15.c5_insn);
- return 0;
-}
-
-static int arm946_prbs_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
-{
- if (ri->crm >= 8) {
- return EXCP_UDEF;
- }
- *value = env->cp15.c6_region[ri->crm];
- return 0;
-}
-
-static int arm946_prbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- if (ri->crm >= 8) {
- return EXCP_UDEF;
- }
- env->cp15.c6_region[ri->crm] = value;
- return 0;
+ return simple_mpu_ap_bits(env->cp15.c5_insn);
}
static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
@@ -1204,14 +1127,35 @@ static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
.access = PL1_RW,
.fieldoffset = offsetof(CPUARMState, cp15.c2_insn), .resetvalue = 0, },
/* Protection region base and size registers */
- { .name = "946_PRBS", .cp = 15, .crn = 6, .crm = CP_ANY, .opc1 = 0,
- .opc2 = CP_ANY, .access = PL1_RW,
- .readfn = arm946_prbs_read, .writefn = arm946_prbs_write, },
+ { .name = "946_PRBS0", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0,
+ .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.c6_region[0]) },
+ { .name = "946_PRBS1", .cp = 15, .crn = 6, .crm = 1, .opc1 = 0,
+ .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.c6_region[1]) },
+ { .name = "946_PRBS2", .cp = 15, .crn = 6, .crm = 2, .opc1 = 0,
+ .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.c6_region[2]) },
+ { .name = "946_PRBS3", .cp = 15, .crn = 6, .crm = 3, .opc1 = 0,
+ .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.c6_region[3]) },
+ { .name = "946_PRBS4", .cp = 15, .crn = 6, .crm = 4, .opc1 = 0,
+ .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.c6_region[4]) },
+ { .name = "946_PRBS5", .cp = 15, .crn = 6, .crm = 5, .opc1 = 0,
+ .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.c6_region[5]) },
+ { .name = "946_PRBS6", .cp = 15, .crn = 6, .crm = 6, .opc1 = 0,
+ .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.c6_region[6]) },
+ { .name = "946_PRBS7", .cp = 15, .crn = 6, .crm = 7, .opc1 = 0,
+ .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.c6_region[7]) },
REGINFO_SENTINEL
};
-static int vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
int maskshift = extract32(value, 0, 3);
@@ -1228,11 +1172,10 @@ static int vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
env->cp15.c2_control = value;
env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> maskshift);
env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> maskshift);
- return 0;
}
-static int vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
if (arm_feature(env, ARM_FEATURE_LPAE)) {
/* With LPAE the TTBCR could result in a change of ASID
@@ -1240,7 +1183,7 @@ static int vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
*/
tlb_flush(env, 1);
}
- return vmsa_ttbcr_raw_write(env, ri, value);
+ vmsa_ttbcr_raw_write(env, ri, value);
}
static void vmsa_ttbcr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
@@ -1273,40 +1216,36 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
REGINFO_SENTINEL
};
-static int omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
env->cp15.c15_ticonfig = value & 0xe7;
/* The OS_TYPE bit in this register changes the reported CPUID! */
env->cp15.c0_cpuid = (value & (1 << 5)) ?
ARM_CPUID_TI915T : ARM_CPUID_TI925T;
- return 0;
}
-static int omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
env->cp15.c15_threadid = value & 0xffff;
- return 0;
}
-static int omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
/* Wait-for-interrupt (deprecated) */
cpu_interrupt(CPU(arm_env_get_cpu(env)), CPU_INTERRUPT_HALT);
- return 0;
}
-static int omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
/* On OMAP there are registers indicating the max/min index of dcache lines
* containing a dirty line; cache flush operations have to reset these.
*/
env->cp15.c15_i_max = 0x000;
env->cp15.c15_i_min = 0xff0;
- return 0;
}
static const ARMCPRegInfo omap_cp_reginfo[] = {
@@ -1348,8 +1287,8 @@ static const ARMCPRegInfo omap_cp_reginfo[] = {
REGINFO_SENTINEL
};
-static int xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
value &= 0x3fff;
if (env->cp15.c15_cpar != value) {
@@ -1357,7 +1296,6 @@ static int xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
tb_flush(env);
env->cp15.c15_cpar = value;
}
- return 0;
}
static const ARMCPRegInfo xscale_cp_reginfo[] = {
@@ -1437,8 +1375,7 @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = {
REGINFO_SENTINEL
};
-static int mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
CPUState *cs = CPU(arm_env_get_cpu(env));
uint32_t mpidr = cs->cpu_index;
@@ -1453,8 +1390,7 @@ static int mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
* not currently model any of those cores.
*/
}
- *value = mpidr;
- return 0;
+ return mpidr;
}
static const ARMCPRegInfo mpidr_cp_reginfo[] = {
@@ -1463,17 +1399,16 @@ static const ARMCPRegInfo mpidr_cp_reginfo[] = {
REGINFO_SENTINEL
};
-static int par64_read(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t *value)
+static uint64_t par64_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
- *value = ((uint64_t)env->cp15.c7_par_hi << 32) | env->cp15.c7_par;
- return 0;
+ return ((uint64_t)env->cp15.c7_par_hi << 32) | env->cp15.c7_par;
}
-static int par64_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void par64_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
env->cp15.c7_par_hi = value >> 32;
env->cp15.c7_par = value;
- return 0;
}
static void par64_reset(CPUARMState *env, const ARMCPRegInfo *ri)
@@ -1482,27 +1417,24 @@ static void par64_reset(CPUARMState *env, const ARMCPRegInfo *ri)
env->cp15.c7_par = 0;
}
-static int ttbr064_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t ttbr064_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
- *value = ((uint64_t)env->cp15.c2_base0_hi << 32) | env->cp15.c2_base0;
- return 0;
+ return ((uint64_t)env->cp15.c2_base0_hi << 32) | env->cp15.c2_base0;
}
-static int ttbr064_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void ttbr064_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
env->cp15.c2_base0_hi = value >> 32;
env->cp15.c2_base0 = value;
- return 0;
}
-static int ttbr064_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void ttbr064_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
/* Writes to the 64 bit format TTBRs may change the ASID */
tlb_flush(env, 1);
- return ttbr064_raw_write(env, ri, value);
+ ttbr064_raw_write(env, ri, value);
}
static void ttbr064_reset(CPUARMState *env, const ARMCPRegInfo *ri)
@@ -1511,19 +1443,16 @@ static void ttbr064_reset(CPUARMState *env, const ARMCPRegInfo *ri)
env->cp15.c2_base0 = 0;
}
-static int ttbr164_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t ttbr164_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
- *value = ((uint64_t)env->cp15.c2_base1_hi << 32) | env->cp15.c2_base1;
- return 0;
+ return ((uint64_t)env->cp15.c2_base1_hi << 32) | env->cp15.c2_base1;
}
-static int ttbr164_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void ttbr164_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
env->cp15.c2_base1_hi = value >> 32;
env->cp15.c2_base1 = value;
- return 0;
}
static void ttbr164_reset(CPUARMState *env, const ARMCPRegInfo *ri)
@@ -1560,32 +1489,26 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
REGINFO_SENTINEL
};
-static int aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
- *value = vfp_get_fpcr(env);
- return 0;
+ return vfp_get_fpcr(env);
}
-static int aa64_fpcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void aa64_fpcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
vfp_set_fpcr(env, value);
- return 0;
}
-static int aa64_fpsr_read(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t *value)
+static uint64_t aa64_fpsr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
- *value = vfp_get_fpsr(env);
- return 0;
+ return vfp_get_fpsr(env);
}
-static int aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
vfp_set_fpsr(env, value);
- return 0;
}
static const ARMCPRegInfo v8_cp_reginfo[] = {
@@ -1618,13 +1541,13 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
REGINFO_SENTINEL
};
-static int sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
env->cp15.c1_sys = value;
/* ??? Lots of these bits are not implemented. */
/* This may enable/disable the MMU, so do a TLB flush. */
tlb_flush(env, 1);
- return 0;
}
void register_cp_regs_for_features(ARMCPU *cpu)
@@ -1707,8 +1630,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
.access = PL0_RW, .resetvalue = cpu->midr & 0xff000000,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
- .readfn = pmreg_read, .writefn = pmcr_write,
- .raw_readfn = raw_read, .raw_writefn = raw_write,
+ .accessfn = pmreg_access, .writefn = pmcr_write,
+ .raw_writefn = raw_write,
};
ARMCPRegInfo clidr = {
.name = "CLIDR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
@@ -2202,17 +2125,15 @@ const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
return g_hash_table_lookup(cpregs, &encoded_cp);
}
-int arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
/* Helper coprocessor write function for write-ignore registers */
- return 0;
}
-int arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t *value)
+uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri)
{
/* Helper coprocessor write function for read-as-zero registers */
- *value = 0;
return 0;
}
@@ -2718,7 +2639,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
return; /* Never happens. Keep compiler happy. */
}
/* High vectors. */
- if (env->cp15.c1_sys & (1 << 13)) {
+ if (env->cp15.c1_sys & SCTLR_V) {
/* when enabled, base address cannot be remapped. */
addr += 0xffff0000;
} else {
@@ -2741,7 +2662,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
/* this is a lie, as the was no c1_sys on V4T/V5, but who cares
* and we should just guard the thumb mode on V4 */
if (arm_feature(env, ARM_FEATURE_V4T)) {
- env->thumb = (env->cp15.c1_sys & (1 << 30)) != 0;
+ env->thumb = (env->cp15.c1_sys & SCTLR_TE) != 0;
}
env->regs[14] = env->regs[15] + offset;
env->regs[15] = addr;
@@ -2767,12 +2688,15 @@ static inline int check_ap(CPUARMState *env, int ap, int domain_prot,
switch (ap) {
case 0:
+ if (arm_feature(env, ARM_FEATURE_V7)) {
+ return 0;
+ }
if (access_type == 1)
return 0;
- switch ((env->cp15.c1_sys >> 8) & 3) {
- case 1:
+ switch (env->cp15.c1_sys & (SCTLR_S | SCTLR_R)) {
+ case SCTLR_S:
return is_user ? 0 : PAGE_READ;
- case 2:
+ case SCTLR_R:
return PAGE_READ;
default:
return 0;
@@ -3003,7 +2927,7 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type,
goto do_fault;
/* The simplified model uses AP[0] as an access control bit. */
- if ((env->cp15.c1_sys & (1 << 29)) && (ap & 1) == 0) {
+ if ((env->cp15.c1_sys & SCTLR_AFE) && (ap & 1) == 0) {
/* Access flag fault. */
code = (code == 15) ? 6 : 3;
goto do_fault;
@@ -3295,7 +3219,7 @@ static inline int get_phys_addr(CPUARMState *env, uint32_t address,
if (address < 0x02000000)
address += env->cp15.c13_fcse;
- if ((env->cp15.c1_sys & 1) == 0) {
+ if ((env->cp15.c1_sys & SCTLR_M) == 0) {
/* MMU/MPU disabled. */
*phys_ptr = address;
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
@@ -3308,7 +3232,7 @@ static inline int get_phys_addr(CPUARMState *env, uint32_t address,
} else if (extended_addresses_enabled(env)) {
return get_phys_addr_lpae(env, address, access_type, is_user, phys_ptr,
prot, page_size);
- } else if (env->cp15.c1_sys & (1 << 23)) {
+ } else if (env->cp15.c1_sys & SCTLR_XP) {
return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr,
prot, page_size);
} else {
diff --git a/target-arm/helper.h b/target-arm/helper.h
index 951e6ad..19bd620 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -57,6 +57,7 @@ DEF_HELPER_1(cpsr_read, i32, env)
DEF_HELPER_3(v7m_msr, void, env, i32, i32)
DEF_HELPER_2(v7m_mrs, i32, env, i32)
+DEF_HELPER_2(access_check_cp_reg, void, env, ptr)
DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
DEF_HELPER_2(get_cp_reg, i32, env, ptr)
DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
@@ -382,6 +383,8 @@ DEF_HELPER_3(neon_cge_f32, i32, i32, i32, ptr)
DEF_HELPER_3(neon_cgt_f32, i32, i32, i32, ptr)
DEF_HELPER_3(neon_acge_f32, i32, i32, i32, ptr)
DEF_HELPER_3(neon_acgt_f32, i32, i32, i32, ptr)
+DEF_HELPER_3(neon_acge_f64, i64, i64, i64, ptr)
+DEF_HELPER_3(neon_acgt_f64, i64, i64, i64, ptr)
/* iwmmxt_helper.c */
DEF_HELPER_2(iwmmxt_maddsq, i64, i64, i64)
diff --git a/target-arm/kvm-consts.h b/target-arm/kvm-consts.h
index 0e7f889..6009a33 100644
--- a/target-arm/kvm-consts.h
+++ b/target-arm/kvm-consts.h
@@ -50,15 +50,29 @@ MISMATCH_CHECK(PSCI_FN_CPU_OFF, KVM_PSCI_FN_CPU_OFF)
MISMATCH_CHECK(PSCI_FN_CPU_ON, KVM_PSCI_FN_CPU_ON)
MISMATCH_CHECK(PSCI_FN_MIGRATE, KVM_PSCI_FN_MIGRATE)
+/* Note that KVM uses overlapping values for AArch32 and AArch64
+ * target CPU numbers. AArch32 targets:
+ */
#define QEMU_KVM_ARM_TARGET_CORTEX_A15 0
+#define QEMU_KVM_ARM_TARGET_CORTEX_A7 1
+
+/* AArch64 targets: */
+#define QEMU_KVM_ARM_TARGET_AEM_V8 0
+#define QEMU_KVM_ARM_TARGET_FOUNDATION_V8 1
+#define QEMU_KVM_ARM_TARGET_CORTEX_A57 2
/* There's no kernel define for this: sentinel value which
* matches no KVM target value for either 64 or 32 bit
*/
#define QEMU_KVM_ARM_TARGET_NONE UINT_MAX
-#ifndef TARGET_AARCH64
+#ifdef TARGET_AARCH64
+MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_AEM_V8, KVM_ARM_TARGET_AEM_V8)
+MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_FOUNDATION_V8, KVM_ARM_TARGET_FOUNDATION_V8)
+MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A57, KVM_ARM_TARGET_CORTEX_A57)
+#else
MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A15, KVM_ARM_TARGET_CORTEX_A15)
+MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A7, KVM_ARM_TARGET_CORTEX_A7)
#endif
#define CP_REG_ARM64 0x6000000000000000ULL
diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index b4c8690..13752ba 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -1823,6 +1823,22 @@ uint32_t HELPER(neon_acgt_f32)(uint32_t a, uint32_t b, void *fpstp)
return -float32_lt(f1, f0, fpst);
}
+uint64_t HELPER(neon_acge_f64)(uint64_t a, uint64_t b, void *fpstp)
+{
+ float_status *fpst = fpstp;
+ float64 f0 = float64_abs(make_float64(a));
+ float64 f1 = float64_abs(make_float64(b));
+ return -float64_le(f1, f0, fpst);
+}
+
+uint64_t HELPER(neon_acgt_f64)(uint64_t a, uint64_t b, void *fpstp)
+{
+ float_status *fpst = fpstp;
+ float64 f0 = float64_abs(make_float64(a));
+ float64 f1 = float64_abs(make_float64(b));
+ return -float64_lt(f1, f0, fpst);
+}
+
#define ELEM(V, N, SIZE) (((V) >> ((N) * (SIZE))) & ((1ull << (SIZE)) - 1))
void HELPER(neon_qunzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index a918e5b..eb0fccd 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -273,44 +273,50 @@ void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
}
}
-void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
+void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip)
{
const ARMCPRegInfo *ri = rip;
- int excp = ri->writefn(env, ri, value);
- if (excp) {
- raise_exception(env, excp);
+ switch (ri->accessfn(env, ri)) {
+ case CP_ACCESS_OK:
+ return;
+ case CP_ACCESS_TRAP:
+ case CP_ACCESS_TRAP_UNCATEGORIZED:
+ /* These cases will eventually need to generate different
+ * syndrome information.
+ */
+ break;
+ default:
+ g_assert_not_reached();
}
+ raise_exception(env, EXCP_UDEF);
+}
+
+void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
+{
+ const ARMCPRegInfo *ri = rip;
+
+ ri->writefn(env, ri, value);
}
uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip)
{
const ARMCPRegInfo *ri = rip;
- uint64_t value;
- int excp = ri->readfn(env, ri, &value);
- if (excp) {
- raise_exception(env, excp);
- }
- return value;
+
+ return ri->readfn(env, ri);
}
void HELPER(set_cp_reg64)(CPUARMState *env, void *rip, uint64_t value)
{
const ARMCPRegInfo *ri = rip;
- int excp = ri->writefn(env, ri, value);
- if (excp) {
- raise_exception(env, excp);
- }
+
+ ri->writefn(env, ri, value);
}
uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
{
const ARMCPRegInfo *ri = rip;
- uint64_t value;
- int excp = ri->readfn(env, ri, &value);
- if (excp) {
- raise_exception(env, excp);
- }
- return value;
+
+ return ri->readfn(env, ri);
}
/* ??? Flag setting arithmetic is awkward because we need to do comparisons.
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index d60223a..8752e7e 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -75,8 +75,12 @@ typedef struct AArch64DecodeTable {
/* Function prototype for gen_ functions for calling Neon helpers */
typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
+typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
+typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
+typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
+typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
/* initialize TCG globals. */
void a64_translate_init(void)
@@ -614,20 +618,26 @@ static void gen_adc_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
*/
/*
- * Store from GPR register to memory
+ * Store from GPR register to memory.
*/
+static void do_gpr_st_memidx(DisasContext *s, TCGv_i64 source,
+ TCGv_i64 tcg_addr, int size, int memidx)
+{
+ g_assert(size <= 3);
+ tcg_gen_qemu_st_i64(source, tcg_addr, memidx, MO_TE + size);
+}
+
static void do_gpr_st(DisasContext *s, TCGv_i64 source,
TCGv_i64 tcg_addr, int size)
{
- g_assert(size <= 3);
- tcg_gen_qemu_st_i64(source, tcg_addr, get_mem_index(s), MO_TE + size);
+ do_gpr_st_memidx(s, source, tcg_addr, size, get_mem_index(s));
}
/*
* Load from memory to GPR register
*/
-static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
- int size, bool is_signed, bool extend)
+static void do_gpr_ld_memidx(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
+ int size, bool is_signed, bool extend, int memidx)
{
TCGMemOp memop = MO_TE + size;
@@ -637,7 +647,7 @@ static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
memop += MO_SIGN;
}
- tcg_gen_qemu_ld_i64(dest, tcg_addr, get_mem_index(s), memop);
+ tcg_gen_qemu_ld_i64(dest, tcg_addr, memidx, memop);
if (extend && is_signed) {
g_assert(size < 3);
@@ -645,6 +655,13 @@ static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
}
}
+static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
+ int size, bool is_signed, bool extend)
+{
+ do_gpr_ld_memidx(s, dest, tcg_addr, size, is_signed, extend,
+ get_mem_index(s));
+}
+
/*
* Store from FP register to memory
*/
@@ -1175,7 +1192,12 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
crn, crm, op0, op1, op2));
if (!ri) {
- /* Unknown register */
+ /* Unknown register; this might be a guest error or a QEMU
+ * unimplemented feature.
+ */
+ qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch64 "
+ "system register op0:%d op1:%d crn:%d crm:%d op2:%d\n",
+ isread ? "read" : "write", op0, op1, crn, crm, op2);
unallocated_encoding(s);
return;
}
@@ -1186,6 +1208,17 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
return;
}
+ if (ri->accessfn) {
+ /* Emit code to perform further access permissions checks at
+ * runtime; this may result in an exception.
+ */
+ TCGv_ptr tmpptr;
+ gen_a64_set_pc_im(s->pc - 4);
+ tmpptr = tcg_const_ptr(ri);
+ gen_helper_access_check_cp_reg(cpu_env, tmpptr);
+ tcg_temp_free_ptr(tmpptr);
+ }
+
/* Handle special cases first */
switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
case ARM_CP_NOP:
@@ -1213,7 +1246,6 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
tcg_gen_movi_i64(tcg_rt, ri->resetvalue);
} else if (ri->readfn) {
TCGv_ptr tmpptr;
- gen_a64_set_pc_im(s->pc - 4);
tmpptr = tcg_const_ptr(ri);
gen_helper_get_cp_reg64(tcg_rt, cpu_env, tmpptr);
tcg_temp_free_ptr(tmpptr);
@@ -1226,7 +1258,6 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
return;
} else if (ri->writefn) {
TCGv_ptr tmpptr;
- gen_a64_set_pc_im(s->pc - 4);
tmpptr = tcg_const_ptr(ri);
gen_helper_set_cp_reg64(cpu_env, tmpptr, tcg_rt);
tcg_temp_free_ptr(tmpptr);
@@ -1471,12 +1502,68 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
}
#else
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
- TCGv_i64 addr, int size, int is_pair)
-{
- qemu_log_mask(LOG_UNIMP,
- "%s:%d: system mode store_exclusive unsupported "
- "at pc=%016" PRIx64 "\n",
- __FILE__, __LINE__, s->pc - 4);
+ TCGv_i64 inaddr, int size, int is_pair)
+{
+ /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]
+ * && (!is_pair || env->exclusive_high == [addr + datasize])) {
+ * [addr] = {Rt};
+ * if (is_pair) {
+ * [addr + datasize] = {Rt2};
+ * }
+ * {Rd} = 0;
+ * } else {
+ * {Rd} = 1;
+ * }
+ * env->exclusive_addr = -1;
+ */
+ int fail_label = gen_new_label();
+ int done_label = gen_new_label();
+ TCGv_i64 addr = tcg_temp_local_new_i64();
+ TCGv_i64 tmp;
+
+ /* Copy input into a local temp so it is not trashed when the
+ * basic block ends at the branch insn.
+ */
+ tcg_gen_mov_i64(addr, inaddr);
+ tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
+
+ tmp = tcg_temp_new_i64();
+ tcg_gen_qemu_ld_i64(tmp, addr, get_mem_index(s), MO_TE + size);
+ tcg_gen_brcond_i64(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
+ tcg_temp_free_i64(tmp);
+
+ if (is_pair) {
+ TCGv_i64 addrhi = tcg_temp_new_i64();
+ TCGv_i64 tmphi = tcg_temp_new_i64();
+
+ tcg_gen_addi_i64(addrhi, addr, 1 << size);
+ tcg_gen_qemu_ld_i64(tmphi, addrhi, get_mem_index(s), MO_TE + size);
+ tcg_gen_brcond_i64(TCG_COND_NE, tmphi, cpu_exclusive_high, fail_label);
+
+ tcg_temp_free_i64(tmphi);
+ tcg_temp_free_i64(addrhi);
+ }
+
+ /* We seem to still have the exclusive monitor, so do the store */
+ tcg_gen_qemu_st_i64(cpu_reg(s, rt), addr, get_mem_index(s), MO_TE + size);
+ if (is_pair) {
+ TCGv_i64 addrhi = tcg_temp_new_i64();
+
+ tcg_gen_addi_i64(addrhi, addr, 1 << size);
+ tcg_gen_qemu_st_i64(cpu_reg(s, rt2), addrhi,
+ get_mem_index(s), MO_TE + size);
+ tcg_temp_free_i64(addrhi);
+ }
+
+ tcg_temp_free_i64(addr);
+
+ tcg_gen_movi_i64(cpu_reg(s, rd), 0);
+ tcg_gen_br(done_label);
+ gen_set_label(fail_label);
+ tcg_gen_movi_i64(cpu_reg(s, rd), 1);
+ gen_set_label(done_label);
+ tcg_gen_movi_i64(cpu_exclusive_addr, -1);
+
}
#endif
@@ -1750,6 +1837,7 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
* +----+-------+---+-----+-----+---+--------+-----+------+------+
*
* idx = 01 -> post-indexed, 11 pre-indexed, 00 unscaled imm. (no writeback)
+ 10 -> unprivileged
* V = 0 -> non-vector
* size: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64bit
* opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
@@ -1765,6 +1853,7 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn)
bool is_signed = false;
bool is_store = false;
bool is_extended = false;
+ bool is_unpriv = (idx == 2);
bool is_vector = extract32(insn, 26, 1);
bool post_index;
bool writeback;
@@ -1773,7 +1862,7 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn)
if (is_vector) {
size |= (opc & 2) << 1;
- if (size > 4) {
+ if (size > 4 || is_unpriv) {
unallocated_encoding(s);
return;
}
@@ -1781,6 +1870,10 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn)
} else {
if (size == 3 && opc == 2) {
/* PRFM - prefetch */
+ if (is_unpriv) {
+ unallocated_encoding(s);
+ return;
+ }
return;
}
if (opc == 3 && size > 1) {
@@ -1794,6 +1887,7 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn)
switch (idx) {
case 0:
+ case 2:
post_index = false;
writeback = false;
break;
@@ -1805,9 +1899,6 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn)
post_index = false;
writeback = true;
break;
- case 2:
- g_assert(false);
- break;
}
if (rn == 31) {
@@ -1827,10 +1918,13 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn)
}
} else {
TCGv_i64 tcg_rt = cpu_reg(s, rt);
+ int memidx = is_unpriv ? 1 : get_mem_index(s);
+
if (is_store) {
- do_gpr_st(s, tcg_rt, tcg_addr, size);
+ do_gpr_st_memidx(s, tcg_rt, tcg_addr, size, memidx);
} else {
- do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
+ do_gpr_ld_memidx(s, tcg_rt, tcg_addr, size,
+ is_signed, is_extended, memidx);
}
}
@@ -2010,25 +2104,6 @@ static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn)
}
}
-/* Load/store register (immediate forms) */
-static void disas_ldst_reg_imm(DisasContext *s, uint32_t insn)
-{
- switch (extract32(insn, 10, 2)) {
- case 0: case 1: case 3:
- /* Load/store register (unscaled immediate) */
- /* Load/store immediate pre/post-indexed */
- disas_ldst_reg_imm9(s, insn);
- break;
- case 2:
- /* Load/store register unprivileged */
- unsupported_encoding(s, insn);
- break;
- default:
- unallocated_encoding(s);
- break;
- }
-}
-
/* Load/store register (all forms) */
static void disas_ldst_reg(DisasContext *s, uint32_t insn)
{
@@ -2037,7 +2112,11 @@ static void disas_ldst_reg(DisasContext *s, uint32_t insn)
if (extract32(insn, 21, 1) == 1 && extract32(insn, 10, 2) == 2) {
disas_ldst_reg_roffset(s, insn);
} else {
- disas_ldst_reg_imm(s, insn);
+ /* Load/store register (unscaled immediate)
+ * Load/store immediate pre/post-indexed
+ * Load/store register unprivileged
+ */
+ disas_ldst_reg_imm9(s, insn);
}
break;
case 1:
@@ -5838,7 +5917,100 @@ static void disas_simd_scalar_shift_imm(DisasContext *s, uint32_t insn)
*/
static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
{
- unsupported_encoding(s, insn);
+ bool is_u = extract32(insn, 29, 1);
+ int size = extract32(insn, 22, 2);
+ int opcode = extract32(insn, 12, 4);
+ int rm = extract32(insn, 16, 5);
+ int rn = extract32(insn, 5, 5);
+ int rd = extract32(insn, 0, 5);
+
+ if (is_u) {
+ unallocated_encoding(s);
+ return;
+ }
+
+ switch (opcode) {
+ case 0x9: /* SQDMLAL, SQDMLAL2 */
+ case 0xb: /* SQDMLSL, SQDMLSL2 */
+ case 0xd: /* SQDMULL, SQDMULL2 */
+ if (size == 0 || size == 3) {
+ unallocated_encoding(s);
+ return;
+ }
+ break;
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+
+ if (size == 2) {
+ TCGv_i64 tcg_op1 = tcg_temp_new_i64();
+ TCGv_i64 tcg_op2 = tcg_temp_new_i64();
+ TCGv_i64 tcg_res = tcg_temp_new_i64();
+
+ read_vec_element(s, tcg_op1, rn, 0, MO_32 | MO_SIGN);
+ read_vec_element(s, tcg_op2, rm, 0, MO_32 | MO_SIGN);
+
+ tcg_gen_mul_i64(tcg_res, tcg_op1, tcg_op2);
+ gen_helper_neon_addl_saturate_s64(tcg_res, cpu_env, tcg_res, tcg_res);
+
+ switch (opcode) {
+ case 0xd: /* SQDMULL, SQDMULL2 */
+ break;
+ case 0xb: /* SQDMLSL, SQDMLSL2 */
+ tcg_gen_neg_i64(tcg_res, tcg_res);
+ /* fall through */
+ case 0x9: /* SQDMLAL, SQDMLAL2 */
+ read_vec_element(s, tcg_op1, rd, 0, MO_64);
+ gen_helper_neon_addl_saturate_s64(tcg_res, cpu_env,
+ tcg_res, tcg_op1);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ write_fp_dreg(s, rd, tcg_res);
+
+ tcg_temp_free_i64(tcg_op1);
+ tcg_temp_free_i64(tcg_op2);
+ tcg_temp_free_i64(tcg_res);
+ } else {
+ TCGv_i32 tcg_op1 = tcg_temp_new_i32();
+ TCGv_i32 tcg_op2 = tcg_temp_new_i32();
+ TCGv_i64 tcg_res = tcg_temp_new_i64();
+
+ read_vec_element_i32(s, tcg_op1, rn, 0, MO_16);
+ read_vec_element_i32(s, tcg_op2, rm, 0, MO_16);
+
+ gen_helper_neon_mull_s16(tcg_res, tcg_op1, tcg_op2);
+ gen_helper_neon_addl_saturate_s32(tcg_res, cpu_env, tcg_res, tcg_res);
+
+ switch (opcode) {
+ case 0xd: /* SQDMULL, SQDMULL2 */
+ break;
+ case 0xb: /* SQDMLSL, SQDMLSL2 */
+ gen_helper_neon_negl_u32(tcg_res, tcg_res);
+ /* fall through */
+ case 0x9: /* SQDMLAL, SQDMLAL2 */
+ {
+ TCGv_i64 tcg_op3 = tcg_temp_new_i64();
+ read_vec_element(s, tcg_op3, rd, 0, MO_32);
+ gen_helper_neon_addl_saturate_s32(tcg_res, cpu_env,
+ tcg_res, tcg_op3);
+ tcg_temp_free_i64(tcg_op3);
+ break;
+ }
+ default:
+ g_assert_not_reached();
+ }
+
+ tcg_gen_ext32u_i64(tcg_res, tcg_res);
+ write_fp_dreg(s, rd, tcg_res);
+
+ tcg_temp_free_i32(tcg_op1);
+ tcg_temp_free_i32(tcg_op2);
+ tcg_temp_free_i64(tcg_res);
+ }
}
static void handle_3same_64(DisasContext *s, int opcode, bool u,
@@ -5950,15 +6122,33 @@ static void handle_3same_float(DisasContext *s, int size, int elements,
read_vec_element(s, tcg_op2, rm, pass, MO_64);
switch (fpopcode) {
+ case 0x39: /* FMLS */
+ /* As usual for ARM, separate negation for fused multiply-add */
+ gen_helper_vfp_negd(tcg_op1, tcg_op1);
+ /* fall through */
+ case 0x19: /* FMLA */
+ read_vec_element(s, tcg_res, rd, pass, MO_64);
+ gen_helper_vfp_muladdd(tcg_res, tcg_op1, tcg_op2,
+ tcg_res, fpst);
+ break;
case 0x18: /* FMAXNM */
gen_helper_vfp_maxnumd(tcg_res, tcg_op1, tcg_op2, fpst);
break;
case 0x1a: /* FADD */
gen_helper_vfp_addd(tcg_res, tcg_op1, tcg_op2, fpst);
break;
+ case 0x1b: /* FMULX */
+ gen_helper_vfp_mulxd(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x1c: /* FCMEQ */
+ gen_helper_neon_ceq_f64(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
case 0x1e: /* FMAX */
gen_helper_vfp_maxd(tcg_res, tcg_op1, tcg_op2, fpst);
break;
+ case 0x1f: /* FRECPS */
+ gen_helper_recpsf_f64(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
case 0x38: /* FMINNM */
gen_helper_vfp_minnumd(tcg_res, tcg_op1, tcg_op2, fpst);
break;
@@ -5968,9 +6158,18 @@ static void handle_3same_float(DisasContext *s, int size, int elements,
case 0x3e: /* FMIN */
gen_helper_vfp_mind(tcg_res, tcg_op1, tcg_op2, fpst);
break;
+ case 0x3f: /* FRSQRTS */
+ gen_helper_rsqrtsf_f64(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
case 0x5b: /* FMUL */
gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst);
break;
+ case 0x5c: /* FCMGE */
+ gen_helper_neon_cge_f64(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x5d: /* FACGE */
+ gen_helper_neon_acge_f64(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
case 0x5f: /* FDIV */
gen_helper_vfp_divd(tcg_res, tcg_op1, tcg_op2, fpst);
break;
@@ -5978,6 +6177,12 @@ static void handle_3same_float(DisasContext *s, int size, int elements,
gen_helper_vfp_subd(tcg_res, tcg_op1, tcg_op2, fpst);
gen_helper_vfp_absd(tcg_res, tcg_res);
break;
+ case 0x7c: /* FCMGT */
+ gen_helper_neon_cgt_f64(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x7d: /* FACGT */
+ gen_helper_neon_acgt_f64(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
default:
g_assert_not_reached();
}
@@ -5997,12 +6202,30 @@ static void handle_3same_float(DisasContext *s, int size, int elements,
read_vec_element_i32(s, tcg_op2, rm, pass, MO_32);
switch (fpopcode) {
+ case 0x39: /* FMLS */
+ /* As usual for ARM, separate negation for fused multiply-add */
+ gen_helper_vfp_negs(tcg_op1, tcg_op1);
+ /* fall through */
+ case 0x19: /* FMLA */
+ read_vec_element_i32(s, tcg_res, rd, pass, MO_32);
+ gen_helper_vfp_muladds(tcg_res, tcg_op1, tcg_op2,
+ tcg_res, fpst);
+ break;
case 0x1a: /* FADD */
gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst);
break;
+ case 0x1b: /* FMULX */
+ gen_helper_vfp_mulxs(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x1c: /* FCMEQ */
+ gen_helper_neon_ceq_f32(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
case 0x1e: /* FMAX */
gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst);
break;
+ case 0x1f: /* FRECPS */
+ gen_helper_recpsf_f32(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
case 0x18: /* FMAXNM */
gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst);
break;
@@ -6015,9 +6238,18 @@ static void handle_3same_float(DisasContext *s, int size, int elements,
case 0x3e: /* FMIN */
gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst);
break;
+ case 0x3f: /* FRSQRTS */
+ gen_helper_rsqrtsf_f32(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
case 0x5b: /* FMUL */
gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst);
break;
+ case 0x5c: /* FCMGE */
+ gen_helper_neon_cge_f32(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x5d: /* FACGE */
+ gen_helper_neon_acge_f32(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
case 0x5f: /* FDIV */
gen_helper_vfp_divs(tcg_res, tcg_op1, tcg_op2, fpst);
break;
@@ -6025,6 +6257,12 @@ static void handle_3same_float(DisasContext *s, int size, int elements,
gen_helper_vfp_subs(tcg_res, tcg_op1, tcg_op2, fpst);
gen_helper_vfp_abss(tcg_res, tcg_res);
break;
+ case 0x7c: /* FCMGT */
+ gen_helper_neon_cgt_f32(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x7d: /* FACGT */
+ gen_helper_neon_acgt_f32(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
default:
g_assert_not_reached();
}
@@ -6075,15 +6313,13 @@ static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn)
int fpopcode = opcode | (extract32(size, 1, 1) << 5) | (u << 6);
switch (fpopcode) {
case 0x1b: /* FMULX */
- case 0x1c: /* FCMEQ */
case 0x1f: /* FRECPS */
case 0x3f: /* FRSQRTS */
- case 0x5c: /* FCMGE */
case 0x5d: /* FACGE */
- case 0x7c: /* FCMGT */
case 0x7d: /* FACGT */
- unsupported_encoding(s, insn);
- return;
+ case 0x1c: /* FCMEQ */
+ case 0x5c: /* FCMGE */
+ case 0x7c: /* FCMGT */
case 0x7a: /* FABD */
break;
default:
@@ -6268,6 +6504,115 @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u,
}
}
+static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
+ bool is_scalar, bool is_u, bool is_q,
+ int size, int rn, int rd)
+{
+ bool is_double = (size == 3);
+ TCGv_ptr fpst = get_fpstatus_ptr();
+
+ if (is_double) {
+ TCGv_i64 tcg_op = tcg_temp_new_i64();
+ TCGv_i64 tcg_zero = tcg_const_i64(0);
+ TCGv_i64 tcg_res = tcg_temp_new_i64();
+ NeonGenTwoDoubleOPFn *genfn;
+ bool swap = false;
+ int pass;
+
+ switch (opcode) {
+ case 0x2e: /* FCMLT (zero) */
+ swap = true;
+ /* fallthrough */
+ case 0x2c: /* FCMGT (zero) */
+ genfn = gen_helper_neon_cgt_f64;
+ break;
+ case 0x2d: /* FCMEQ (zero) */
+ genfn = gen_helper_neon_ceq_f64;
+ break;
+ case 0x6d: /* FCMLE (zero) */
+ swap = true;
+ /* fall through */
+ case 0x6c: /* FCMGE (zero) */
+ genfn = gen_helper_neon_cge_f64;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
+ read_vec_element(s, tcg_op, rn, pass, MO_64);
+ if (swap) {
+ genfn(tcg_res, tcg_zero, tcg_op, fpst);
+ } else {
+ genfn(tcg_res, tcg_op, tcg_zero, fpst);
+ }
+ write_vec_element(s, tcg_res, rd, pass, MO_64);
+ }
+ if (is_scalar) {
+ clear_vec_high(s, rd);
+ }
+
+ tcg_temp_free_i64(tcg_res);
+ tcg_temp_free_i64(tcg_zero);
+ tcg_temp_free_i64(tcg_op);
+ } else {
+ TCGv_i32 tcg_op = tcg_temp_new_i32();
+ TCGv_i32 tcg_zero = tcg_const_i32(0);
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
+ NeonGenTwoSingleOPFn *genfn;
+ bool swap = false;
+ int pass, maxpasses;
+
+ switch (opcode) {
+ case 0x2e: /* FCMLT (zero) */
+ swap = true;
+ /* fall through */
+ case 0x2c: /* FCMGT (zero) */
+ genfn = gen_helper_neon_cgt_f32;
+ break;
+ case 0x2d: /* FCMEQ (zero) */
+ genfn = gen_helper_neon_ceq_f32;
+ break;
+ case 0x6d: /* FCMLE (zero) */
+ swap = true;
+ /* fall through */
+ case 0x6c: /* FCMGE (zero) */
+ genfn = gen_helper_neon_cge_f32;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ if (is_scalar) {
+ maxpasses = 1;
+ } else {
+ maxpasses = is_q ? 4 : 2;
+ }
+
+ for (pass = 0; pass < maxpasses; pass++) {
+ read_vec_element_i32(s, tcg_op, rn, pass, MO_32);
+ if (swap) {
+ genfn(tcg_res, tcg_zero, tcg_op, fpst);
+ } else {
+ genfn(tcg_res, tcg_op, tcg_zero, fpst);
+ }
+ if (is_scalar) {
+ write_fp_sreg(s, rd, tcg_res);
+ } else {
+ write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
+ }
+ }
+ tcg_temp_free_i32(tcg_res);
+ tcg_temp_free_i32(tcg_zero);
+ tcg_temp_free_i32(tcg_op);
+ if (!is_q && !is_scalar) {
+ clear_vec_high(s, rd);
+ }
+ }
+
+ tcg_temp_free_ptr(fpst);
+}
+
/* C3.6.12 AdvSIMD scalar two reg misc
* 31 30 29 28 24 23 22 21 17 16 12 11 10 9 5 4 0
* +-----+---+-----------+------+-----------+--------+-----+------+------+
@@ -6297,9 +6642,47 @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
return;
}
break;
+ case 0xc ... 0xf:
+ case 0x16 ... 0x1d:
+ case 0x1f:
+ /* Floating point: U, size[1] and opcode indicate operation;
+ * size[0] indicates single or double precision.
+ */
+ opcode |= (extract32(size, 1, 1) << 5) | (u << 6);
+ size = extract32(size, 0, 1) ? 3 : 2;
+ switch (opcode) {
+ case 0x2c: /* FCMGT (zero) */
+ case 0x2d: /* FCMEQ (zero) */
+ case 0x2e: /* FCMLT (zero) */
+ case 0x6c: /* FCMGE (zero) */
+ case 0x6d: /* FCMLE (zero) */
+ handle_2misc_fcmp_zero(s, opcode, true, u, true, size, rn, rd);
+ return;
+ case 0x1a: /* FCVTNS */
+ case 0x1b: /* FCVTMS */
+ case 0x1c: /* FCVTAS */
+ case 0x1d: /* SCVTF */
+ case 0x3a: /* FCVTPS */
+ case 0x3b: /* FCVTZS */
+ case 0x3d: /* FRECPE */
+ case 0x3f: /* FRECPX */
+ case 0x56: /* FCVTXN, FCVTXN2 */
+ case 0x5a: /* FCVTNU */
+ case 0x5b: /* FCVTMU */
+ case 0x5c: /* FCVTAU */
+ case 0x5d: /* UCVTF */
+ case 0x7a: /* FCVTPU */
+ case 0x7b: /* FCVTZU */
+ case 0x7d: /* FRSQRTE */
+ unsupported_encoding(s, insn);
+ return;
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+ break;
default:
/* Other categories of encoding in this class:
- * + floating point (single and double)
* + SUQADD/USQADD/SQABS/SQNEG : size 8, 16, 32 or 64
* + SQXTN/SQXTN2/SQXTUN/SQXTUN2/UQXTN/UQXTN2:
* narrowing saturate ops: size 64/32/16 -> 32/16/8
@@ -6322,17 +6705,6 @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
}
}
-/* C3.6.13 AdvSIMD scalar x indexed element
- * 31 30 29 28 24 23 22 21 20 19 16 15 12 11 10 9 5 4 0
- * +-----+---+-----------+------+---+---+------+-----+---+---+------+------+
- * | 0 1 | U | 1 1 1 1 1 | size | L | M | Rm | opc | H | 0 | Rn | Rd |
- * +-----+---+-----------+------+---+---+------+-----+---+---+------+------+
- */
-static void disas_simd_scalar_indexed(DisasContext *s, uint32_t insn)
-{
- unsupported_encoding(s, insn);
-}
-
/* SSHR[RA]/USHR[RA] - Vector shift right (optional rounding/accumulate) */
static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
int immh, int immb, int opcode, int rn, int rd)
@@ -6514,6 +6886,24 @@ static void disas_simd_shift_imm(DisasContext *s, uint32_t insn)
}
}
+/* Generate code to do a "long" addition or subtraction, ie one done in
+ * TCGv_i64 on vector lanes twice the width specified by size.
+ */
+static void gen_neon_addl(int size, bool is_sub, TCGv_i64 tcg_res,
+ TCGv_i64 tcg_op1, TCGv_i64 tcg_op2)
+{
+ static NeonGenTwo64OpFn * const fns[3][2] = {
+ { gen_helper_neon_addl_u16, gen_helper_neon_subl_u16 },
+ { gen_helper_neon_addl_u32, gen_helper_neon_subl_u32 },
+ { tcg_gen_add_i64, tcg_gen_sub_i64 },
+ };
+ NeonGenTwo64OpFn *genfn;
+ assert(size < 3);
+
+ genfn = fns[size][is_sub];
+ genfn(tcg_res, tcg_op1, tcg_op2);
+}
+
static void handle_3rd_widening(DisasContext *s, int is_q, int is_u, int size,
int opcode, int rd, int rn, int rm)
{
@@ -6569,6 +6959,12 @@ static void handle_3rd_widening(DisasContext *s, int is_q, int is_u, int size,
}
switch (opcode) {
+ case 0: /* SADDL, SADDL2, UADDL, UADDL2 */
+ tcg_gen_add_i64(tcg_passres, tcg_op1, tcg_op2);
+ break;
+ case 2: /* SSUBL, SSUBL2, USUBL, USUBL2 */
+ tcg_gen_sub_i64(tcg_passres, tcg_op1, tcg_op2);
+ break;
case 5: /* SABAL, SABAL2, UABAL, UABAL2 */
case 7: /* SABDL, SABDL2, UABDL, UABDL2 */
{
@@ -6589,15 +6985,31 @@ static void handle_3rd_widening(DisasContext *s, int is_q, int is_u, int size,
case 12: /* UMULL, UMULL2, SMULL, SMULL2 */
tcg_gen_mul_i64(tcg_passres, tcg_op1, tcg_op2);
break;
+ case 9: /* SQDMLAL, SQDMLAL2 */
+ case 11: /* SQDMLSL, SQDMLSL2 */
+ case 13: /* SQDMULL, SQDMULL2 */
+ tcg_gen_mul_i64(tcg_passres, tcg_op1, tcg_op2);
+ gen_helper_neon_addl_saturate_s64(tcg_passres, cpu_env,
+ tcg_passres, tcg_passres);
+ break;
default:
g_assert_not_reached();
}
- if (accop > 0) {
+ if (opcode == 9 || opcode == 11) {
+ /* saturating accumulate ops */
+ if (accop < 0) {
+ tcg_gen_neg_i64(tcg_passres, tcg_passres);
+ }
+ gen_helper_neon_addl_saturate_s64(tcg_res[pass], cpu_env,
+ tcg_res[pass], tcg_passres);
+ } else if (accop > 0) {
tcg_gen_add_i64(tcg_res[pass], tcg_res[pass], tcg_passres);
- tcg_temp_free_i64(tcg_passres);
} else if (accop < 0) {
tcg_gen_sub_i64(tcg_res[pass], tcg_res[pass], tcg_passres);
+ }
+
+ if (accop != 0) {
tcg_temp_free_i64(tcg_passres);
}
@@ -6622,6 +7034,23 @@ static void handle_3rd_widening(DisasContext *s, int is_q, int is_u, int size,
}
switch (opcode) {
+ case 0: /* SADDL, SADDL2, UADDL, UADDL2 */
+ case 2: /* SSUBL, SSUBL2, USUBL, USUBL2 */
+ {
+ TCGv_i64 tcg_op2_64 = tcg_temp_new_i64();
+ static NeonGenWidenFn * const widenfns[2][2] = {
+ { gen_helper_neon_widen_s8, gen_helper_neon_widen_u8 },
+ { gen_helper_neon_widen_s16, gen_helper_neon_widen_u16 },
+ };
+ NeonGenWidenFn *widenfn = widenfns[size][is_u];
+
+ widenfn(tcg_op2_64, tcg_op2);
+ widenfn(tcg_passres, tcg_op1);
+ gen_neon_addl(size, (opcode == 2), tcg_passres,
+ tcg_passres, tcg_op2_64);
+ tcg_temp_free_i64(tcg_op2_64);
+ break;
+ }
case 5: /* SABAL, SABAL2, UABAL, UABAL2 */
case 7: /* SABDL, SABDL2, UABDL, UABDL2 */
if (size == 0) {
@@ -6655,28 +7084,32 @@ static void handle_3rd_widening(DisasContext *s, int is_q, int is_u, int size,
}
}
break;
+ case 9: /* SQDMLAL, SQDMLAL2 */
+ case 11: /* SQDMLSL, SQDMLSL2 */
+ case 13: /* SQDMULL, SQDMULL2 */
+ assert(size == 1);
+ gen_helper_neon_mull_s16(tcg_passres, tcg_op1, tcg_op2);
+ gen_helper_neon_addl_saturate_s32(tcg_passres, cpu_env,
+ tcg_passres, tcg_passres);
+ break;
default:
g_assert_not_reached();
}
tcg_temp_free_i32(tcg_op1);
tcg_temp_free_i32(tcg_op2);
- if (accop > 0) {
- if (size == 0) {
- gen_helper_neon_addl_u16(tcg_res[pass], tcg_res[pass],
- tcg_passres);
- } else {
- gen_helper_neon_addl_u32(tcg_res[pass], tcg_res[pass],
- tcg_passres);
- }
- tcg_temp_free_i64(tcg_passres);
- } else if (accop < 0) {
- if (size == 0) {
- gen_helper_neon_subl_u16(tcg_res[pass], tcg_res[pass],
- tcg_passres);
+ if (accop != 0) {
+ if (opcode == 9 || opcode == 11) {
+ /* saturating accumulate ops */
+ if (accop < 0) {
+ gen_helper_neon_negl_u32(tcg_passres, tcg_passres);
+ }
+ gen_helper_neon_addl_saturate_s32(tcg_res[pass], cpu_env,
+ tcg_res[pass],
+ tcg_passres);
} else {
- gen_helper_neon_subl_u32(tcg_res[pass], tcg_res[pass],
- tcg_passres);
+ gen_neon_addl(size, (accop < 0), tcg_res[pass],
+ tcg_res[pass], tcg_passres);
}
tcg_temp_free_i64(tcg_passres);
}
@@ -6689,6 +7122,95 @@ static void handle_3rd_widening(DisasContext *s, int is_q, int is_u, int size,
tcg_temp_free_i64(tcg_res[1]);
}
+static void handle_3rd_wide(DisasContext *s, int is_q, int is_u, int size,
+ int opcode, int rd, int rn, int rm)
+{
+ TCGv_i64 tcg_res[2];
+ int part = is_q ? 2 : 0;
+ int pass;
+
+ for (pass = 0; pass < 2; pass++) {
+ TCGv_i64 tcg_op1 = tcg_temp_new_i64();
+ TCGv_i32 tcg_op2 = tcg_temp_new_i32();
+ TCGv_i64 tcg_op2_wide = tcg_temp_new_i64();
+ static NeonGenWidenFn * const widenfns[3][2] = {
+ { gen_helper_neon_widen_s8, gen_helper_neon_widen_u8 },
+ { gen_helper_neon_widen_s16, gen_helper_neon_widen_u16 },
+ { tcg_gen_ext_i32_i64, tcg_gen_extu_i32_i64 },
+ };
+ NeonGenWidenFn *widenfn = widenfns[size][is_u];
+
+ read_vec_element(s, tcg_op1, rn, pass, MO_64);
+ read_vec_element_i32(s, tcg_op2, rm, part + pass, MO_32);
+ widenfn(tcg_op2_wide, tcg_op2);
+ tcg_temp_free_i32(tcg_op2);
+ tcg_res[pass] = tcg_temp_new_i64();
+ gen_neon_addl(size, (opcode == 3),
+ tcg_res[pass], tcg_op1, tcg_op2_wide);
+ tcg_temp_free_i64(tcg_op1);
+ tcg_temp_free_i64(tcg_op2_wide);
+ }
+
+ for (pass = 0; pass < 2; pass++) {
+ write_vec_element(s, tcg_res[pass], rd, pass, MO_64);
+ tcg_temp_free_i64(tcg_res[pass]);
+ }
+}
+
+static void do_narrow_high_u32(TCGv_i32 res, TCGv_i64 in)
+{
+ tcg_gen_shri_i64(in, in, 32);
+ tcg_gen_trunc_i64_i32(res, in);
+}
+
+static void do_narrow_round_high_u32(TCGv_i32 res, TCGv_i64 in)
+{
+ tcg_gen_addi_i64(in, in, 1U << 31);
+ do_narrow_high_u32(res, in);
+}
+
+static void handle_3rd_narrowing(DisasContext *s, int is_q, int is_u, int size,
+ int opcode, int rd, int rn, int rm)
+{
+ TCGv_i32 tcg_res[2];
+ int part = is_q ? 2 : 0;
+ int pass;
+
+ for (pass = 0; pass < 2; pass++) {
+ TCGv_i64 tcg_op1 = tcg_temp_new_i64();
+ TCGv_i64 tcg_op2 = tcg_temp_new_i64();
+ TCGv_i64 tcg_wideres = tcg_temp_new_i64();
+ static NeonGenNarrowFn * const narrowfns[3][2] = {
+ { gen_helper_neon_narrow_high_u8,
+ gen_helper_neon_narrow_round_high_u8 },
+ { gen_helper_neon_narrow_high_u16,
+ gen_helper_neon_narrow_round_high_u16 },
+ { do_narrow_high_u32, do_narrow_round_high_u32 },
+ };
+ NeonGenNarrowFn *gennarrow = narrowfns[size][is_u];
+
+ read_vec_element(s, tcg_op1, rn, pass, MO_64);
+ read_vec_element(s, tcg_op2, rm, pass, MO_64);
+
+ gen_neon_addl(size, (opcode == 6), tcg_wideres, tcg_op1, tcg_op2);
+
+ tcg_temp_free_i64(tcg_op1);
+ tcg_temp_free_i64(tcg_op2);
+
+ tcg_res[pass] = tcg_temp_new_i32();
+ gennarrow(tcg_res[pass], tcg_wideres);
+ tcg_temp_free_i64(tcg_wideres);
+ }
+
+ for (pass = 0; pass < 2; pass++) {
+ write_vec_element_i32(s, tcg_res[pass], rd, pass + part, MO_32);
+ tcg_temp_free_i32(tcg_res[pass]);
+ }
+ if (!is_q) {
+ clear_vec_high(s, rd);
+ }
+}
+
/* C3.6.15 AdvSIMD three different
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0
* +---+---+---+-----------+------+---+------+--------+-----+------+------+
@@ -6719,31 +7241,43 @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
case 1: /* SADDW, SADDW2, UADDW, UADDW2 */
case 3: /* SSUBW, SSUBW2, USUBW, USUBW2 */
/* 64 x 128 -> 128 */
- unsupported_encoding(s, insn);
+ if (size == 3) {
+ unallocated_encoding(s);
+ return;
+ }
+ handle_3rd_wide(s, is_q, is_u, size, opcode, rd, rn, rm);
break;
case 4: /* ADDHN, ADDHN2, RADDHN, RADDHN2 */
case 6: /* SUBHN, SUBHN2, RSUBHN, RSUBHN2 */
/* 128 x 128 -> 64 */
- unsupported_encoding(s, insn);
+ if (size == 3) {
+ unallocated_encoding(s);
+ return;
+ }
+ handle_3rd_narrowing(s, is_q, is_u, size, opcode, rd, rn, rm);
break;
- case 9:
- case 11:
- case 13:
- case 14:
- if (is_u) {
+ case 14: /* PMULL, PMULL2 */
+ if (is_u || size == 1 || size == 2) {
unallocated_encoding(s);
return;
}
- /* fall through */
- case 0:
- case 2:
unsupported_encoding(s, insn);
break;
- case 5:
- case 7:
- case 8:
- case 10:
- case 12:
+ case 9: /* SQDMLAL, SQDMLAL2 */
+ case 11: /* SQDMLSL, SQDMLSL2 */
+ case 13: /* SQDMULL, SQDMULL2 */
+ if (is_u || size == 0) {
+ unallocated_encoding(s);
+ return;
+ }
+ /* fall through */
+ case 0: /* SADDL, SADDL2, UADDL, UADDL2 */
+ case 2: /* SSUBL, SSUBL2, USUBL, USUBL2 */
+ case 5: /* SABAL, SABAL2, UABAL, UABAL2 */
+ case 7: /* SABDL, SABDL2, UABDL, UABDL2 */
+ case 8: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
+ case 10: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
+ case 12: /* SMULL, SMULL2, UMULL, UMULL2 */
/* 64 x 64 -> 128 */
if (size == 3) {
unallocated_encoding(s);
@@ -6856,39 +7390,22 @@ static void gen_min_u32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2)
tcg_gen_movcond_i32(TCG_COND_LEU, res, op1, op2, op1, op2);
}
-/* Pairwise op subgroup of C3.6.16. */
-static void disas_simd_3same_pair(DisasContext *s, uint32_t insn)
+/* Pairwise op subgroup of C3.6.16.
+ *
+ * This is called directly or via the handle_3same_float for float pairwise
+ * operations where the opcode and size are calculated differently.
+ */
+static void handle_simd_3same_pair(DisasContext *s, int is_q, int u, int opcode,
+ int size, int rn, int rm, int rd)
{
- int is_q = extract32(insn, 30, 1);
- int u = extract32(insn, 29, 1);
- int size = extract32(insn, 22, 2);
- int opcode = extract32(insn, 11, 5);
- int rm = extract32(insn, 16, 5);
- int rn = extract32(insn, 5, 5);
- int rd = extract32(insn, 0, 5);
+ TCGv_ptr fpst;
int pass;
- if (size == 3 && !is_q) {
- unallocated_encoding(s);
- return;
- }
-
- switch (opcode) {
- case 0x14: /* SMAXP, UMAXP */
- case 0x15: /* SMINP, UMINP */
- if (size == 3) {
- unallocated_encoding(s);
- return;
- }
- break;
- case 0x17:
- if (u) {
- unallocated_encoding(s);
- return;
- }
- break;
- default:
- g_assert_not_reached();
+ /* Floating point operations need fpst */
+ if (opcode >= 0x58) {
+ fpst = get_fpstatus_ptr();
+ } else {
+ TCGV_UNUSED_PTR(fpst);
}
/* These operations work on the concatenated rm:rn, with each pair of
@@ -6906,9 +7423,28 @@ static void disas_simd_3same_pair(DisasContext *s, uint32_t insn)
read_vec_element(s, tcg_op2, passreg, 1, MO_64);
tcg_res[pass] = tcg_temp_new_i64();
- /* The only 64 bit pairwise integer op is ADDP */
- assert(opcode == 0x17);
- tcg_gen_add_i64(tcg_res[pass], tcg_op1, tcg_op2);
+ switch (opcode) {
+ case 0x17: /* ADDP */
+ tcg_gen_add_i64(tcg_res[pass], tcg_op1, tcg_op2);
+ break;
+ case 0x58: /* FMAXNMP */
+ gen_helper_vfp_maxnumd(tcg_res[pass], tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x5a: /* FADDP */
+ gen_helper_vfp_addd(tcg_res[pass], tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x5e: /* FMAXP */
+ gen_helper_vfp_maxd(tcg_res[pass], tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x78: /* FMINNMP */
+ gen_helper_vfp_minnumd(tcg_res[pass], tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x7e: /* FMINP */
+ gen_helper_vfp_mind(tcg_res[pass], tcg_op1, tcg_op2, fpst);
+ break;
+ default:
+ g_assert_not_reached();
+ }
tcg_temp_free_i64(tcg_op1);
tcg_temp_free_i64(tcg_op2);
@@ -6925,7 +7461,7 @@ static void disas_simd_3same_pair(DisasContext *s, uint32_t insn)
for (pass = 0; pass < maxpass; pass++) {
TCGv_i32 tcg_op1 = tcg_temp_new_i32();
TCGv_i32 tcg_op2 = tcg_temp_new_i32();
- NeonGenTwoOpFn *genfn;
+ NeonGenTwoOpFn *genfn = NULL;
int passreg = pass < (maxpass / 2) ? rn : rm;
int passelt = (is_q && (pass & 1)) ? 2 : 0;
@@ -6964,11 +7500,30 @@ static void disas_simd_3same_pair(DisasContext *s, uint32_t insn)
genfn = fns[size][u];
break;
}
+ /* The FP operations are all on single floats (32 bit) */
+ case 0x58: /* FMAXNMP */
+ gen_helper_vfp_maxnums(tcg_res[pass], tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x5a: /* FADDP */
+ gen_helper_vfp_adds(tcg_res[pass], tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x5e: /* FMAXP */
+ gen_helper_vfp_maxs(tcg_res[pass], tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x78: /* FMINNMP */
+ gen_helper_vfp_minnums(tcg_res[pass], tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x7e: /* FMINP */
+ gen_helper_vfp_mins(tcg_res[pass], tcg_op1, tcg_op2, fpst);
+ break;
default:
g_assert_not_reached();
}
- genfn(tcg_res[pass], tcg_op1, tcg_op2);
+ /* FP ops called directly, otherwise call now */
+ if (genfn) {
+ genfn(tcg_res[pass], tcg_op1, tcg_op2);
+ }
tcg_temp_free_i32(tcg_op1);
tcg_temp_free_i32(tcg_op2);
@@ -6982,6 +7537,10 @@ static void disas_simd_3same_pair(DisasContext *s, uint32_t insn)
clear_vec_high(s, rd);
}
}
+
+ if (!TCGV_IS_UNUSED_PTR(fpst)) {
+ tcg_temp_free_ptr(fpst);
+ }
}
/* Floating point op subgroup of C3.6.16. */
@@ -7015,30 +7574,32 @@ static void disas_simd_3same_float(DisasContext *s, uint32_t insn)
case 0x5e: /* FMAXP */
case 0x78: /* FMINNMP */
case 0x7e: /* FMINP */
- /* pairwise ops */
- unsupported_encoding(s, insn);
+ if (size && !is_q) {
+ unallocated_encoding(s);
+ return;
+ }
+ handle_simd_3same_pair(s, is_q, 0, fpopcode, size ? MO_64 : MO_32,
+ rn, rm, rd);
return;
case 0x1b: /* FMULX */
- case 0x1c: /* FCMEQ */
case 0x1f: /* FRECPS */
case 0x3f: /* FRSQRTS */
- case 0x5c: /* FCMGE */
case 0x5d: /* FACGE */
- case 0x7c: /* FCMGT */
case 0x7d: /* FACGT */
case 0x19: /* FMLA */
case 0x39: /* FMLS */
- unsupported_encoding(s, insn);
- return;
case 0x18: /* FMAXNM */
case 0x1a: /* FADD */
+ case 0x1c: /* FCMEQ */
case 0x1e: /* FMAX */
case 0x38: /* FMINNM */
case 0x3a: /* FSUB */
case 0x3e: /* FMIN */
case 0x5b: /* FMUL */
+ case 0x5c: /* FCMGE */
case 0x5f: /* FDIV */
case 0x7a: /* FABD */
+ case 0x7c: /* FCMGT */
handle_3same_float(s, size, elements, fpopcode, rd, rn, rm);
return;
default:
@@ -7366,9 +7927,28 @@ static void disas_simd_three_reg_same(DisasContext *s, uint32_t insn)
case 0x17: /* ADDP */
case 0x14: /* SMAXP, UMAXP */
case 0x15: /* SMINP, UMINP */
+ {
/* Pairwise operations */
- disas_simd_3same_pair(s, insn);
+ int is_q = extract32(insn, 30, 1);
+ int u = extract32(insn, 29, 1);
+ int size = extract32(insn, 22, 2);
+ int rm = extract32(insn, 16, 5);
+ int rn = extract32(insn, 5, 5);
+ int rd = extract32(insn, 0, 5);
+ if (opcode == 0x17) {
+ if (u || (size == 3 && !is_q)) {
+ unallocated_encoding(s);
+ return;
+ }
+ } else {
+ if (size == 3) {
+ unallocated_encoding(s);
+ return;
+ }
+ }
+ handle_simd_3same_pair(s, is_q, u, opcode, size, rn, rm, rd);
break;
+ }
case 0x18 ... 0x31:
/* floating point ops, sz[1] and U are part of opcode */
disas_simd_3same_float(s, insn);
@@ -7618,6 +8198,17 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
return;
}
break;
+ case 0x2c: /* FCMGT (zero) */
+ case 0x2d: /* FCMEQ (zero) */
+ case 0x2e: /* FCMLT (zero) */
+ case 0x6c: /* FCMGE (zero) */
+ case 0x6d: /* FCMLE (zero) */
+ if (size == 3 && !is_q) {
+ unallocated_encoding(s);
+ return;
+ }
+ handle_2misc_fcmp_zero(s, opcode, false, u, is_q, size, rn, rd);
+ return;
case 0x16: /* FCVTN, FCVTN2 */
case 0x17: /* FCVTL, FCVTL2 */
case 0x18: /* FRINTN */
@@ -7626,9 +8217,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
case 0x1b: /* FCVTMS */
case 0x1c: /* FCVTAS */
case 0x1d: /* SCVTF */
- case 0x2c: /* FCMGT (zero) */
- case 0x2d: /* FCMEQ (zero) */
- case 0x2e: /* FCMLT (zero) */
case 0x38: /* FRINTP */
case 0x39: /* FRINTZ */
case 0x3a: /* FCVTPS */
@@ -7642,8 +8230,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
case 0x5b: /* FCVTMU */
case 0x5c: /* FCVTAU */
case 0x5d: /* UCVTF */
- case 0x6c: /* FCMGE (zero) */
- case 0x6d: /* FCMLE (zero) */
case 0x79: /* FRINTI */
case 0x7a: /* FCVTPU */
case 0x7b: /* FCVTZU */
@@ -7805,15 +8391,455 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
}
}
-/* C3.6.18 AdvSIMD vector x indexed element
+/* C3.6.13 AdvSIMD scalar x indexed element
+ * 31 30 29 28 24 23 22 21 20 19 16 15 12 11 10 9 5 4 0
+ * +-----+---+-----------+------+---+---+------+-----+---+---+------+------+
+ * | 0 1 | U | 1 1 1 1 1 | size | L | M | Rm | opc | H | 0 | Rn | Rd |
+ * +-----+---+-----------+------+---+---+------+-----+---+---+------+------+
+ * C3.6.18 AdvSIMD vector x indexed element
* 31 30 29 28 24 23 22 21 20 19 16 15 12 11 10 9 5 4 0
* +---+---+---+-----------+------+---+---+------+-----+---+---+------+------+
* | 0 | Q | U | 0 1 1 1 1 | size | L | M | Rm | opc | H | 0 | Rn | Rd |
* +---+---+---+-----------+------+---+---+------+-----+---+---+------+------+
*/
-static void disas_simd_indexed_vector(DisasContext *s, uint32_t insn)
-{
- unsupported_encoding(s, insn);
+static void disas_simd_indexed(DisasContext *s, uint32_t insn)
+{
+ /* This encoding has two kinds of instruction:
+ * normal, where we perform elt x idxelt => elt for each
+ * element in the vector
+ * long, where we perform elt x idxelt and generate a result of
+ * double the width of the input element
+ * The long ops have a 'part' specifier (ie come in INSN, INSN2 pairs).
+ */
+ bool is_scalar = extract32(insn, 28, 1);
+ bool is_q = extract32(insn, 30, 1);
+ bool u = extract32(insn, 29, 1);
+ int size = extract32(insn, 22, 2);
+ int l = extract32(insn, 21, 1);
+ int m = extract32(insn, 20, 1);
+ /* Note that the Rm field here is only 4 bits, not 5 as it usually is */
+ int rm = extract32(insn, 16, 4);
+ int opcode = extract32(insn, 12, 4);
+ int h = extract32(insn, 11, 1);
+ int rn = extract32(insn, 5, 5);
+ int rd = extract32(insn, 0, 5);
+ bool is_long = false;
+ bool is_fp = false;
+ int index;
+ TCGv_ptr fpst;
+
+ switch (opcode) {
+ case 0x0: /* MLA */
+ case 0x4: /* MLS */
+ if (!u || is_scalar) {
+ unallocated_encoding(s);
+ return;
+ }
+ break;
+ case 0x2: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
+ case 0x6: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
+ case 0xa: /* SMULL, SMULL2, UMULL, UMULL2 */
+ if (is_scalar) {
+ unallocated_encoding(s);
+ return;
+ }
+ is_long = true;
+ break;
+ case 0x3: /* SQDMLAL, SQDMLAL2 */
+ case 0x7: /* SQDMLSL, SQDMLSL2 */
+ case 0xb: /* SQDMULL, SQDMULL2 */
+ is_long = true;
+ /* fall through */
+ case 0xc: /* SQDMULH */
+ case 0xd: /* SQRDMULH */
+ if (u) {
+ unallocated_encoding(s);
+ return;
+ }
+ break;
+ case 0x8: /* MUL */
+ if (u || is_scalar) {
+ unallocated_encoding(s);
+ return;
+ }
+ break;
+ case 0x1: /* FMLA */
+ case 0x5: /* FMLS */
+ if (u) {
+ unallocated_encoding(s);
+ return;
+ }
+ /* fall through */
+ case 0x9: /* FMUL, FMULX */
+ if (!extract32(size, 1, 1)) {
+ unallocated_encoding(s);
+ return;
+ }
+ is_fp = true;
+ break;
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+
+ if (is_fp) {
+ /* low bit of size indicates single/double */
+ size = extract32(size, 0, 1) ? 3 : 2;
+ if (size == 2) {
+ index = h << 1 | l;
+ } else {
+ if (l || !is_q) {
+ unallocated_encoding(s);
+ return;
+ }
+ index = h;
+ }
+ rm |= (m << 4);
+ } else {
+ switch (size) {
+ case 1:
+ index = h << 2 | l << 1 | m;
+ break;
+ case 2:
+ index = h << 1 | l;
+ rm |= (m << 4);
+ break;
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+ }
+
+ if (is_fp) {
+ fpst = get_fpstatus_ptr();
+ } else {
+ TCGV_UNUSED_PTR(fpst);
+ }
+
+ if (size == 3) {
+ TCGv_i64 tcg_idx = tcg_temp_new_i64();
+ int pass;
+
+ assert(is_fp && is_q && !is_long);
+
+ read_vec_element(s, tcg_idx, rm, index, MO_64);
+
+ for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
+ TCGv_i64 tcg_op = tcg_temp_new_i64();
+ TCGv_i64 tcg_res = tcg_temp_new_i64();
+
+ read_vec_element(s, tcg_op, rn, pass, MO_64);
+
+ switch (opcode) {
+ case 0x5: /* FMLS */
+ /* As usual for ARM, separate negation for fused multiply-add */
+ gen_helper_vfp_negd(tcg_op, tcg_op);
+ /* fall through */
+ case 0x1: /* FMLA */
+ read_vec_element(s, tcg_res, rd, pass, MO_64);
+ gen_helper_vfp_muladdd(tcg_res, tcg_op, tcg_idx, tcg_res, fpst);
+ break;
+ case 0x9: /* FMUL, FMULX */
+ if (u) {
+ gen_helper_vfp_mulxd(tcg_res, tcg_op, tcg_idx, fpst);
+ } else {
+ gen_helper_vfp_muld(tcg_res, tcg_op, tcg_idx, fpst);
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ write_vec_element(s, tcg_res, rd, pass, MO_64);
+ tcg_temp_free_i64(tcg_op);
+ tcg_temp_free_i64(tcg_res);
+ }
+
+ if (is_scalar) {
+ clear_vec_high(s, rd);
+ }
+
+ tcg_temp_free_i64(tcg_idx);
+ } else if (!is_long) {
+ /* 32 bit floating point, or 16 or 32 bit integer.
+ * For the 16 bit scalar case we use the usual Neon helpers and
+ * rely on the fact that 0 op 0 == 0 with no side effects.
+ */
+ TCGv_i32 tcg_idx = tcg_temp_new_i32();
+ int pass, maxpasses;
+
+ if (is_scalar) {
+ maxpasses = 1;
+ } else {
+ maxpasses = is_q ? 4 : 2;
+ }
+
+ read_vec_element_i32(s, tcg_idx, rm, index, size);
+
+ if (size == 1 && !is_scalar) {
+ /* The simplest way to handle the 16x16 indexed ops is to duplicate
+ * the index into both halves of the 32 bit tcg_idx and then use
+ * the usual Neon helpers.
+ */
+ tcg_gen_deposit_i32(tcg_idx, tcg_idx, tcg_idx, 16, 16);
+ }
+
+ for (pass = 0; pass < maxpasses; pass++) {
+ TCGv_i32 tcg_op = tcg_temp_new_i32();
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
+
+ read_vec_element_i32(s, tcg_op, rn, pass, is_scalar ? size : MO_32);
+
+ switch (opcode) {
+ case 0x0: /* MLA */
+ case 0x4: /* MLS */
+ case 0x8: /* MUL */
+ {
+ static NeonGenTwoOpFn * const fns[2][2] = {
+ { gen_helper_neon_add_u16, gen_helper_neon_sub_u16 },
+ { tcg_gen_add_i32, tcg_gen_sub_i32 },
+ };
+ NeonGenTwoOpFn *genfn;
+ bool is_sub = opcode == 0x4;
+
+ if (size == 1) {
+ gen_helper_neon_mul_u16(tcg_res, tcg_op, tcg_idx);
+ } else {
+ tcg_gen_mul_i32(tcg_res, tcg_op, tcg_idx);
+ }
+ if (opcode == 0x8) {
+ break;
+ }
+ read_vec_element_i32(s, tcg_op, rd, pass, MO_32);
+ genfn = fns[size - 1][is_sub];
+ genfn(tcg_res, tcg_op, tcg_res);
+ break;
+ }
+ case 0x5: /* FMLS */
+ /* As usual for ARM, separate negation for fused multiply-add */
+ gen_helper_vfp_negs(tcg_op, tcg_op);
+ /* fall through */
+ case 0x1: /* FMLA */
+ read_vec_element_i32(s, tcg_res, rd, pass, MO_32);
+ gen_helper_vfp_muladds(tcg_res, tcg_op, tcg_idx, tcg_res, fpst);
+ break;
+ case 0x9: /* FMUL, FMULX */
+ if (u) {
+ gen_helper_vfp_mulxs(tcg_res, tcg_op, tcg_idx, fpst);
+ } else {
+ gen_helper_vfp_muls(tcg_res, tcg_op, tcg_idx, fpst);
+ }
+ break;
+ case 0xc: /* SQDMULH */
+ if (size == 1) {
+ gen_helper_neon_qdmulh_s16(tcg_res, cpu_env,
+ tcg_op, tcg_idx);
+ } else {
+ gen_helper_neon_qdmulh_s32(tcg_res, cpu_env,
+ tcg_op, tcg_idx);
+ }
+ break;
+ case 0xd: /* SQRDMULH */
+ if (size == 1) {
+ gen_helper_neon_qrdmulh_s16(tcg_res, cpu_env,
+ tcg_op, tcg_idx);
+ } else {
+ gen_helper_neon_qrdmulh_s32(tcg_res, cpu_env,
+ tcg_op, tcg_idx);
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ if (is_scalar) {
+ write_fp_sreg(s, rd, tcg_res);
+ } else {
+ write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
+ }
+
+ tcg_temp_free_i32(tcg_op);
+ tcg_temp_free_i32(tcg_res);
+ }
+
+ tcg_temp_free_i32(tcg_idx);
+
+ if (!is_q) {
+ clear_vec_high(s, rd);
+ }
+ } else {
+ /* long ops: 16x16->32 or 32x32->64 */
+ TCGv_i64 tcg_res[2];
+ int pass;
+ bool satop = extract32(opcode, 0, 1);
+ TCGMemOp memop = MO_32;
+
+ if (satop || !u) {
+ memop |= MO_SIGN;
+ }
+
+ if (size == 2) {
+ TCGv_i64 tcg_idx = tcg_temp_new_i64();
+
+ read_vec_element(s, tcg_idx, rm, index, memop);
+
+ for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
+ TCGv_i64 tcg_op = tcg_temp_new_i64();
+ TCGv_i64 tcg_passres;
+ int passelt;
+
+ if (is_scalar) {
+ passelt = 0;
+ } else {
+ passelt = pass + (is_q * 2);
+ }
+
+ read_vec_element(s, tcg_op, rn, passelt, memop);
+
+ tcg_res[pass] = tcg_temp_new_i64();
+
+ if (opcode == 0xa || opcode == 0xb) {
+ /* Non-accumulating ops */
+ tcg_passres = tcg_res[pass];
+ } else {
+ tcg_passres = tcg_temp_new_i64();
+ }
+
+ tcg_gen_mul_i64(tcg_passres, tcg_op, tcg_idx);
+ tcg_temp_free_i64(tcg_op);
+
+ if (satop) {
+ /* saturating, doubling */
+ gen_helper_neon_addl_saturate_s64(tcg_passres, cpu_env,
+ tcg_passres, tcg_passres);
+ }
+
+ if (opcode == 0xa || opcode == 0xb) {
+ continue;
+ }
+
+ /* Accumulating op: handle accumulate step */
+ read_vec_element(s, tcg_res[pass], rd, pass, MO_64);
+
+ switch (opcode) {
+ case 0x2: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
+ tcg_gen_add_i64(tcg_res[pass], tcg_res[pass], tcg_passres);
+ break;
+ case 0x6: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
+ tcg_gen_sub_i64(tcg_res[pass], tcg_res[pass], tcg_passres);
+ break;
+ case 0x7: /* SQDMLSL, SQDMLSL2 */
+ tcg_gen_neg_i64(tcg_passres, tcg_passres);
+ /* fall through */
+ case 0x3: /* SQDMLAL, SQDMLAL2 */
+ gen_helper_neon_addl_saturate_s64(tcg_res[pass], cpu_env,
+ tcg_res[pass],
+ tcg_passres);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ tcg_temp_free_i64(tcg_passres);
+ }
+ tcg_temp_free_i64(tcg_idx);
+
+ if (is_scalar) {
+ clear_vec_high(s, rd);
+ }
+ } else {
+ TCGv_i32 tcg_idx = tcg_temp_new_i32();
+
+ assert(size == 1);
+ read_vec_element_i32(s, tcg_idx, rm, index, size);
+
+ if (!is_scalar) {
+ /* The simplest way to handle the 16x16 indexed ops is to
+ * duplicate the index into both halves of the 32 bit tcg_idx
+ * and then use the usual Neon helpers.
+ */
+ tcg_gen_deposit_i32(tcg_idx, tcg_idx, tcg_idx, 16, 16);
+ }
+
+ for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
+ TCGv_i32 tcg_op = tcg_temp_new_i32();
+ TCGv_i64 tcg_passres;
+
+ if (is_scalar) {
+ read_vec_element_i32(s, tcg_op, rn, pass, size);
+ } else {
+ read_vec_element_i32(s, tcg_op, rn,
+ pass + (is_q * 2), MO_32);
+ }
+
+ tcg_res[pass] = tcg_temp_new_i64();
+
+ if (opcode == 0xa || opcode == 0xb) {
+ /* Non-accumulating ops */
+ tcg_passres = tcg_res[pass];
+ } else {
+ tcg_passres = tcg_temp_new_i64();
+ }
+
+ if (memop & MO_SIGN) {
+ gen_helper_neon_mull_s16(tcg_passres, tcg_op, tcg_idx);
+ } else {
+ gen_helper_neon_mull_u16(tcg_passres, tcg_op, tcg_idx);
+ }
+ if (satop) {
+ gen_helper_neon_addl_saturate_s32(tcg_passres, cpu_env,
+ tcg_passres, tcg_passres);
+ }
+ tcg_temp_free_i32(tcg_op);
+
+ if (opcode == 0xa || opcode == 0xb) {
+ continue;
+ }
+
+ /* Accumulating op: handle accumulate step */
+ read_vec_element(s, tcg_res[pass], rd, pass, MO_64);
+
+ switch (opcode) {
+ case 0x2: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
+ gen_helper_neon_addl_u32(tcg_res[pass], tcg_res[pass],
+ tcg_passres);
+ break;
+ case 0x6: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
+ gen_helper_neon_subl_u32(tcg_res[pass], tcg_res[pass],
+ tcg_passres);
+ break;
+ case 0x7: /* SQDMLSL, SQDMLSL2 */
+ gen_helper_neon_negl_u32(tcg_passres, tcg_passres);
+ /* fall through */
+ case 0x3: /* SQDMLAL, SQDMLAL2 */
+ gen_helper_neon_addl_saturate_s32(tcg_res[pass], cpu_env,
+ tcg_res[pass],
+ tcg_passres);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ tcg_temp_free_i64(tcg_passres);
+ }
+ tcg_temp_free_i32(tcg_idx);
+
+ if (is_scalar) {
+ tcg_gen_ext32u_i64(tcg_res[0], tcg_res[0]);
+ }
+ }
+
+ if (is_scalar) {
+ tcg_res[1] = tcg_const_i64(0);
+ }
+
+ for (pass = 0; pass < 2; pass++) {
+ write_vec_element(s, tcg_res[pass], rd, pass, MO_64);
+ tcg_temp_free_i64(tcg_res[pass]);
+ }
+ }
+
+ if (!TCGV_IS_UNUSED_PTR(fpst)) {
+ tcg_temp_free_ptr(fpst);
+ }
}
/* C3.6.19 Crypto AES
@@ -7861,7 +8887,7 @@ static const AArch64DecodeTable data_proc_simd[] = {
{ 0x0e200800, 0x9f3e0c00, disas_simd_two_reg_misc },
{ 0x0e300800, 0x9f3e0c00, disas_simd_across_lanes },
{ 0x0e000400, 0x9fe08400, disas_simd_copy },
- { 0x0f000000, 0x9f000400, disas_simd_indexed_vector },
+ { 0x0f000000, 0x9f000400, disas_simd_indexed }, /* vector indexed */
/* simd_mod_imm decode is a subset of simd_shift_imm, so must precede it */
{ 0x0f000400, 0x9ff80400, disas_simd_mod_imm },
{ 0x0f000400, 0x9f800400, disas_simd_shift_imm },
@@ -7873,7 +8899,7 @@ static const AArch64DecodeTable data_proc_simd[] = {
{ 0x5e200800, 0xdf3e0c00, disas_simd_scalar_two_reg_misc },
{ 0x5e300800, 0xdf3e0c00, disas_simd_scalar_pairwise },
{ 0x5e000400, 0xdfe08400, disas_simd_scalar_copy },
- { 0x5f000000, 0xdf000400, disas_simd_scalar_indexed },
+ { 0x5f000000, 0xdf000400, disas_simd_indexed }, /* scalar indexed */
{ 0x5f000400, 0xdf800400, disas_simd_scalar_shift_imm },
{ 0x4e280800, 0xff3e0c00, disas_crypto_aes },
{ 0x5e000000, 0xff208c00, disas_crypto_three_reg_sha },
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 782aab8..6ccf0ba 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6837,6 +6837,17 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
return 1;
}
+ if (ri->accessfn) {
+ /* Emit code to perform further access permissions checks at
+ * runtime; this may result in an exception.
+ */
+ TCGv_ptr tmpptr;
+ gen_set_pc_im(s, s->pc);
+ tmpptr = tcg_const_ptr(ri);
+ gen_helper_access_check_cp_reg(cpu_env, tmpptr);
+ tcg_temp_free_ptr(tmpptr);
+ }
+
/* Handle special cases first */
switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
case ARM_CP_NOP:
@@ -6865,7 +6876,6 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
tmp64 = tcg_const_i64(ri->resetvalue);
} else if (ri->readfn) {
TCGv_ptr tmpptr;
- gen_set_pc_im(s, s->pc);
tmp64 = tcg_temp_new_i64();
tmpptr = tcg_const_ptr(ri);
gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
@@ -6888,7 +6898,6 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
tmp = tcg_const_i32(ri->resetvalue);
} else if (ri->readfn) {
TCGv_ptr tmpptr;
- gen_set_pc_im(s, s->pc);
tmp = tcg_temp_new_i32();
tmpptr = tcg_const_ptr(ri);
gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
@@ -6923,7 +6932,6 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
tcg_temp_free_i32(tmphi);
if (ri->writefn) {
TCGv_ptr tmpptr = tcg_const_ptr(ri);
- gen_set_pc_im(s, s->pc);
gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
tcg_temp_free_ptr(tmpptr);
} else {
@@ -6934,7 +6942,6 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
if (ri->writefn) {
TCGv_i32 tmp;
TCGv_ptr tmpptr;
- gen_set_pc_im(s, s->pc);
tmp = load_reg(s, rt);
tmpptr = tcg_const_ptr(ri);
gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
@@ -6962,6 +6969,19 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
return 0;
}
+ /* Unknown register; this might be a guest error or a QEMU
+ * unimplemented feature.
+ */
+ if (is64) {
+ qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
+ "64 bit system register cp:%d opc1: %d crm:%d\n",
+ isread ? "read" : "write", cpnum, opc1, crm);
+ } else {
+ qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
+ "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
+ isread ? "read" : "write", cpnum, opc1, crn, crm, opc2);
+ }
+
return 1;
}
diff --git a/target-i386/translate.c b/target-i386/translate.c
index b0f2279..5dd2450 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -6284,6 +6284,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
case 0xe5:
ot = mo_b_d32(b, dflag);
val = cpu_ldub_code(env, s->pc++);
+ tcg_gen_movi_tl(cpu_T[0], val);
gen_check_io(s, ot, pc_start - s->cs_base,
SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
if (use_icount)
@@ -6300,6 +6301,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
case 0xe7:
ot = mo_b_d32(b, dflag);
val = cpu_ldub_code(env, s->pc++);
+ tcg_gen_movi_tl(cpu_T[0], val);
gen_check_io(s, ot, pc_start - s->cs_base,
svm_is_rep(prefixes));
gen_op_mov_v_reg(ot, cpu_T[1], R_EAX);
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index c030a20..445c360 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7960,6 +7960,17 @@ static int ppc_fixup_cpu(PowerPCCPU *cpu)
return 0;
}
+static inline bool ppc_cpu_is_valid(PowerPCCPUClass *pcc)
+{
+#ifdef TARGET_PPCEMB
+ return pcc->mmu_model == POWERPC_MMU_BOOKE ||
+ pcc->mmu_model == POWERPC_MMU_SOFT_4xx ||
+ pcc->mmu_model == POWERPC_MMU_SOFT_4xx_Z;
+#else
+ return true;
+#endif
+}
+
static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
@@ -7991,8 +8002,8 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
}
#if defined(TARGET_PPCEMB)
- if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
- error_setg(errp, "CPU does not possess a BookE MMU. "
+ if (!ppc_cpu_is_valid(pcc)) {
+ error_setg(errp, "CPU does not possess a BookE or 4xx MMU. "
"Please use qemu-system-ppc or qemu-system-ppc64 instead "
"or choose another CPU model.");
return;
@@ -8209,11 +8220,9 @@ static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
return -1;
}
-#if defined(TARGET_PPCEMB)
- if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
+ if (!ppc_cpu_is_valid(pcc)) {
return -1;
}
-#endif
return pcc->pvr == pvr ? 0 : -1;
}
@@ -8246,11 +8255,10 @@ static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b)
return -1;
}
-#if defined(TARGET_PPCEMB)
- if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
+ if (!ppc_cpu_is_valid(pcc)) {
return -1;
}
-#endif
+
ret = (((pcc->pvr & pcc->pvr_mask) == (pvr & pcc->pvr_mask)) ? 0 : -1);
return ret;
@@ -8275,14 +8283,10 @@ static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b)
{
ObjectClass *oc = (ObjectClass *)a;
const char *name = b;
-#if defined(TARGET_PPCEMB)
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-#endif
if (strncasecmp(name, object_class_get_name(oc), strlen(name)) == 0 &&
-#if defined(TARGET_PPCEMB)
- pcc->mmu_model == POWERPC_MMU_BOOKE &&
-#endif
+ ppc_cpu_is_valid(pcc) &&
strcmp(object_class_get_name(oc) + strlen(name),
"-" TYPE_POWERPC_CPU) == 0) {
return 0;
@@ -8414,11 +8418,9 @@ static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
char *name;
int i;
-#if defined(TARGET_PPCEMB)
- if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
+ if (!ppc_cpu_is_valid(pcc)) {
return;
}
-#endif
if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
return;
}
@@ -8466,13 +8468,11 @@ static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
const char *typename;
CpuDefinitionInfoList *entry;
CpuDefinitionInfo *info;
-#if defined(TARGET_PPCEMB)
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
- if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
+ if (!ppc_cpu_is_valid(pcc)) {
return;
}
-#endif
typename = object_class_get_name(oc);
info = g_malloc0(sizeof(*info));
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 82658a1..c8884b3 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -1866,7 +1866,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
SHIFT_IMM_ROR((0x20 - args[2]) & 0x1f) :
SHIFT_IMM_LSL(0));
} else {
- tcg_out_dat_imm(s, COND_AL, ARITH_RSB, TCG_REG_TMP, args[1], 0x20);
+ tcg_out_dat_imm(s, COND_AL, ARITH_RSB, TCG_REG_TMP, args[2], 0x20);
tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
SHIFT_REG_ROR(TCG_REG_TMP));
}
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 5d4cf93..f832282 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -88,6 +88,11 @@ static const int tcg_target_call_oarg_regs[] = {
#endif
};
+/* Constants we accept. */
+#define TCG_CT_CONST_S32 0x100
+#define TCG_CT_CONST_U32 0x200
+#define TCG_CT_CONST_I32 0x400
+
/* Registers used with L constraint, which are the first argument
registers on x86_64, and two random call clobbered registers on
i386. */
@@ -110,7 +115,7 @@ static const int tcg_target_call_oarg_regs[] = {
is available. */
#if TCG_TARGET_REG_BITS == 64
# define have_cmov 1
-#elif defined(CONFIG_CPUID_H)
+#elif defined(CONFIG_CPUID_H) && defined(bit_CMOV)
static bool have_cmov;
#else
# define have_cmov 0
@@ -124,6 +129,16 @@ static bool have_movbe;
# define have_movbe 0
#endif
+/* We need this symbol in tcg-target.h, and we can't properly conditionalize
+ it there. Therefore we always define the variable. */
+bool have_bmi1;
+
+#if defined(CONFIG_CPUID_H) && defined(bit_BMI2)
+static bool have_bmi2;
+#else
+# define have_bmi2 0
+#endif
+
static uint8_t *tb_ret_addr;
static void patch_reloc(uint8_t *code_ptr, int type,
@@ -166,6 +181,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
tcg_regset_set_reg(ct->u.regs, TCG_REG_EBX);
break;
case 'c':
+ case_c:
ct->ct |= TCG_CT_REG;
tcg_regset_set_reg(ct->u.regs, TCG_REG_ECX);
break;
@@ -194,6 +210,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
tcg_regset_set32(ct->u.regs, 0, 0xf);
break;
case 'r':
+ case_r:
ct->ct |= TCG_CT_REG;
if (TCG_TARGET_REG_BITS == 64) {
tcg_regset_set32(ct->u.regs, 0, 0xffff);
@@ -201,6 +218,13 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
tcg_regset_set32(ct->u.regs, 0, 0xff);
}
break;
+ case 'C':
+ /* With SHRX et al, we need not use ECX as shift count register. */
+ if (have_bmi2) {
+ goto case_r;
+ } else {
+ goto case_c;
+ }
/* qemu_ld/st address constraint */
case 'L':
@@ -220,6 +244,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
case 'Z':
ct->ct |= TCG_CT_CONST_U32;
break;
+ case 'I':
+ ct->ct |= TCG_CT_CONST_I32;
+ break;
default:
return -1;
@@ -243,6 +270,9 @@ static inline int tcg_target_const_match(tcg_target_long val,
if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
return 1;
}
+ if ((ct & TCG_CT_CONST_I32) && ~val == (int32_t)~val) {
+ return 1;
+ }
return 0;
}
@@ -268,10 +298,13 @@ static inline int tcg_target_const_match(tcg_target_long val,
# define P_REXB_RM 0
# define P_GS 0
#endif
+#define P_SIMDF3 0x10000 /* 0xf3 opcode prefix */
+#define P_SIMDF2 0x20000 /* 0xf2 opcode prefix */
#define OPC_ARITH_EvIz (0x81)
#define OPC_ARITH_EvIb (0x83)
#define OPC_ARITH_GvEv (0x03) /* ... plus (ARITH_FOO << 3) */
+#define OPC_ANDN (0xf2 | P_EXT38)
#define OPC_ADD_GvEv (OPC_ARITH_GvEv | (ARITH_ADD << 3))
#define OPC_BSWAP (0xc8 | P_EXT)
#define OPC_CALL_Jz (0xe8)
@@ -309,6 +342,9 @@ static inline int tcg_target_const_match(tcg_target_long val,
#define OPC_SHIFT_1 (0xd1)
#define OPC_SHIFT_Ib (0xc1)
#define OPC_SHIFT_cl (0xd3)
+#define OPC_SARX (0xf7 | P_EXT38 | P_SIMDF3)
+#define OPC_SHLX (0xf7 | P_EXT38 | P_DATA16)
+#define OPC_SHRX (0xf7 | P_EXT38 | P_SIMDF2)
#define OPC_TESTL (0x85)
#define OPC_XCHG_ax_r32 (0x90)
@@ -398,9 +434,9 @@ static void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x)
rex = 0;
rex |= (opc & P_REXW) ? 0x8 : 0x0; /* REX.W */
- rex |= (r & 8) >> 1; /* REX.R */
- rex |= (x & 8) >> 2; /* REX.X */
- rex |= (rm & 8) >> 3; /* REX.B */
+ rex |= (r & 8) >> 1; /* REX.R */
+ rex |= (x & 8) >> 2; /* REX.X */
+ rex |= (rm & 8) >> 3; /* REX.B */
/* P_REXB_{R,RM} indicates that the given register is the low byte.
For %[abcd]l we need no REX prefix, but for %{si,di,bp,sp}l we do,
@@ -449,6 +485,48 @@ static void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
tcg_out8(s, 0xc0 | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
}
+static void tcg_out_vex_modrm(TCGContext *s, int opc, int r, int v, int rm)
+{
+ int tmp;
+
+ if ((opc & (P_REXW | P_EXT | P_EXT38)) || (rm & 8)) {
+ /* Three byte VEX prefix. */
+ tcg_out8(s, 0xc4);
+
+ /* VEX.m-mmmm */
+ if (opc & P_EXT38) {
+ tmp = 2;
+ } else if (opc & P_EXT) {
+ tmp = 1;
+ } else {
+ tcg_abort();
+ }
+ tmp |= 0x40; /* VEX.X */
+ tmp |= (r & 8 ? 0 : 0x80); /* VEX.R */
+ tmp |= (rm & 8 ? 0 : 0x20); /* VEX.B */
+ tcg_out8(s, tmp);
+
+ tmp = (opc & P_REXW ? 0x80 : 0); /* VEX.W */
+ } else {
+ /* Two byte VEX prefix. */
+ tcg_out8(s, 0xc5);
+
+ tmp = (r & 8 ? 0 : 0x80); /* VEX.R */
+ }
+ /* VEX.pp */
+ if (opc & P_DATA16) {
+ tmp |= 1; /* 0x66 */
+ } else if (opc & P_SIMDF3) {
+ tmp |= 2; /* 0xf3 */
+ } else if (opc & P_SIMDF2) {
+ tmp |= 3; /* 0xf2 */
+ }
+ tmp |= (~v & 15) << 3; /* VEX.vvvv */
+ tcg_out8(s, tmp);
+ tcg_out8(s, opc);
+ tcg_out8(s, 0xc0 | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
+}
+
/* Output an opcode with a full "rm + (index<<shift) + offset" address mode.
We handle either RM and INDEX missing with a negative value. In 64-bit
mode for absolute addresses, ~RM is the size of the immediate operand
@@ -1638,7 +1716,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64)
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg *args, const int *const_args)
{
- int c, rexw = 0;
+ int c, vexop, rexw = 0;
#if TCG_TARGET_REG_BITS == 64
# define OP_32_64(x) \
@@ -1774,6 +1852,16 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
}
break;
+ OP_32_64(andc):
+ if (const_args[2]) {
+ tcg_out_mov(s, rexw ? TCG_TYPE_I64 : TCG_TYPE_I32,
+ args[0], args[1]);
+ tgen_arithi(s, ARITH_AND + rexw, args[0], ~args[2], 0);
+ } else {
+ tcg_out_vex_modrm(s, OPC_ANDN + rexw, args[0], args[2], args[1]);
+ }
+ break;
+
OP_32_64(mul):
if (const_args[2]) {
int32_t val;
@@ -1799,19 +1887,28 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
OP_32_64(shl):
c = SHIFT_SHL;
- goto gen_shift;
+ vexop = OPC_SHLX;
+ goto gen_shift_maybe_vex;
OP_32_64(shr):
c = SHIFT_SHR;
- goto gen_shift;
+ vexop = OPC_SHRX;
+ goto gen_shift_maybe_vex;
OP_32_64(sar):
c = SHIFT_SAR;
- goto gen_shift;
+ vexop = OPC_SARX;
+ goto gen_shift_maybe_vex;
OP_32_64(rotl):
c = SHIFT_ROL;
goto gen_shift;
OP_32_64(rotr):
c = SHIFT_ROR;
goto gen_shift;
+ gen_shift_maybe_vex:
+ if (have_bmi2 && !const_args[2]) {
+ tcg_out_vex_modrm(s, vexop + rexw, args[0], args[2], args[1]);
+ break;
+ }
+ /* FALLTHRU */
gen_shift:
if (const_args[2]) {
tcg_out_shifti(s, c + rexw, args[0], args[2]);
@@ -2002,10 +2099,11 @@ static const TCGTargetOpDef x86_op_defs[] = {
{ INDEX_op_and_i32, { "r", "0", "ri" } },
{ INDEX_op_or_i32, { "r", "0", "ri" } },
{ INDEX_op_xor_i32, { "r", "0", "ri" } },
+ { INDEX_op_andc_i32, { "r", "r", "ri" } },
- { INDEX_op_shl_i32, { "r", "0", "ci" } },
- { INDEX_op_shr_i32, { "r", "0", "ci" } },
- { INDEX_op_sar_i32, { "r", "0", "ci" } },
+ { INDEX_op_shl_i32, { "r", "0", "Ci" } },
+ { INDEX_op_shr_i32, { "r", "0", "Ci" } },
+ { INDEX_op_sar_i32, { "r", "0", "Ci" } },
{ INDEX_op_rotl_i32, { "r", "0", "ci" } },
{ INDEX_op_rotr_i32, { "r", "0", "ci" } },
@@ -2059,10 +2157,11 @@ static const TCGTargetOpDef x86_op_defs[] = {
{ INDEX_op_and_i64, { "r", "0", "reZ" } },
{ INDEX_op_or_i64, { "r", "0", "re" } },
{ INDEX_op_xor_i64, { "r", "0", "re" } },
+ { INDEX_op_andc_i64, { "r", "r", "rI" } },
- { INDEX_op_shl_i64, { "r", "0", "ci" } },
- { INDEX_op_shr_i64, { "r", "0", "ci" } },
- { INDEX_op_sar_i64, { "r", "0", "ci" } },
+ { INDEX_op_shl_i64, { "r", "0", "Ci" } },
+ { INDEX_op_shr_i64, { "r", "0", "Ci" } },
+ { INDEX_op_sar_i64, { "r", "0", "Ci" } },
{ INDEX_op_rotl_i64, { "r", "0", "ci" } },
{ INDEX_op_rotr_i64, { "r", "0", "ci" } },
@@ -2196,23 +2295,34 @@ static void tcg_target_qemu_prologue(TCGContext *s)
static void tcg_target_init(TCGContext *s)
{
-#if !(defined(have_cmov) && defined(have_movbe))
- {
- unsigned a, b, c, d;
- int ret = __get_cpuid(1, &a, &b, &c, &d);
+#ifdef CONFIG_CPUID_H
+ unsigned a, b, c, d;
+ int max = __get_cpuid_max(0, 0);
-# ifndef have_cmov
+ if (max >= 1) {
+ __cpuid(1, a, b, c, d);
+#ifndef have_cmov
/* For 32-bit, 99% certainty that we're running on hardware that
supports cmov, but we still need to check. In case cmov is not
available, we'll use a small forward branch. */
- have_cmov = ret && (d & bit_CMOV);
-# endif
-
-# ifndef have_movbe
+ have_cmov = (d & bit_CMOV) != 0;
+#endif
+#ifndef have_movbe
/* MOVBE is only available on Intel Atom and Haswell CPUs, so we
need to probe for it. */
- have_movbe = ret && (c & bit_MOVBE);
-# endif
+ have_movbe = (c & bit_MOVBE) != 0;
+#endif
+ }
+
+ if (max >= 7) {
+ /* BMI1 is available on AMD Piledriver and Intel Haswell CPUs. */
+ __cpuid_count(7, 0, a, b, c, d);
+#ifdef bit_BMI
+ have_bmi1 = (b & bit_BMI) != 0;
+#endif
+#ifndef have_bmi2
+ have_bmi2 = (b & bit_BMI2) != 0;
+#endif
}
#endif
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 92c0fcd..bdf2222 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -64,9 +64,6 @@ typedef enum {
TCG_REG_RDI = TCG_REG_EDI,
} TCGReg;
-#define TCG_CT_CONST_S32 0x100
-#define TCG_CT_CONST_U32 0x200
-
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_ESP
#define TCG_TARGET_STACK_ALIGN 16
@@ -76,6 +73,8 @@ typedef enum {
#define TCG_TARGET_CALL_STACK_OFFSET 0
#endif
+extern bool have_bmi1;
+
/* optional instructions */
#define TCG_TARGET_HAS_div2_i32 1
#define TCG_TARGET_HAS_rot_i32 1
@@ -87,7 +86,7 @@ typedef enum {
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_neg_i32 1
#define TCG_TARGET_HAS_not_i32 1
-#define TCG_TARGET_HAS_andc_i32 0
+#define TCG_TARGET_HAS_andc_i32 have_bmi1
#define TCG_TARGET_HAS_orc_i32 0
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_i32 0
@@ -115,7 +114,7 @@ typedef enum {
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_neg_i64 1
#define TCG_TARGET_HAS_not_i64 1
-#define TCG_TARGET_HAS_andc_i64 0
+#define TCG_TARGET_HAS_andc_i64 have_bmi1
#define TCG_TARGET_HAS_orc_i64 0
#define TCG_TARGET_HAS_eqv_i64 0
#define TCG_TARGET_HAS_nand_i64 0
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 89e2d6a..7777743 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -655,11 +655,68 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
}
}
break;
+ CASE_OP_32_64(xor):
+ CASE_OP_32_64(nand):
+ if (temps[args[1]].state != TCG_TEMP_CONST
+ && temps[args[2]].state == TCG_TEMP_CONST
+ && temps[args[2]].val == -1) {
+ i = 1;
+ goto try_not;
+ }
+ break;
+ CASE_OP_32_64(nor):
+ if (temps[args[1]].state != TCG_TEMP_CONST
+ && temps[args[2]].state == TCG_TEMP_CONST
+ && temps[args[2]].val == 0) {
+ i = 1;
+ goto try_not;
+ }
+ break;
+ CASE_OP_32_64(andc):
+ if (temps[args[2]].state != TCG_TEMP_CONST
+ && temps[args[1]].state == TCG_TEMP_CONST
+ && temps[args[1]].val == -1) {
+ i = 2;
+ goto try_not;
+ }
+ break;
+ CASE_OP_32_64(orc):
+ CASE_OP_32_64(eqv):
+ if (temps[args[2]].state != TCG_TEMP_CONST
+ && temps[args[1]].state == TCG_TEMP_CONST
+ && temps[args[1]].val == 0) {
+ i = 2;
+ goto try_not;
+ }
+ break;
+ try_not:
+ {
+ TCGOpcode not_op;
+ bool have_not;
+
+ if (def->flags & TCG_OPF_64BIT) {
+ not_op = INDEX_op_not_i64;
+ have_not = TCG_TARGET_HAS_not_i64;
+ } else {
+ not_op = INDEX_op_not_i32;
+ have_not = TCG_TARGET_HAS_not_i32;
+ }
+ if (!have_not) {
+ break;
+ }
+ s->gen_opc_buf[op_index] = not_op;
+ reset_temp(args[0]);
+ gen_args[0] = args[0];
+ gen_args[1] = args[i];
+ args += 3;
+ gen_args += 2;
+ continue;
+ }
default:
break;
}
- /* Simplify expression for "op r, a, 0 => mov r, a" cases */
+ /* Simplify expression for "op r, a, const => mov r, a" cases */
switch (op) {
CASE_OP_32_64(add):
CASE_OP_32_64(sub):
@@ -670,28 +727,38 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
CASE_OP_32_64(rotr):
CASE_OP_32_64(or):
CASE_OP_32_64(xor):
- if (temps[args[1]].state == TCG_TEMP_CONST) {
- /* Proceed with possible constant folding. */
- break;
- }
- if (temps[args[2]].state == TCG_TEMP_CONST
+ CASE_OP_32_64(andc):
+ if (temps[args[1]].state != TCG_TEMP_CONST
+ && temps[args[2]].state == TCG_TEMP_CONST
&& temps[args[2]].val == 0) {
- if (temps_are_copies(args[0], args[1])) {
- s->gen_opc_buf[op_index] = INDEX_op_nop;
- } else {
- s->gen_opc_buf[op_index] = op_to_mov(op);
- tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
- gen_args += 2;
- }
- args += 3;
- continue;
+ goto do_mov3;
+ }
+ break;
+ CASE_OP_32_64(and):
+ CASE_OP_32_64(orc):
+ CASE_OP_32_64(eqv):
+ if (temps[args[1]].state != TCG_TEMP_CONST
+ && temps[args[2]].state == TCG_TEMP_CONST
+ && temps[args[2]].val == -1) {
+ goto do_mov3;
}
break;
+ do_mov3:
+ if (temps_are_copies(args[0], args[1])) {
+ s->gen_opc_buf[op_index] = INDEX_op_nop;
+ } else {
+ s->gen_opc_buf[op_index] = op_to_mov(op);
+ tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
+ gen_args += 2;
+ }
+ args += 3;
+ continue;
default:
break;
}
- /* Simplify using known-zero bits */
+ /* Simplify using known-zero bits. Currently only ops with a single
+ output argument is supported. */
mask = -1;
affected = -1;
switch (op) {
@@ -726,16 +793,36 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
mask = temps[args[1]].mask & mask;
break;
- CASE_OP_32_64(sar):
+ CASE_OP_32_64(andc):
+ /* Known-zeros does not imply known-ones. Therefore unless
+ args[2] is constant, we can't infer anything from it. */
if (temps[args[2]].state == TCG_TEMP_CONST) {
- mask = ((tcg_target_long)temps[args[1]].mask
- >> temps[args[2]].val);
+ mask = ~temps[args[2]].mask;
+ goto and_const;
}
+ /* But we certainly know nothing outside args[1] may be set. */
+ mask = temps[args[1]].mask;
break;
- CASE_OP_32_64(shr):
+ case INDEX_op_sar_i32:
if (temps[args[2]].state == TCG_TEMP_CONST) {
- mask = temps[args[1]].mask >> temps[args[2]].val;
+ mask = (int32_t)temps[args[1]].mask >> temps[args[2]].val;
+ }
+ break;
+ case INDEX_op_sar_i64:
+ if (temps[args[2]].state == TCG_TEMP_CONST) {
+ mask = (int64_t)temps[args[1]].mask >> temps[args[2]].val;
+ }
+ break;
+
+ case INDEX_op_shr_i32:
+ if (temps[args[2]].state == TCG_TEMP_CONST) {
+ mask = (uint32_t)temps[args[1]].mask >> temps[args[2]].val;
+ }
+ break;
+ case INDEX_op_shr_i64:
+ if (temps[args[2]].state == TCG_TEMP_CONST) {
+ mask = (uint64_t)temps[args[1]].mask >> temps[args[2]].val;
}
break;
@@ -769,10 +856,40 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
mask = temps[args[3]].mask | temps[args[4]].mask;
break;
+ CASE_OP_32_64(ld8u):
+ case INDEX_op_qemu_ld8u:
+ mask = 0xff;
+ break;
+ CASE_OP_32_64(ld16u):
+ case INDEX_op_qemu_ld16u:
+ mask = 0xffff;
+ break;
+ case INDEX_op_ld32u_i64:
+#if TCG_TARGET_REG_BITS == 64
+ case INDEX_op_qemu_ld32u:
+#endif
+ mask = 0xffffffffu;
+ break;
+
+ CASE_OP_32_64(qemu_ld):
+ {
+ TCGMemOp mop = args[def->nb_oargs + def->nb_iargs];
+ if (!(mop & MO_SIGN)) {
+ mask = (2ULL << ((8 << (mop & MO_SIZE)) - 1)) - 1;
+ }
+ }
+ break;
+
default:
break;
}
+ /* 32-bit ops (non 64-bit ops and non load/store ops) generate 32-bit
+ results */
+ if (!(def->flags & (TCG_OPF_CALL_CLOBBER | TCG_OPF_64BIT))) {
+ mask &= 0xffffffffu;
+ }
+
if (mask == 0) {
assert(def->nb_oargs == 1);
s->gen_opc_buf[op_index] = op_to_movi(op);
@@ -839,6 +956,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
/* Simplify expression for "op r, a, a => movi r, 0" cases */
switch (op) {
+ CASE_OP_32_64(andc):
CASE_OP_32_64(sub):
CASE_OP_32_64(xor):
if (temps_are_copies(args[1], args[2])) {
@@ -1140,6 +1258,11 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
} else {
for (i = 0; i < def->nb_oargs; i++) {
reset_temp(args[i]);
+ /* Save the corresponding known-zero bits mask for the
+ first output argument (only one supported so far). */
+ if (i == 0) {
+ temps[args[i]].mask = mask;
+ }
}
}
for (i = 0; i < def->nb_args; i++) {
diff --git a/tcg/tcg.c b/tcg/tcg.c
index acd02b9..ffc851e 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -526,7 +526,7 @@ static inline int tcg_temp_new_internal(TCGType type, int temp_local)
ts->temp_local = temp_local;
ts->name = NULL;
ts++;
- ts->base_type = TCG_TYPE_I32;
+ ts->base_type = type;
ts->type = TCG_TYPE_I32;
ts->temp_allocated = 1;
ts->temp_local = temp_local;
diff --git a/tests/Makefile b/tests/Makefile
index 9a7d2f1..b17d41e 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,5 +1,9 @@
export SRC_PATH
+# Get the list of all supported sysemu targets
+SYSEMU_TARGET_LIST := $(subst -softmmu.mak,,$(notdir \
+ $(wildcard $(SRC_PATH)/default-configs/*-softmmu.mak)))
+
check-unit-y = tests/check-qdict$(EXESUF)
gcov-files-check-qdict-y = qobject/qdict.c
check-unit-y += tests/check-qfloat$(EXESUF)
@@ -60,64 +64,78 @@ check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
# All QTests for now are POSIX-only, but the dependencies are
# really in libqtest, not in the testcases themselves.
+
+gcov-files-ipack-y += hw/ipack/ipack.c
+check-qtest-ipack-y += tests/ipoctal232-test$(EXESUF)
+gcov-files-ipack-y += hw/char/ipoctal232.c
+
+gcov-files-virtio-y += i386-softmmu/hw/virtio/virtio.c
+check-qtest-virtio-y += tests/virtio-net-test$(EXESUF)
+gcov-files-virtio-y += i386-softmmu/hw/net/virtio-net.c
+
+check-qtest-pci-y += tests/e1000-test$(EXESUF)
+gcov-files-pci-y += hw/net/e1000.c
+check-qtest-pci-y += tests/rtl8139-test$(EXESUF)
+gcov-files-pci-y += hw/net/rtl8139.c
+check-qtest-pci-y += tests/pcnet-test$(EXESUF)
+gcov-files-pci-y += hw/net/pcnet.c
+gcov-files-pci-y += hw/net/pcnet-pci.c
+check-qtest-pci-y += tests/eepro100-test$(EXESUF)
+gcov-files-pci-y += hw/net/eepro100.c
+check-qtest-pci-y += tests/ne2000-test$(EXESUF)
+gcov-files-pci-y += hw/net/ne2000.c
+check-qtest-pci-y += $(check-qtest-virtio-y)
+gcov-files-pci-y += $(gcov-files-virtio-y) hw/virtio/virtio-pci.c
+check-qtest-pci-y += tests/tpci200-test$(EXESUF)
+gcov-files-pci-y += hw/char/tpci200.c
+check-qtest-pci-y += $(check-qtest-ipack-y)
+gcov-files-pci-y += $(gcov-files-ipack-y) hw/ipack/tpci200.c
+
check-qtest-i386-y = tests/endianness-test$(EXESUF)
check-qtest-i386-y += tests/fdc-test$(EXESUF)
-gcov-files-i386-y = hw/fdc.c
+gcov-files-i386-y = hw/block/fdc.c
check-qtest-i386-y += tests/ide-test$(EXESUF)
check-qtest-i386-y += tests/hd-geo-test$(EXESUF)
-gcov-files-i386-y += hw/hd-geometry.c
+gcov-files-i386-y += hw/block/hd-geometry.c
check-qtest-i386-y += tests/boot-order-test$(EXESUF)
check-qtest-i386-y += tests/acpi-test$(EXESUF)
check-qtest-i386-y += tests/rtc-test$(EXESUF)
check-qtest-i386-y += tests/i440fx-test$(EXESUF)
check-qtest-i386-y += tests/fw_cfg-test$(EXESUF)
-check-qtest-i386-y += tests/qom-test$(EXESUF)
check-qtest-i386-y += tests/blockdev-test$(EXESUF)
check-qtest-i386-y += tests/qdev-monitor-test$(EXESUF)
+check-qtest-i386-y += $(check-qtest-pci-y)
+gcov-files-i386-y += $(gcov-files-pci-y)
+check-qtest-i386-y += tests/vmxnet3-test$(EXESUF)
+gcov-files-i386-y += hw/net/vmxnet3.c
+gcov-files-i386-y += hw/net/vmxnet_rx_pkt.c
+gcov-files-i386-y += hw/net/vmxnet_tx_pkt.c
check-qtest-x86_64-y = $(check-qtest-i386-y)
-gcov-files-i386-y += i386-softmmu/hw/mc146818rtc.c
+gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
check-qtest-mips-y = tests/endianness-test$(EXESUF)
check-qtest-mips64-y = tests/endianness-test$(EXESUF)
check-qtest-mips64el-y = tests/endianness-test$(EXESUF)
-check-qtest-mips-y += tests/qom-test$(EXESUF)
-check-qtest-mipsel-y += tests/qom-test$(EXESUF)
-check-qtest-mips64-y += tests/qom-test$(EXESUF)
-check-qtest-mips64el-y += tests/qom-test$(EXESUF)
check-qtest-ppc-y = tests/endianness-test$(EXESUF)
check-qtest-ppc64-y = tests/endianness-test$(EXESUF)
check-qtest-sh4-y = tests/endianness-test$(EXESUF)
check-qtest-sh4eb-y = tests/endianness-test$(EXESUF)
-check-qtest-sh4-y += tests/qom-test$(EXESUF)
-check-qtest-sh4eb-y += tests/qom-test$(EXESUF)
check-qtest-sparc64-y = tests/endianness-test$(EXESUF)
#check-qtest-sparc-y = tests/m48t59-test$(EXESUF)
#check-qtest-sparc64-y += tests/m48t59-test$(EXESUF)
-gcov-files-sparc-y += hw/m48t59.c
-gcov-files-sparc64-y += hw/m48t59.c
-check-qtest-sparc-y += tests/qom-test$(EXESUF)
-check-qtest-sparc64-y += tests/qom-test$(EXESUF)
+gcov-files-sparc-y += hw/timer/m48t59.c
+gcov-files-sparc64-y += hw/timer/m48t59.c
check-qtest-arm-y = tests/tmp105-test$(EXESUF)
-gcov-files-arm-y += hw/tmp105.c
-check-qtest-arm-y += tests/qom-test$(EXESUF)
+gcov-files-arm-y += hw/misc/tmp105.c
check-qtest-ppc-y += tests/boot-order-test$(EXESUF)
check-qtest-ppc64-y += tests/boot-order-test$(EXESUF)
-check-qtest-ppc-y += tests/qom-test$(EXESUF)
-check-qtest-ppc64-y += tests/qom-test$(EXESUF)
-check-qtest-ppcemb-y += tests/qom-test$(EXESUF)
-check-qtest-alpha-y += tests/qom-test$(EXESUF)
-check-qtest-cris-y += tests/qom-test$(EXESUF)
-check-qtest-lm32-y += tests/qom-test$(EXESUF)
-check-qtest-m68k-y += tests/qom-test$(EXESUF)
-check-qtest-microblaze-y += tests/qom-test$(EXESUF)
check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
-check-qtest-moxie-y += tests/qom-test$(EXESUF)
-check-qtest-or32-y += tests/qom-test$(EXESUF)
-check-qtest-s390x-y += tests/qom-test$(EXESUF)
-check-qtest-unicore32-y += tests/qom-test$(EXESUF)
-check-qtest-xtensa-y += tests/qom-test$(EXESUF)
check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
+# qom-test works for all sysemu architectures:
+$(foreach target,$(SYSEMU_TARGET_LIST), \
+ $(eval check-qtest-$(target)-y += tests/qom-test$(EXESUF)))
+
check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
comments.json empty.json funny-char.json indented-expr.json \
missing-colon.json missing-comma-list.json \
@@ -211,6 +229,15 @@ tests/acpi-test$(EXESUF): tests/acpi-test.o $(libqos-obj-y)
tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
+tests/e1000-test$(EXESUF): tests/e1000-test.o
+tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o
+tests/pcnet-test$(EXESUF): tests/pcnet-test.o
+tests/eepro100-test$(EXESUF): tests/eepro100-test.o
+tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
+tests/ne2000-test$(EXESUF): tests/ne2000-test.o
+tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o
+tests/tpci200-test$(EXESUF): tests/tpci200-test.o
+tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o
tests/qom-test$(EXESUF): tests/qom-test.o
tests/blockdev-test$(EXESUF): tests/blockdev-test.o $(libqos-pc-obj-y)
tests/qdev-monitor-test$(EXESUF): tests/qdev-monitor-test.o $(libqos-pc-obj-y)
diff --git a/tests/e1000-test.c b/tests/e1000-test.c
new file mode 100644
index 0000000..a8ba2fc
--- /dev/null
+++ b/tests/e1000-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for e1000 NIC
+ *
+ * Copyright (c) 2013-2014 SUSE LINUX Products GmbH
+ *
+ * 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 <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/e1000/nop", nop);
+
+ qtest_start("-device e1000");
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/eepro100-test.c b/tests/eepro100-test.c
new file mode 100644
index 0000000..bf82526
--- /dev/null
+++ b/tests/eepro100-test.c
@@ -0,0 +1,63 @@
+/*
+ * QTest testcase for eepro100 NIC
+ *
+ * Copyright (c) 2013-2014 SUSE LINUX Products GmbH
+ *
+ * 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 <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+static void test_device(gconstpointer data)
+{
+ const char *model = data;
+ QTestState *s;
+ char *args;
+
+ args = g_strdup_printf("-device %s", model);
+ s = qtest_start(args);
+
+ /* Tests only initialization so far. TODO: Implement functional tests */
+
+ if (s) {
+ qtest_quit(s);
+ }
+ g_free(args);
+}
+
+static const char *models[] = {
+ "i82550",
+ "i82551",
+ "i82557a",
+ "i82557b",
+ "i82557c",
+ "i82558a",
+ "i82558b",
+ "i82559a",
+ "i82559b",
+ "i82559c",
+ "i82559er",
+ "i82562",
+ "i82801",
+};
+
+int main(int argc, char **argv)
+{
+ int i;
+
+ g_test_init(&argc, &argv, NULL);
+
+ for (i = 0; i < ARRAY_SIZE(models); i++) {
+ char *path;
+
+ path = g_strdup_printf("/%s/eepro100/%s",
+ qtest_get_arch(), models[i]);
+ g_test_add_data_func(path, models[i], test_device);
+ }
+
+ return g_test_run();
+}
diff --git a/tests/endianness-test.c b/tests/endianness-test.c
index 646df7d..92e17d2 100644
--- a/tests/endianness-test.c
+++ b/tests/endianness-test.c
@@ -10,7 +10,6 @@
* See the COPYING file in the top-level directory.
*
*/
-#include "libqtest.h"
#include <glib.h>
#include <stdio.h>
@@ -18,6 +17,7 @@
#include <stdlib.h>
#include <unistd.h>
+#include "libqtest.h"
#include "qemu/bswap.h"
typedef struct TestCase TestCase;
diff --git a/tests/fw_cfg-test.c b/tests/fw_cfg-test.c
index e4f355c..5c8f8d6 100644
--- a/tests/fw_cfg-test.c
+++ b/tests/fw_cfg-test.c
@@ -10,15 +10,14 @@
* See the COPYING file in the top-level directory.
*/
-#define NO_QEMU_PROTOS
+#include <string.h>
+#include <glib.h>
#include "libqtest.h"
+#define NO_QEMU_PROTOS
#include "hw/nvram/fw_cfg.h"
#include "libqos/fw_cfg.h"
-#include <string.h>
-#include <glib.h>
-
static uint64_t ram_size = 128 << 20;
static uint16_t nb_cpus = 1;
static uint16_t max_cpus = 1;
diff --git a/tests/i440fx-test.c b/tests/i440fx-test.c
index bcd2181..ad232b5 100644
--- a/tests/i440fx-test.c
+++ b/tests/i440fx-test.c
@@ -12,12 +12,6 @@
* See the COPYING file in the top-level directory.
*/
-#include "libqos/pci.h"
-#include "libqos/pci-pc.h"
-#include "libqtest.h"
-
-#include "hw/pci/pci_regs.h"
-
#include <glib.h>
#include <string.h>
#include <stdio.h>
@@ -26,6 +20,11 @@
#include <sys/mman.h>
#include <stdlib.h>
+#include "libqtest.h"
+#include "libqos/pci.h"
+#include "libqos/pci-pc.h"
+#include "hw/pci/pci_regs.h"
+
#define BROKEN 1
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
diff --git a/tests/ipoctal232-test.c b/tests/ipoctal232-test.c
new file mode 100644
index 0000000..3ac1714
--- /dev/null
+++ b/tests/ipoctal232-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for IndustryPack Octal-RS232
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * 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 <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/ipoctal232/tpci200/nop", nop);
+
+ qtest_start("-device tpci200,id=ipack0 -device ipoctal232,bus=ipack0.0");
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/libqtest.c b/tests/libqtest.c
index c9a4f89..f587d36 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -43,8 +43,8 @@ struct QTestState
int qmp_fd;
bool irq_level[MAX_IRQ];
GString *rx;
- int child_pid; /* Child process created to execute QEMU */
- pid_t qemu_pid; /* QEMU process spawned by our child */
+ pid_t qemu_pid; /* our child QEMU process */
+ struct sigaction sigact_old; /* restored on exit */
};
#define g_assert_no_errno(ret) do { \
@@ -89,20 +89,17 @@ static int socket_accept(int sock)
return ret;
}
-static pid_t read_pid_file(const char *pid_file)
+static void kill_qemu(QTestState *s)
{
- FILE *f;
- char buffer[1024];
- pid_t pid = -1;
-
- f = fopen(pid_file, "r");
- if (f) {
- if (fgets(buffer, sizeof(buffer), f)) {
- pid = atoi(buffer);
- }
- fclose(f);
+ if (s->qemu_pid != -1) {
+ kill(s->qemu_pid, SIGTERM);
+ waitpid(s->qemu_pid, NULL, 0);
}
- return pid;
+}
+
+static void sigabrt_handler(int signo)
+{
+ kill_qemu(global_qtest);
}
QTestState *qtest_init(const char *extra_args)
@@ -111,10 +108,9 @@ QTestState *qtest_init(const char *extra_args)
int sock, qmpsock, i;
gchar *socket_path;
gchar *qmp_socket_path;
- gchar *pid_file;
gchar *command;
const char *qemu_binary;
- pid_t pid;
+ struct sigaction sigact;
qemu_binary = getenv("QTEST_QEMU_BINARY");
g_assert(qemu_binary != NULL);
@@ -123,22 +119,28 @@ QTestState *qtest_init(const char *extra_args)
socket_path = g_strdup_printf("/tmp/qtest-%d.sock", getpid());
qmp_socket_path = g_strdup_printf("/tmp/qtest-%d.qmp", getpid());
- pid_file = g_strdup_printf("/tmp/qtest-%d.pid", getpid());
sock = init_socket(socket_path);
qmpsock = init_socket(qmp_socket_path);
- pid = fork();
- if (pid == 0) {
- command = g_strdup_printf("%s "
+ /* Catch SIGABRT to clean up on g_assert() failure */
+ sigact = (struct sigaction){
+ .sa_handler = sigabrt_handler,
+ .sa_flags = SA_RESETHAND,
+ };
+ sigemptyset(&sigact.sa_mask);
+ sigaction(SIGABRT, &sigact, &s->sigact_old);
+
+ s->qemu_pid = fork();
+ if (s->qemu_pid == 0) {
+ command = g_strdup_printf("exec %s "
"-qtest unix:%s,nowait "
"-qtest-log /dev/null "
"-qmp unix:%s,nowait "
- "-pidfile %s "
"-machine accel=qtest "
"-display none "
"%s", qemu_binary, socket_path,
- qmp_socket_path, pid_file,
+ qmp_socket_path,
extra_args ?: "");
execlp("/bin/sh", "sh", "-c", command, NULL);
exit(1);
@@ -152,7 +154,6 @@ QTestState *qtest_init(const char *extra_args)
g_free(qmp_socket_path);
s->rx = g_string_new("");
- s->child_pid = pid;
for (i = 0; i < MAX_IRQ; i++) {
s->irq_level[i] = false;
}
@@ -161,10 +162,6 @@ QTestState *qtest_init(const char *extra_args)
qtest_qmp_discard_response(s, "");
qtest_qmp_discard_response(s, "{ 'execute': 'qmp_capabilities' }");
- s->qemu_pid = read_pid_file(pid_file);
- unlink(pid_file);
- g_free(pid_file);
-
if (getenv("QTEST_STOP")) {
kill(s->qemu_pid, SIGSTOP);
}
@@ -174,13 +171,9 @@ QTestState *qtest_init(const char *extra_args)
void qtest_quit(QTestState *s)
{
- int status;
-
- if (s->qemu_pid != -1) {
- kill(s->qemu_pid, SIGTERM);
- waitpid(s->qemu_pid, &status, 0);
- }
+ sigaction(SIGABRT, &s->sigact_old, NULL);
+ kill_qemu(s);
close(s->fd);
close(s->qmp_fd);
g_string_free(s->rx, true);
diff --git a/tests/m48t59-test.c b/tests/m48t59-test.c
index 6abc4c8..71b4f28 100644
--- a/tests/m48t59-test.c
+++ b/tests/m48t59-test.c
@@ -11,7 +11,6 @@
* See the COPYING file in the top-level directory.
*
*/
-#include "libqtest.h"
#include <glib.h>
#include <stdio.h>
@@ -19,6 +18,8 @@
#include <stdlib.h>
#include <unistd.h>
+#include "libqtest.h"
+
#define RTC_SECONDS 0x9
#define RTC_MINUTES 0xa
#define RTC_HOURS 0xb
diff --git a/tests/ne2000-test.c b/tests/ne2000-test.c
new file mode 100644
index 0000000..61a678a
--- /dev/null
+++ b/tests/ne2000-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for ne2000 NIC
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * 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 <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void pci_nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/ne2000/pci/nop", pci_nop);
+
+ qtest_start("-device ne2k_pci");
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/pcnet-test.c b/tests/pcnet-test.c
new file mode 100644
index 0000000..84af4f3
--- /dev/null
+++ b/tests/pcnet-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for PC-Net NIC
+ *
+ * Copyright (c) 2013-2014 SUSE LINUX Products GmbH
+ *
+ * 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 <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void pci_nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/pcnet/pci/nop", pci_nop);
+
+ qtest_start("-device pcnet");
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/qom-test.c b/tests/qom-test.c
index 5e5af7a..b6671fb 100644
--- a/tests/qom-test.c
+++ b/tests/qom-test.c
@@ -6,250 +6,94 @@
* 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 "libqtest.h"
#include <glib.h>
#include <string.h>
+
+#include "libqtest.h"
#include "qemu/osdep.h"
+#include "qapi/qmp/types.h"
+
+static const char *blacklist_x86[] = {
+ "xenfv", "xenpv", NULL
+};
+
+static const struct {
+ const char *arch;
+ const char **machine;
+} blacklists[] = {
+ { "i386", blacklist_x86 },
+ { "x86_64", blacklist_x86 },
+};
-static void test_nop(gconstpointer data)
+static bool is_blacklisted(const char *arch, const char *mach)
+{
+ int i;
+ const char **p;
+
+ for (i = 0; i < ARRAY_SIZE(blacklists); i++) {
+ if (!strcmp(blacklists[i].arch, arch)) {
+ for (p = blacklists[i].machine; *p; p++) {
+ if (!strcmp(*p, mach)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+static void test_machine(gconstpointer data)
{
- QTestState *s;
const char *machine = data;
char *args;
+ QDict *response;
args = g_strdup_printf("-machine %s", machine);
- s = qtest_start(args);
- if (s) {
- qtest_quit(s);
- }
+ qtest_start(args);
+ response = qmp("{ 'execute': 'quit' }");
+ g_assert(qdict_haskey(response, "return"));
+ qtest_end();
g_free(args);
}
-static const char *x86_machines[] = {
- "pc",
- "isapc",
- "q35",
-};
-
-static const char *alpha_machines[] = {
- "clipper",
-};
-
-static const char *arm_machines[] = {
- "integratorcp",
- "versatilepb",
- "versatileab",
- "lm3s811evb",
- "lm3s6965evb",
- "collie",
- "akita",
- "spitz",
- "borzoi",
- "terrier",
- "tosa",
- "cheetah",
- "sx1-v1",
- "sx1",
- "realview-eb",
- "realview-eb-mpcore",
- "realview-pb-a8",
- "realview-pbx-a9",
- "musicpal",
- "mainstone",
- "connex",
- "verdex",
- "z2",
- "n800",
- "n810",
- "kzm",
- "vexpress-a9",
- "vexpress-a15",
- "smdkc210",
- "nuri",
- "xilinx-zynq-a9",
- "highbank",
- "midway",
- "canon-a1100",
- "cubieboard",
-};
-
-static const char *cris_machines[] = {
- "axis-dev88",
-};
-
-static const char *lm32_machines[] = {
- "lm32-evr",
- "lm32-uclinux",
- "milkymist",
-};
-
-static const char *m68k_machines[] = {
- "mcf5208evb",
- "an5206",
- "dummy",
-};
-
-static const char *microblaze_machines[] = {
- "petalogix-ml605",
- "petalogix-s3adsp1800",
-};
-
-static const char *mips_machines[] = {
- "malta",
- "magnum",
- "mips",
- "mipssim",
- "pica61",
-};
-
-static const char *moxie_machines[] = {
- "moxiesim",
-};
-
-static const char *openrisc_machines[] = {
- "or32-sim",
-};
-
-static const char *ppc_machines[] = {
- "g3beige",
- "mac99",
- "prep",
- "mpc8544ds",
- "ppce500",
-};
-
-static const char *ppc64_machines[] = {
- "pseries",
-};
-
-static const char *ppc405_machines[] = {
- "ref405ep",
- "taihu",
-};
-
-static const char *ppc440_machines[] = {
- "bamboo",
- "virtex-ml507",
-};
-
-static const char *s390_machines[] = {
- "s390-virtio",
- "s390-ccw-virtio",
-};
-
-static const char *superh_machines[] = {
- "r2d",
- "shix",
-};
-
-static const char *sparc_machines[] = {
- "SS-4",
- "SS-5",
- "SS-10",
- "SS-20",
- "SS-600MP",
- "LX",
- "SPARCClassic",
- "SPARCbook",
- "leon3_generic",
-};
-
-static const char *sparc64_machines[] = {
- "sun4u",
- "sun4v",
- "Niagara",
-};
-
-static const char *unicore32_machines[] = {
- "puv3",
-};
-
-static const char *xtensa_machines[] = {
- "sim",
- "lx60",
- "lx200",
-};
-
-static void add_test_cases(const char *arch, const char *machine)
+static void add_machine_test_cases(void)
{
- char *path;
- path = g_strdup_printf("/%s/qom/%s", arch, machine);
- g_test_add_data_func(path, machine, test_nop);
+ const char *arch = qtest_get_arch();
+ QDict *response, *minfo;
+ QList *list;
+ const QListEntry *p;
+ QObject *qobj;
+ QString *qstr;
+ const char *mname, *path;
+
+ qtest_start("-machine none");
+ response = qmp("{ 'execute': 'query-machines' }");
+ g_assert(response);
+ list = qdict_get_qlist(response, "return");
+ g_assert(list);
+
+ for (p = qlist_first(list); p; p = qlist_next(p)) {
+ minfo = qobject_to_qdict(qlist_entry_obj(p));
+ g_assert(minfo);
+ qobj = qdict_get(minfo, "name");
+ g_assert(qobj);
+ qstr = qobject_to_qstring(qobj);
+ g_assert(qstr);
+ mname = qstring_get_str(qstr);
+ if (!is_blacklisted(arch, mname)) {
+ path = g_strdup_printf("/%s/qom/%s", arch, mname);
+ g_test_add_data_func(path, mname, test_machine);
+ }
+ }
+ qtest_end();
}
-#define ADD_MACHINE_TESTS(arch, array) do { \
- int i; \
- for (i = 0; i < ARRAY_SIZE(array); i++) { \
- add_test_cases((arch), (array)[i]); \
- } \
-} while (false)
-
int main(int argc, char **argv)
{
- const char *arch = qtest_get_arch();
-
g_test_init(&argc, &argv, NULL);
- add_test_cases(arch, "none");
-
- if (strcmp(arch, "i386") == 0 ||
- strcmp(arch, "x86_64") == 0) {
- ADD_MACHINE_TESTS(arch, x86_machines);
- } else if (strcmp(arch, "alpha") == 0) {
- ADD_MACHINE_TESTS(arch, alpha_machines);
- } else if (strcmp(arch, "arm") == 0) {
- ADD_MACHINE_TESTS(arch, arm_machines);
- } else if (strcmp(arch, "cris") == 0) {
- ADD_MACHINE_TESTS(arch, cris_machines);
- } else if (strcmp(arch, "lm32") == 0) {
- ADD_MACHINE_TESTS(arch, lm32_machines);
- } else if (strcmp(arch, "m68k") == 0) {
- ADD_MACHINE_TESTS(arch, m68k_machines);
- } else if (strcmp(arch, "microblaze") == 0 ||
- strcmp(arch, "microblazeel") == 0) {
- ADD_MACHINE_TESTS(arch, microblaze_machines);
- } else if (strcmp(arch, "mips") == 0 ||
- strcmp(arch, "mipsel") == 0 ||
- strcmp(arch, "mips64") == 0) {
- ADD_MACHINE_TESTS(arch, mips_machines);
- } else if (strcmp(arch, "mips64el") == 0) {
- ADD_MACHINE_TESTS(arch, mips_machines);
- add_test_cases(arch, "fulong2e");
- } else if (strcmp(arch, "moxie") == 0) {
- ADD_MACHINE_TESTS(arch, moxie_machines);
- } else if (strcmp(arch, "or32") == 0) {
- ADD_MACHINE_TESTS(arch, openrisc_machines);
- } else if (strcmp(arch, "ppcemb") == 0) {
-#if 0
- /* XXX Available in ppcemb but don't work */
- ADD_MACHINE_TESTS(arch, ppc405_machines);
-#endif
- ADD_MACHINE_TESTS(arch, ppc440_machines);
- } else if (strcmp(arch, "ppc") == 0) {
- ADD_MACHINE_TESTS(arch, ppc405_machines);
- ADD_MACHINE_TESTS(arch, ppc440_machines);
- ADD_MACHINE_TESTS(arch, ppc_machines);
- } else if (strcmp(arch, "ppc64") == 0) {
- ADD_MACHINE_TESTS(arch, ppc405_machines);
- ADD_MACHINE_TESTS(arch, ppc440_machines);
- ADD_MACHINE_TESTS(arch, ppc_machines);
- ADD_MACHINE_TESTS(arch, ppc64_machines);
- } else if (strcmp(arch, "s390x") == 0) {
- ADD_MACHINE_TESTS(arch, s390_machines);
- } else if (strcmp(arch, "sh4") == 0 ||
- strcmp(arch, "sh4eb") == 0) {
- ADD_MACHINE_TESTS(arch, superh_machines);
- } else if (strcmp(arch, "sparc") == 0) {
- ADD_MACHINE_TESTS(arch, sparc_machines);
- } else if (strcmp(arch, "sparc64") == 0) {
- ADD_MACHINE_TESTS(arch, sparc64_machines);
- } else if (strcmp(arch, "unicore32") == 0) {
- ADD_MACHINE_TESTS(arch, unicore32_machines);
- } else if (strcmp(arch, "xtensa") == 0 ||
- strcmp(arch, "xtensaeb") == 0) {
- ADD_MACHINE_TESTS(arch, xtensa_machines);
- }
+ add_machine_test_cases();
return g_test_run();
}
diff --git a/tests/rtc-test.c b/tests/rtc-test.c
index f1b123f..4243624 100644
--- a/tests/rtc-test.c
+++ b/tests/rtc-test.c
@@ -10,8 +10,6 @@
* See the COPYING file in the top-level directory.
*
*/
-#include "libqtest.h"
-#include "hw/timer/mc146818rtc_regs.h"
#include <glib.h>
#include <stdio.h>
@@ -19,6 +17,9 @@
#include <stdlib.h>
#include <unistd.h>
+#include "libqtest.h"
+#include "hw/timer/mc146818rtc_regs.h"
+
static uint8_t base = 0x70;
static int bcd2dec(int value)
diff --git a/tests/rtl8139-test.c b/tests/rtl8139-test.c
new file mode 100644
index 0000000..f6a1be3
--- /dev/null
+++ b/tests/rtl8139-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for Realtek 8139 NIC
+ *
+ * Copyright (c) 2013-2014 SUSE LINUX Products GmbH
+ *
+ * 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 <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/rtl8139/nop", nop);
+
+ qtest_start("-device rtl8139");
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index 6f68963..38bdf5e 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -92,7 +92,7 @@ static void test_validate_struct(TestInputVisitorData *data,
v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
visit_type_TestStruct(v, &p, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_free(p->string);
g_free(p);
}
@@ -107,7 +107,7 @@ static void test_validate_struct_nested(TestInputVisitorData *data,
v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string' }, 'string2': 'string2'}}}");
visit_type_UserDefNested(v, &udp, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
qapi_free_UserDefNested(udp);
}
@@ -121,7 +121,7 @@ static void test_validate_list(TestInputVisitorData *data,
v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
visit_type_UserDefOneList(v, &head, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
qapi_free_UserDefOneList(head);
}
@@ -135,7 +135,7 @@ static void test_validate_union(TestInputVisitorData *data,
v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 } }");
visit_type_UserDefUnion(v, &tmp, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
qapi_free_UserDefUnion(tmp);
}
@@ -149,7 +149,7 @@ static void test_validate_fail_struct(TestInputVisitorData *data,
v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }");
visit_type_TestStruct(v, &p, NULL, &errp);
- g_assert(error_is_set(&errp));
+ g_assert(errp);
if (p) {
g_free(p->string);
}
@@ -166,7 +166,7 @@ static void test_validate_fail_struct_nested(TestInputVisitorData *data,
v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}");
visit_type_UserDefNested(v, &udp, NULL, &errp);
- g_assert(error_is_set(&errp));
+ g_assert(errp);
qapi_free_UserDefNested(udp);
}
@@ -180,7 +180,7 @@ static void test_validate_fail_list(TestInputVisitorData *data,
v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]");
visit_type_UserDefOneList(v, &head, NULL, &errp);
- g_assert(error_is_set(&errp));
+ g_assert(errp);
qapi_free_UserDefOneList(head);
}
@@ -194,7 +194,7 @@ static void test_validate_fail_union(TestInputVisitorData *data,
v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 }, 'extra': 'yyy' }");
visit_type_UserDefUnion(v, &tmp, NULL, &errp);
- g_assert(error_is_set(&errp));
+ g_assert(errp);
qapi_free_UserDefUnion(tmp);
}
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 1e1c6fa..6eb7dc5 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -96,7 +96,7 @@ static void test_visitor_in_int(TestInputVisitorData *data,
v = visitor_input_test_init(data, "%" PRId64, value);
visit_type_int(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpint(res, ==, value);
}
@@ -114,7 +114,7 @@ static void test_visitor_in_int_overflow(TestInputVisitorData *data,
v = visitor_input_test_init(data, "%f", DBL_MAX);
visit_type_int(v, &res, NULL, &errp);
- g_assert(error_is_set(&errp));
+ g_assert(errp);
error_free(errp);
}
@@ -128,7 +128,7 @@ static void test_visitor_in_bool(TestInputVisitorData *data,
v = visitor_input_test_init(data, "true");
visit_type_bool(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpint(res, ==, true);
}
@@ -142,7 +142,7 @@ static void test_visitor_in_number(TestInputVisitorData *data,
v = visitor_input_test_init(data, "%f", value);
visit_type_number(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpfloat(res, ==, value);
}
@@ -156,7 +156,7 @@ static void test_visitor_in_string(TestInputVisitorData *data,
v = visitor_input_test_init(data, "%s", value);
visit_type_str(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpstr(res, ==, value);
g_free(res);
@@ -175,7 +175,7 @@ static void test_visitor_in_enum(TestInputVisitorData *data,
v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]);
visit_type_EnumOne(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpint(i, ==, res);
visitor_input_teardown(data, NULL);
@@ -223,7 +223,7 @@ static void test_visitor_in_struct(TestInputVisitorData *data,
v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
visit_type_TestStruct(v, &p, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpint(p->integer, ==, -42);
g_assert(p->boolean == true);
g_assert_cmpstr(p->string, ==, "foo");
@@ -248,7 +248,7 @@ static void test_visitor_in_struct_nested(TestInputVisitorData *data,
v = visitor_input_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string' }, 'string2': 'string2'}}}");
visit_type_UserDefNested(v, &udp, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
check_and_free_str(udp->string0, "string0");
check_and_free_str(udp->dict1.string1, "string1");
@@ -272,7 +272,7 @@ static void test_visitor_in_list(TestInputVisitorData *data,
v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
visit_type_UserDefOneList(v, &head, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert(head != NULL);
for (i = 0, item = head; item; item = item->next, i++) {
@@ -601,7 +601,7 @@ static void test_visitor_in_errors(TestInputVisitorData *data,
v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', 'string': -42 }");
visit_type_TestStruct(v, &p, NULL, &errp);
- g_assert(error_is_set(&errp));
+ g_assert(errp);
g_assert(p->string == NULL);
error_free(errp);
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index e073d83..f31d168 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -49,7 +49,7 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
QObject *obj;
visit_type_int(data->ov, &value, NULL, &errp);
- g_assert(error_is_set(&errp) == 0);
+ g_assert(!errp);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
@@ -67,7 +67,7 @@ static void test_visitor_out_bool(TestOutputVisitorData *data,
QObject *obj;
visit_type_bool(data->ov, &value, NULL, &errp);
- g_assert(error_is_set(&errp) == 0);
+ g_assert(!errp);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
@@ -85,7 +85,7 @@ static void test_visitor_out_number(TestOutputVisitorData *data,
QObject *obj;
visit_type_number(data->ov, &value, NULL, &errp);
- g_assert(error_is_set(&errp) == 0);
+ g_assert(!errp);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
@@ -103,7 +103,7 @@ static void test_visitor_out_string(TestOutputVisitorData *data,
QObject *obj;
visit_type_str(data->ov, &string, NULL, &errp);
- g_assert(error_is_set(&errp) == 0);
+ g_assert(!errp);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
@@ -122,7 +122,7 @@ static void test_visitor_out_no_string(TestOutputVisitorData *data,
/* A null string should return "" */
visit_type_str(data->ov, &string, NULL, &errp);
- g_assert(error_is_set(&errp) == 0);
+ g_assert(!errp);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
@@ -141,7 +141,7 @@ static void test_visitor_out_enum(TestOutputVisitorData *data,
for (i = 0; i < ENUM_ONE_MAX; i++) {
visit_type_EnumOne(data->ov, &i, "unused", &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
@@ -161,7 +161,7 @@ static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
errp = NULL;
visit_type_EnumOne(data->ov, &bad_values[i], "unused", &errp);
- g_assert(error_is_set(&errp) == true);
+ g_assert(errp);
error_free(errp);
}
}
@@ -198,7 +198,7 @@ static void test_visitor_out_struct(TestOutputVisitorData *data,
QDict *qdict;
visit_type_TestStruct(data->ov, &p, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
@@ -241,7 +241,7 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
ud2->dict1.dict3.string3 = g_strdup(strings[3]);
visit_type_UserDefNested(data->ov, &ud2, "unused", &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
@@ -288,7 +288,7 @@ static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
u.has_enum1 = true;
u.enum1 = bad_values[i];
visit_type_UserDefOne(data->ov, &pu, "unused", &errp);
- g_assert(error_is_set(&errp) == true);
+ g_assert(errp);
error_free(errp);
}
}
@@ -343,7 +343,7 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
}
visit_type_TestStructList(data->ov, &head, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c
index 5989f81..d406263 100644
--- a/tests/test-string-input-visitor.c
+++ b/tests/test-string-input-visitor.c
@@ -60,7 +60,7 @@ static void test_visitor_in_int(TestInputVisitorData *data,
v = visitor_input_test_init(data, "-42");
visit_type_int(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpint(res, ==, value);
}
@@ -74,42 +74,42 @@ static void test_visitor_in_bool(TestInputVisitorData *data,
v = visitor_input_test_init(data, "true");
visit_type_bool(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpint(res, ==, true);
visitor_input_teardown(data, unused);
v = visitor_input_test_init(data, "yes");
visit_type_bool(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpint(res, ==, true);
visitor_input_teardown(data, unused);
v = visitor_input_test_init(data, "on");
visit_type_bool(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpint(res, ==, true);
visitor_input_teardown(data, unused);
v = visitor_input_test_init(data, "false");
visit_type_bool(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpint(res, ==, false);
visitor_input_teardown(data, unused);
v = visitor_input_test_init(data, "no");
visit_type_bool(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpint(res, ==, false);
visitor_input_teardown(data, unused);
v = visitor_input_test_init(data, "off");
visit_type_bool(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpint(res, ==, false);
}
@@ -123,7 +123,7 @@ static void test_visitor_in_number(TestInputVisitorData *data,
v = visitor_input_test_init(data, "3.14");
visit_type_number(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpfloat(res, ==, value);
}
@@ -137,7 +137,7 @@ static void test_visitor_in_string(TestInputVisitorData *data,
v = visitor_input_test_init(data, value);
visit_type_str(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpstr(res, ==, value);
g_free(res);
@@ -156,7 +156,7 @@ static void test_visitor_in_enum(TestInputVisitorData *data,
v = visitor_input_test_init(data, EnumOne_lookup[i]);
visit_type_EnumOne(v, &res, NULL, &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
g_assert_cmpint(i, ==, res);
visitor_input_teardown(data, NULL);
diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c
index 79d815f..22363d1 100644
--- a/tests/test-string-output-visitor.c
+++ b/tests/test-string-output-visitor.c
@@ -26,7 +26,7 @@ typedef struct TestOutputVisitorData {
static void visitor_output_setup(TestOutputVisitorData *data,
const void *unused)
{
- data->sov = string_output_visitor_new();
+ data->sov = string_output_visitor_new(false);
g_assert(data->sov != NULL);
data->ov = string_output_get_visitor(data->sov);
@@ -49,7 +49,7 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
char *str;
visit_type_int(data->ov, &value, NULL, &errp);
- g_assert(error_is_set(&errp) == 0);
+ g_assert(!errp);
str = string_output_get_string(data->sov);
g_assert(str != NULL);
@@ -65,7 +65,7 @@ static void test_visitor_out_bool(TestOutputVisitorData *data,
char *str;
visit_type_bool(data->ov, &value, NULL, &errp);
- g_assert(error_is_set(&errp) == 0);
+ g_assert(!errp);
str = string_output_get_string(data->sov);
g_assert(str != NULL);
@@ -81,7 +81,7 @@ static void test_visitor_out_number(TestOutputVisitorData *data,
char *str;
visit_type_number(data->ov, &value, NULL, &errp);
- g_assert(error_is_set(&errp) == 0);
+ g_assert(!errp);
str = string_output_get_string(data->sov);
g_assert(str != NULL);
@@ -97,7 +97,7 @@ static void test_visitor_out_string(TestOutputVisitorData *data,
char *str;
visit_type_str(data->ov, &string, NULL, &errp);
- g_assert(error_is_set(&errp) == 0);
+ g_assert(!errp);
str = string_output_get_string(data->sov);
g_assert(str != NULL);
@@ -114,7 +114,7 @@ static void test_visitor_out_no_string(TestOutputVisitorData *data,
/* A null string should return "" */
visit_type_str(data->ov, &string, NULL, &errp);
- g_assert(error_is_set(&errp) == 0);
+ g_assert(!errp);
str = string_output_get_string(data->sov);
g_assert(str != NULL);
@@ -131,7 +131,7 @@ static void test_visitor_out_enum(TestOutputVisitorData *data,
for (i = 0; i < ENUM_ONE_MAX; i++) {
visit_type_EnumOne(data->ov, &i, "unused", &errp);
- g_assert(!error_is_set(&errp));
+ g_assert(!errp);
str = string_output_get_string(data->sov);
g_assert(str != NULL);
@@ -149,7 +149,7 @@ static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
errp = NULL;
visit_type_EnumOne(data->ov, &bad_values[i], "unused", &errp);
- g_assert(error_is_set(&errp) == true);
+ g_assert(errp);
error_free(errp);
}
}
diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c
index 9aaa587..6bff950 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -1083,7 +1083,7 @@ static void string_serialize(void *native_in, void **datap,
{
StringSerializeData *d = g_malloc0(sizeof(*d));
- d->sov = string_output_visitor_new();
+ d->sov = string_output_visitor_new(false);
visit(string_output_get_visitor(d->sov), &native_in, errp);
*datap = d;
}
diff --git a/tests/tmp105-test.c b/tests/tmp105-test.c
index 5ac48e2..0834219 100644
--- a/tests/tmp105-test.c
+++ b/tests/tmp105-test.c
@@ -6,12 +6,13 @@
* 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 <glib.h>
+
#include "libqtest.h"
#include "libqos/i2c.h"
#include "hw/misc/tmp105_regs.h"
-#include <glib.h>
-
#define OMAP2_I2C_1_BASE 0x48070000
#define N8X0_ADDR 0x48
diff --git a/tests/tpci200-test.c b/tests/tpci200-test.c
new file mode 100644
index 0000000..9ae0127
--- /dev/null
+++ b/tests/tpci200-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for tpci200 PCI-IndustryPack bridge
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * 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 <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/tpci200/nop", nop);
+
+ qtest_start("-device tpci200");
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/virtio-net-test.c b/tests/virtio-net-test.c
new file mode 100644
index 0000000..df99343
--- /dev/null
+++ b/tests/virtio-net-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for VirtIO NIC
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * 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 <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void pci_nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/virtio/net/pci/nop", pci_nop);
+
+ qtest_start("-device virtio-net-pci");
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/vmxnet3-test.c b/tests/vmxnet3-test.c
new file mode 100644
index 0000000..a2ebed3
--- /dev/null
+++ b/tests/vmxnet3-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for vmxnet3 NIC
+ *
+ * Copyright (c) 2013-2014 SUSE LINUX Products GmbH
+ *
+ * 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 <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/vmxnet3/nop", nop);
+
+ qtest_start("-device vmxnet3");
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/tpm.c b/tpm.c
index d68d69f..c371023 100644
--- a/tpm.c
+++ b/tpm.c
@@ -161,7 +161,7 @@ static int configure_tpm(QemuOpts *opts)
/* validate backend specific opts */
qemu_opts_validate(opts, be->opts, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return 1;
diff --git a/trace-events b/trace-events
index ab11f97..3713063 100644
--- a/trace-events
+++ b/trace-events
@@ -495,10 +495,10 @@ qcow2_writev_done_part(void *co, int cur_nr_sectors) "co %p cur_nr_sectors %d"
qcow2_writev_data(void *co, uint64_t offset) "co %p offset %" PRIx64
# block/qcow2-cluster.c
-qcow2_alloc_clusters_offset(void *co, uint64_t offset, int num) "co %p offet %" PRIx64 " num %d"
-qcow2_handle_copied(void *co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) "co %p guest_offet %" PRIx64 " host_offset %" PRIx64 " bytes %" PRIx64
-qcow2_handle_alloc(void *co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) "co %p guest_offet %" PRIx64 " host_offset %" PRIx64 " bytes %" PRIx64
-qcow2_do_alloc_clusters_offset(void *co, uint64_t guest_offset, uint64_t host_offset, int nb_clusters) "co %p guest_offet %" PRIx64 " host_offset %" PRIx64 " nb_clusters %d"
+qcow2_alloc_clusters_offset(void *co, uint64_t offset, int num) "co %p offset %" PRIx64 " num %d"
+qcow2_handle_copied(void *co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " bytes %" PRIx64
+qcow2_handle_alloc(void *co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " bytes %" PRIx64
+qcow2_do_alloc_clusters_offset(void *co, uint64_t guest_offset, uint64_t host_offset, int nb_clusters) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " nb_clusters %d"
qcow2_cluster_alloc_phys(void *co) "co %p"
qcow2_cluster_link_l2(void *co, int nb_clusters) "co %p nb_clusters %d"
diff --git a/trace/Makefile.objs b/trace/Makefile.objs
index 3b88e49..d321946 100644
--- a/trace/Makefile.objs
+++ b/trace/Makefile.objs
@@ -1,6 +1,30 @@
# -*- mode: makefile -*-
######################################################################
+# Auto-generated event descriptions for LTTng ust code
+
+ifeq ($(TRACE_BACKEND),ust)
+$(obj)/generated-ust-provider.h: $(obj)/generated-ust-provider.h-timestamp
+$(obj)/generated-ust-provider.h-timestamp: $(SRC_PATH)/trace-events
+ $(call quiet-command,$(TRACETOOL) \
+ --format=ust-events-h \
+ --backend=$(TRACE_BACKEND) \
+ < $< > $@," GEN $(patsubst %-timestamp,%,$@)")
+ @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
+
+$(obj)/generated-ust.c: $(obj)/generated-ust.c-timestamp $(BUILD_DIR)/config-host.mak
+$(obj)/generated-ust.c-timestamp: $(SRC_PATH)/trace-events
+ $(call quiet-command,$(TRACETOOL) \
+ --format=ust-events-c \
+ --backend=$(TRACE_BACKEND) \
+ < $< > $@," GEN $(patsubst %-timestamp,%,$@)")
+ @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
+
+$(obj)/generated-events.h: $(obj)/generated-ust-provider.h
+$(obj)/generated-events.c: $(obj)/generated-ust.c
+endif
+
+######################################################################
# Auto-generated event descriptions
$(obj)/generated-events.h: $(obj)/generated-events.h-timestamp
@@ -77,5 +101,6 @@ util-obj-$(CONFIG_TRACE_DEFAULT) += default.o
util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o
util-obj-$(CONFIG_TRACE_STDERR) += stderr.o
util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o
+util-obj-$(CONFIG_TRACE_UST) += generated-ust.o
util-obj-y += control.o
util-obj-y += generated-tracers.o
diff --git a/util/qemu-config.c b/util/qemu-config.c
index 9298f55..797df71 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -31,7 +31,7 @@ QemuOptsList *qemu_find_opts(const char *group)
Error *local_err = NULL;
ret = find_list(vm_config_groups, group, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_report("%s", error_get_pretty(local_err));
error_free(local_err);
}
@@ -295,7 +295,7 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname)
if (sscanf(line, "[%63s \"%63[^\"]\"]", group, id) == 2) {
/* group with id */
list = find_list(lists, group, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_report("%s", error_get_pretty(local_err));
error_free(local_err);
goto out;
@@ -306,7 +306,7 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname)
if (sscanf(line, "[%63[^]]]", group) == 1) {
/* group without id */
list = find_list(lists, group, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_report("%s", error_get_pretty(local_err));
error_free(local_err);
goto out;
@@ -376,13 +376,13 @@ static void config_parse_qdict_section(QDict *options, QemuOptsList *opts,
}
subopts = qemu_opts_create(opts, NULL, 0, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
goto out;
}
qemu_opts_absorb_qdict(subopts, subqdict, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
goto out;
}
@@ -416,13 +416,13 @@ static void config_parse_qdict_section(QDict *options, QemuOptsList *opts,
opt_name = g_strdup_printf("%s.%u", opts->name, i++);
subopts = qemu_opts_create(opts, opt_name, 1, &local_err);
g_free(opt_name);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
goto out;
}
qemu_opts_absorb_qdict(subopts, section, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
qemu_opts_del(subopts);
goto out;
@@ -450,7 +450,7 @@ void qemu_config_parse_qdict(QDict *options, QemuOptsList **lists,
for (i = 0; lists[i]; i++) {
config_parse_qdict_section(options, lists[i], &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return;
}
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 668e5d9..fd76cd2 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -246,7 +246,7 @@ int set_option_parameter(QEMUOptionParameter *list, const char *name,
switch (list->type) {
case OPT_FLAG:
parse_option_bool(name, value, &flag, &local_err);
- if (!error_is_set(&local_err)) {
+ if (!local_err) {
list->value.n = flag;
}
break;
@@ -269,7 +269,7 @@ int set_option_parameter(QEMUOptionParameter *list, const char *name,
return -1;
}
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return -1;
@@ -640,7 +640,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value,
opt->desc = desc;
opt->str = g_strdup(value);
qemu_opt_parse(opt, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
qemu_opt_del(opt);
}
@@ -651,7 +651,7 @@ int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
Error *local_err = NULL;
opt_set(opts, name, value, false, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return -1;
@@ -812,7 +812,7 @@ int qemu_opts_set(QemuOptsList *list, const char *id,
Error *local_err = NULL;
opts = qemu_opts_create(list, id, 1, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return -1;
@@ -897,7 +897,7 @@ static int opts_do_parse(QemuOpts *opts, const char *params,
if (strcmp(option, "id") != 0) {
/* store and parse */
opt_set(opts, option, value, prepend, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return -1;
@@ -945,7 +945,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
assert(!defaults || list->merge_lists);
opts = qemu_opts_create(list, id, !defaults, &local_err);
if (opts == NULL) {
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
}
@@ -1034,7 +1034,7 @@ QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1,
&local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return NULL;
}
@@ -1044,7 +1044,7 @@ QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
state.errp = &local_err;
state.opts = opts;
qdict_iter(qdict, qemu_opts_from_qdict_1, &state);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
qemu_opts_del(opts);
return NULL;
@@ -1075,7 +1075,7 @@ void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp)
if (find_desc_by_name(opts->list->desc, entry->key)) {
qemu_opts_from_qdict_1(entry->key, entry->value, &state);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return;
} else {
@@ -1129,7 +1129,7 @@ void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp)
}
qemu_opt_parse(opt, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_propagate(errp, local_err);
return;
}
diff --git a/vl.c b/vl.c
index c1df83d..1d27b34 100644
--- a/vl.c
+++ b/vl.c
@@ -2268,7 +2268,7 @@ static int chardev_init_func(QemuOpts *opts, void *opaque)
Error *local_err = NULL;
qemu_chr_new_from_opts(opts, NULL, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
error_report("%s", error_get_pretty(local_err));
error_free(local_err);
return -1;
@@ -3021,14 +3021,19 @@ int main(int argc, char **argv, char **envp)
goto chs_fail;
if (*p == ',') {
p++;
- if (!strcmp(p, "none"))
+ if (!strcmp(p, "large")) {
+ translation = BIOS_ATA_TRANSLATION_LARGE;
+ } else if (!strcmp(p, "rechs")) {
+ translation = BIOS_ATA_TRANSLATION_RECHS;
+ } else if (!strcmp(p, "none")) {
translation = BIOS_ATA_TRANSLATION_NONE;
- else if (!strcmp(p, "lba"))
+ } else if (!strcmp(p, "lba")) {
translation = BIOS_ATA_TRANSLATION_LBA;
- else if (!strcmp(p, "auto"))
+ } else if (!strcmp(p, "auto")) {
translation = BIOS_ATA_TRANSLATION_AUTO;
- else
+ } else {
goto chs_fail;
+ }
} else if (*p != '\0') {
chs_fail:
fprintf(stderr, "qemu: invalid physical CHS format\n");
@@ -3042,10 +3047,15 @@ int main(int argc, char **argv, char **envp)
qemu_opt_set(hda_opts, "heads", num);
snprintf(num, sizeof(num), "%d", secs);
qemu_opt_set(hda_opts, "secs", num);
- if (translation == BIOS_ATA_TRANSLATION_LBA)
+ if (translation == BIOS_ATA_TRANSLATION_LARGE) {
+ qemu_opt_set(hda_opts, "trans", "large");
+ } else if (translation == BIOS_ATA_TRANSLATION_RECHS) {
+ qemu_opt_set(hda_opts, "trans", "rechs");
+ } else if (translation == BIOS_ATA_TRANSLATION_LBA) {
qemu_opt_set(hda_opts, "trans", "lba");
- if (translation == BIOS_ATA_TRANSLATION_NONE)
+ } else if (translation == BIOS_ATA_TRANSLATION_NONE) {
qemu_opt_set(hda_opts, "trans", "none");
+ }
}
}
break;
@@ -4026,7 +4036,13 @@ int main(int argc, char **argv, char **envp)
configure_accelerator();
if (qtest_chrdev) {
- qtest_init(qtest_chrdev, qtest_log);
+ Error *local_err = NULL;
+ qtest_init(qtest_chrdev, qtest_log, &local_err);
+ if (local_err) {
+ error_report("%s", error_get_pretty(local_err));
+ error_free(local_err);
+ exit(1);
+ }
}
machine_opts = qemu_get_machine_opts();
OpenPOWER on IntegriCloud