aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--VERSION2
-rw-r--r--arch_init.c2
-rw-r--r--audio/audio_win_int.c1
-rw-r--r--audio/ossaudio.c4
-rw-r--r--block/win32-aio.c1
-rw-r--r--blockdev.c280
-rwxr-xr-xconfigure5
-rw-r--r--exec.c68
-rw-r--r--hw/arm/highbank.c1
-rw-r--r--hw/audio/marvell_88w8618.c1
-rw-r--r--hw/block/pflash_cfi01.c6
-rw-r--r--hw/block/pflash_cfi02.c2
-rw-r--r--hw/i386/kvm/pci-assign.c18
-rw-r--r--hw/intc/Makefile.objs2
-rw-r--r--hw/intc/sbi.c156
-rw-r--r--hw/intc/sun4c_intctl.c208
-rw-r--r--hw/mips/mips_malta.c1
-rw-r--r--hw/misc/lm32_sys.c1
-rw-r--r--hw/net/rtl8139.c3
-rw-r--r--hw/net/virtio-net.c99
-rw-r--r--hw/nvram/fw_cfg.c4
-rw-r--r--hw/pci/pci.c2
-rw-r--r--hw/ppc/spapr.c2
-rw-r--r--hw/ppc/spapr_hcall.c1
-rw-r--r--hw/scsi/megasas.c1
-rw-r--r--hw/sparc/sun4m.c463
-rw-r--r--hw/timer/exynos4210_rtc.c1
-rw-r--r--include/block/coroutine_int.h4
-rw-r--r--include/exec/cpu-common.h4
-rw-r--r--include/exec/memory-internal.h1
-rw-r--r--include/exec/memory.h60
-rw-r--r--include/exec/poison.h1
-rw-r--r--include/hw/i386/pc.h5
-rw-r--r--include/hw/virtio/virtio-net.h13
-rw-r--r--include/qapi/qmp/qlist.h1
-rw-r--r--include/qemu-common.h1
-rw-r--r--include/qemu/config-file.h1
-rw-r--r--linux-user/signal.c16
-rw-r--r--linux-user/syscall.c4
-rw-r--r--memory.c64
-rw-r--r--monitor.c1
-rw-r--r--net/tap-bsd.c3
-rw-r--r--page_cache.c1
-rw-r--r--pc-bios/bios.binbin131072 -> 131072 bytes
-rw-r--r--qapi-schema-test.json15
-rw-r--r--qapi-schema.json27
-rw-r--r--qemu-char.c21
-rw-r--r--qemu-coroutine-lock.c56
-rw-r--r--qemu-coroutine.c23
-rw-r--r--qemu-doc.texi10
-rw-r--r--qemu-io.c46
-rw-r--r--qemu-options.hx7
-rw-r--r--qobject/json-parser.c26
-rw-r--r--qom/object.c4
-rwxr-xr-xroms/configure-seabios.sh2
m---------roms/seabios0
-rw-r--r--scripts/qapi-types.py45
-rw-r--r--scripts/qapi-visit.py36
-rw-r--r--scripts/qapi.py23
-rw-r--r--slirp/misc.c2
-rw-r--r--target-arm/translate.c781
-rw-r--r--target-mips/cpu.h1
-rw-r--r--target-mips/dsp_helper.c16
-rw-r--r--target-mips/helper.c4
-rw-r--r--target-moxie/helper.c2
-rw-r--r--target-ppc/kvm.c2
-rw-r--r--target-s390x/cpu.h5
-rw-r--r--target-sparc/cpu.c122
-rwxr-xr-xtests/qemu-iotests/05458
-rw-r--r--tests/qemu-iotests/054.out10
-rw-r--r--tests/qemu-iotests/common.rc2
-rw-r--r--tests/qemu-iotests/group1
-rwxr-xr-xtests/qemu-iotests/qcow2.py17
-rw-r--r--tests/tcg/linux-test.c1
-rw-r--r--tests/test-qmp-input-visitor.c358
-rw-r--r--tests/test-qmp-output-visitor.c332
-rw-r--r--tests/test-visitor-serialization.c476
-rw-r--r--trace-events5
-rw-r--r--translate-all.c3
-rw-r--r--ui/cocoa.m52
-rw-r--r--ui/input.c13
-rw-r--r--vl.c4
83 files changed, 2365 insertions, 1764 deletions
diff --git a/Makefile b/Makefile
index 7dc02042be..9695c9d14d 100644
--- a/Makefile
+++ b/Makefile
@@ -178,7 +178,7 @@ Makefile: $(version-obj-y) $(version-lobj-y)
# Build libraries
libqemustub.a: $(stub-obj-y)
-libqemuutil.a: $(util-obj-y)
+libqemuutil.a: $(util-obj-y) qapi-types.o qapi-visit.o
######################################################################
@@ -215,10 +215,10 @@ $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
qapi-types.c qapi-types.h :\
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "." < $<, " GEN $@")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "." -b < $<, " GEN $@")
qapi-visit.c qapi-visit.h :\
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "." < $<, " GEN $@")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "." -b < $<, " GEN $@")
qmp-commands.h qmp-marshal.c :\
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o "." < $<, " GEN $@")
diff --git a/VERSION b/VERSION
index bc80560fad..88eb60eeb6 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.5.0
+1.5.50
diff --git a/arch_init.c b/arch_init.c
index 49c5dc27e6..5d32ecf23a 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -386,7 +386,7 @@ static void migration_bitmap_sync(void)
}
trace_migration_bitmap_sync_start();
- memory_global_sync_dirty_bitmap(get_system_memory());
+ address_space_sync_dirty_bitmap(&address_space_memory);
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
for (addr = 0; addr < block->length; addr += TARGET_PAGE_SIZE) {
diff --git a/audio/audio_win_int.c b/audio/audio_win_int.c
index 58690524c4..e1324056a4 100644
--- a/audio/audio_win_int.c
+++ b/audio/audio_win_int.c
@@ -1,7 +1,6 @@
/* public domain */
#include "qemu-common.h"
-#include "audio.h"
#define AUDIO_CAP "win-int"
#include <windows.h>
diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 00be9c91e3..007c64115a 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -25,11 +25,7 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/ioctl.h>
-#ifdef __OpenBSD__
-#include <soundcard.h>
-#else
#include <sys/soundcard.h>
-#endif
#include "qemu-common.h"
#include "qemu/main-loop.h"
#include "qemu/host-utils.h"
diff --git a/block/win32-aio.c b/block/win32-aio.c
index 5d0fbbfb7d..fcb7c754da 100644
--- a/block/win32-aio.c
+++ b/block/win32-aio.c
@@ -25,7 +25,6 @@
#include "qemu/timer.h"
#include "block/block_int.h"
#include "qemu/module.h"
-#include "qemu-common.h"
#include "block/aio.h"
#include "raw-aio.h"
#include "qemu/event_notifier.h"
diff --git a/blockdev.c b/blockdev.c
index 7c9d8dd0ac..d1ec99af73 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -750,8 +750,8 @@ void do_commit(Monitor *mon, const QDict *qdict)
static void blockdev_do_action(int kind, void *data, Error **errp)
{
- BlockdevAction action;
- BlockdevActionList list;
+ TransactionAction action;
+ TransactionActionList list;
action.kind = kind;
action.data = data;
@@ -773,27 +773,176 @@ void qmp_blockdev_snapshot_sync(const char *device, const char *snapshot_file,
.has_mode = has_mode,
.mode = mode,
};
- blockdev_do_action(BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC, &snapshot,
- errp);
+ blockdev_do_action(TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC,
+ &snapshot, errp);
}
/* New and old BlockDriverState structs for group snapshots */
-typedef struct BlkTransactionStates {
+
+typedef struct BlkTransactionStates BlkTransactionStates;
+
+/* Only prepare() may fail. In a single transaction, only one of commit() or
+ abort() will be called, clean() will always be called if it present. */
+typedef struct BdrvActionOps {
+ /* Size of state struct, in bytes. */
+ size_t instance_size;
+ /* Prepare the work, must NOT be NULL. */
+ void (*prepare)(BlkTransactionStates *common, Error **errp);
+ /* Commit the changes, must NOT be NULL. */
+ void (*commit)(BlkTransactionStates *common);
+ /* Abort the changes on fail, can be NULL. */
+ void (*abort)(BlkTransactionStates *common);
+ /* Clean up resource in the end, can be NULL. */
+ void (*clean)(BlkTransactionStates *common);
+} BdrvActionOps;
+
+/*
+ * This structure must be arranged as first member in child type, assuming
+ * that compiler will also arrange it to the same address with parent instance.
+ * Later it will be used in free().
+ */
+struct BlkTransactionStates {
+ TransactionAction *action;
+ const BdrvActionOps *ops;
+ QSIMPLEQ_ENTRY(BlkTransactionStates) entry;
+};
+
+/* external snapshot private data */
+typedef struct ExternalSnapshotStates {
+ BlkTransactionStates common;
BlockDriverState *old_bs;
BlockDriverState *new_bs;
- QSIMPLEQ_ENTRY(BlkTransactionStates) entry;
-} BlkTransactionStates;
+} ExternalSnapshotStates;
+
+static void external_snapshot_prepare(BlkTransactionStates *common,
+ Error **errp)
+{
+ BlockDriver *proto_drv;
+ BlockDriver *drv;
+ int flags, ret;
+ Error *local_err = NULL;
+ const char *device;
+ const char *new_image_file;
+ const char *format = "qcow2";
+ enum NewImageMode mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+ ExternalSnapshotStates *states =
+ DO_UPCAST(ExternalSnapshotStates, common, common);
+ TransactionAction *action = common->action;
+
+ /* get parameters */
+ g_assert(action->kind == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC);
+
+ device = action->blockdev_snapshot_sync->device;
+ new_image_file = action->blockdev_snapshot_sync->snapshot_file;
+ if (action->blockdev_snapshot_sync->has_format) {
+ format = action->blockdev_snapshot_sync->format;
+ }
+ if (action->blockdev_snapshot_sync->has_mode) {
+ mode = action->blockdev_snapshot_sync->mode;
+ }
+
+ /* start processing */
+ drv = bdrv_find_format(format);
+ if (!drv) {
+ error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
+ return;
+ }
+
+ states->old_bs = bdrv_find(device);
+ if (!states->old_bs) {
+ error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+ return;
+ }
+
+ if (!bdrv_is_inserted(states->old_bs)) {
+ error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
+ return;
+ }
+
+ if (bdrv_in_use(states->old_bs)) {
+ error_set(errp, QERR_DEVICE_IN_USE, device);
+ return;
+ }
+
+ if (!bdrv_is_read_only(states->old_bs)) {
+ if (bdrv_flush(states->old_bs)) {
+ error_set(errp, QERR_IO_ERROR);
+ return;
+ }
+ }
+
+ flags = states->old_bs->open_flags;
+
+ proto_drv = bdrv_find_protocol(new_image_file);
+ if (!proto_drv) {
+ error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
+ return;
+ }
+
+ /* create new image w/backing file */
+ if (mode != NEW_IMAGE_MODE_EXISTING) {
+ bdrv_img_create(new_image_file, format,
+ states->old_bs->filename,
+ states->old_bs->drv->format_name,
+ NULL, -1, flags, &local_err, false);
+ if (error_is_set(&local_err)) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
+
+ /* We will manually add the backing_hd field to the bs later */
+ states->new_bs = bdrv_new("");
+ /* TODO Inherit bs->options or only take explicit options with an
+ * extended QMP command? */
+ ret = bdrv_open(states->new_bs, new_image_file, NULL,
+ flags | BDRV_O_NO_BACKING, drv);
+ if (ret != 0) {
+ error_set(errp, QERR_OPEN_FILE_FAILED, new_image_file);
+ }
+}
+
+static void external_snapshot_commit(BlkTransactionStates *common)
+{
+ ExternalSnapshotStates *states =
+ DO_UPCAST(ExternalSnapshotStates, common, common);
+
+ /* This removes our old bs from the bdrv_states, and adds the new bs */
+ bdrv_append(states->new_bs, states->old_bs);
+ /* We don't need (or want) to use the transactional
+ * bdrv_reopen_multiple() across all the entries at once, because we
+ * don't want to abort all of them if one of them fails the reopen */
+ bdrv_reopen(states->new_bs, states->new_bs->open_flags & ~BDRV_O_RDWR,
+ NULL);
+}
+
+static void external_snapshot_abort(BlkTransactionStates *common)
+{
+ ExternalSnapshotStates *states =
+ DO_UPCAST(ExternalSnapshotStates, common, common);
+ if (states->new_bs) {
+ bdrv_delete(states->new_bs);
+ }
+}
+
+static const BdrvActionOps actions[] = {
+ [TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC] = {
+ .instance_size = sizeof(ExternalSnapshotStates),
+ .prepare = external_snapshot_prepare,
+ .commit = external_snapshot_commit,
+ .abort = external_snapshot_abort,
+ },
+};
/*
* 'Atomic' group snapshots. The snapshots are taken as a set, and if any fail
* then we do not pivot any of the devices in the group, and abandon the
* snapshots
*/
-void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
+void qmp_transaction(TransactionActionList *dev_list, Error **errp)
{
- int ret = 0;
- BlockdevActionList *dev_entry = dev_list;
+ TransactionActionList *dev_entry = dev_list;
BlkTransactionStates *states, *next;
Error *local_err = NULL;
@@ -805,109 +954,29 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
/* We don't do anything in this loop that commits us to the snapshot */
while (NULL != dev_entry) {
- BlockdevAction *dev_info = NULL;
- BlockDriver *proto_drv;
- BlockDriver *drv;
- int flags;
- enum NewImageMode mode;
- const char *new_image_file;
- const char *device;
- const char *format = "qcow2";
+ TransactionAction *dev_info = NULL;
+ const BdrvActionOps *ops;
dev_info = dev_entry->value;
dev_entry = dev_entry->next;
- states = g_malloc0(sizeof(BlkTransactionStates));
- QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, states, entry);
-
- switch (dev_info->kind) {
- case BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC:
- device = dev_info->blockdev_snapshot_sync->device;
- if (!dev_info->blockdev_snapshot_sync->has_mode) {
- dev_info->blockdev_snapshot_sync->mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
- }
- new_image_file = dev_info->blockdev_snapshot_sync->snapshot_file;
- if (dev_info->blockdev_snapshot_sync->has_format) {
- format = dev_info->blockdev_snapshot_sync->format;
- }
- mode = dev_info->blockdev_snapshot_sync->mode;
- break;
- default:
- abort();
- }
+ assert(dev_info->kind < ARRAY_SIZE(actions));
- drv = bdrv_find_format(format);
- if (!drv) {
- error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
- goto delete_and_fail;
- }
-
- states->old_bs = bdrv_find(device);
- if (!states->old_bs) {
- error_set(errp, QERR_DEVICE_NOT_FOUND, device);
- goto delete_and_fail;
- }
-
- if (!bdrv_is_inserted(states->old_bs)) {
- error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
- goto delete_and_fail;
- }
-
- if (bdrv_in_use(states->old_bs)) {
- error_set(errp, QERR_DEVICE_IN_USE, device);
- goto delete_and_fail;
- }
-
- if (!bdrv_is_read_only(states->old_bs)) {
- if (bdrv_flush(states->old_bs)) {
- error_set(errp, QERR_IO_ERROR);
- goto delete_and_fail;
- }
- }
-
- flags = states->old_bs->open_flags;
-
- proto_drv = bdrv_find_protocol(new_image_file);
- if (!proto_drv) {
- error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
- goto delete_and_fail;
- }
-
- /* create new image w/backing file */
- if (mode != NEW_IMAGE_MODE_EXISTING) {
- bdrv_img_create(new_image_file, format,
- states->old_bs->filename,
- states->old_bs->drv->format_name,
- NULL, -1, flags, &local_err, false);
- if (error_is_set(&local_err)) {
- error_propagate(errp, local_err);
- goto delete_and_fail;
- }
- }
+ ops = &actions[dev_info->kind];
+ states = g_malloc0(ops->instance_size);
+ states->ops = ops;
+ states->action = dev_info;
+ QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, states, entry);
- /* We will manually add the backing_hd field to the bs later */
- states->new_bs = bdrv_new("");
- /* TODO Inherit bs->options or only take explicit options with an
- * extended QMP command? */
- ret = bdrv_open(states->new_bs, new_image_file, NULL,
- flags | BDRV_O_NO_BACKING, drv);
- if (ret != 0) {
- error_set(errp, QERR_OPEN_FILE_FAILED, new_image_file);
+ states->ops->prepare(states, &local_err);
+ if (error_is_set(&local_err)) {
+ error_propagate(errp, local_err);
goto delete_and_fail;
}
}
-
- /* Now we are going to do the actual pivot. Everything up to this point
- * is reversible, but we are committed at this point */
QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) {
- /* This removes our old bs from the bdrv_states, and adds the new bs */
- bdrv_append(states->new_bs, states->old_bs);
- /* We don't need (or want) to use the transactional
- * bdrv_reopen_multiple() across all the entries at once, because we
- * don't want to abort all of them if one of them fails the reopen */
- bdrv_reopen(states->new_bs, states->new_bs->open_flags & ~BDRV_O_RDWR,
- NULL);
+ states->ops->commit(states);
}
/* success */
@@ -919,12 +988,15 @@ delete_and_fail:
* the original bs for all images
*/
QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) {
- if (states->new_bs) {
- bdrv_delete(states->new_bs);
+ if (states->ops->abort) {
+ states->ops->abort(states);
}
}
exit:
QSIMPLEQ_FOREACH_SAFE(states, &snap_bdrv_states, entry, next) {
+ if (states->ops->clean) {
+ states->ops->clean(states);
+ }
g_free(states);
}
}
diff --git a/configure b/configure
index 5ae7e4a348..eb74510940 100755
--- a/configure
+++ b/configure
@@ -468,9 +468,8 @@ NetBSD)
OpenBSD)
bsd="yes"
make="${MAKE-gmake}"
- audio_drv_list="oss"
- audio_possible_drivers="oss sdl esd"
- oss_lib="-lossaudio"
+ audio_drv_list="sdl"
+ audio_possible_drivers="sdl esd"
;;
Darwin)
bsd="yes"
diff --git a/exec.c b/exec.c
index aec65c5063..3a9ddcb41f 100644
--- a/exec.c
+++ b/exec.c
@@ -187,19 +187,15 @@ MemoryRegionSection *phys_page_find(AddressSpaceDispatch *d, hwaddr index)
PhysPageEntry lp = d->phys_map;
PhysPageEntry *p;
int i;
- uint16_t s_index = phys_section_unassigned;
for (i = P_L2_LEVELS - 1; i >= 0 && !lp.is_leaf; i--) {
if (lp.ptr == PHYS_MAP_NODE_NIL) {
- goto not_found;
+ return &phys_sections[phys_section_unassigned];
}
p = phys_map_nodes[lp.ptr];
lp = p[(index >> (i * L2_BITS)) & (L2_SIZE - 1)];
}
-
- s_index = lp.ptr;
-not_found:
- return &phys_sections[s_index];
+ return &phys_sections[lp.ptr];
}
bool memory_region_is_unassigned(MemoryRegion *mr)
@@ -639,12 +635,6 @@ hwaddr memory_region_section_get_iotlb(CPUArchState *env,
iotlb |= phys_section_rom;
}
} else {
- /* IO handlers are currently passed a physical address.
- It would be nice to pass an offset from the base address
- of that region. This would avoid having to special case RAM,
- and avoid full address decoding in every device.
- We can't use the high bits of pd for this because
- IO_MEM_ROMD uses these as a ram address. */
iotlb = section - phys_sections;
iotlb += memory_region_section_addr(section, paddr);
}
@@ -719,6 +709,12 @@ static void destroy_all_mappings(AddressSpaceDispatch *d)
static uint16_t phys_section_add(MemoryRegionSection *section)
{
+ /* The physical section number is ORed with a page-aligned
+ * pointer to produce the iotlb entries. Thus it should
+ * never overflow into the page-aligned value.
+ */
+ assert(phys_sections_nb < TARGET_PAGE_SIZE);
+
if (phys_sections_nb == phys_sections_nb_alloc) {
phys_sections_nb_alloc = MAX(phys_sections_nb_alloc * 2, 16);
phys_sections = g_renew(MemoryRegionSection, phys_sections,
@@ -775,10 +771,21 @@ static void register_multipage(AddressSpaceDispatch *d, MemoryRegionSection *sec
section_index);
}
+QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > MAX_PHYS_ADDR_SPACE_BITS)
+
+static MemoryRegionSection limit(MemoryRegionSection section)
+{
+ section.size = MIN(section.offset_within_address_space + section.size,
+ MAX_PHYS_ADDR + 1)
+ - section.offset_within_address_space;
+
+ return section;
+}
+
static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
{
AddressSpaceDispatch *d = container_of(listener, AddressSpaceDispatch, listener);
- MemoryRegionSection now = *section, remain = *section;
+ MemoryRegionSection now = limit(*section), remain = limit(*section);
if ((now.offset_within_address_space & ~TARGET_PAGE_MASK)
|| (now.size < TARGET_PAGE_SIZE)) {
@@ -1340,11 +1347,6 @@ static void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t *size)
}
}
-void qemu_put_ram_ptr(void *addr)
-{
- trace_qemu_put_ram_ptr(addr);
-}
-
int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
{
RAMBlock *block;
@@ -1934,7 +1936,6 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
ptr = qemu_get_ram_ptr(addr1);
memcpy(ptr, buf, l);
invalidate_and_set_dirty(addr1, l);
- qemu_put_ram_ptr(ptr);
}
} else {
if (!(memory_region_is_ram(section->mr) ||
@@ -1964,7 +1965,6 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
+ memory_region_section_addr(section,
addr));
memcpy(buf, ptr, l);
- qemu_put_ram_ptr(ptr);
}
}
len -= l;
@@ -2026,7 +2026,6 @@ void cpu_physical_memory_write_rom(hwaddr addr,
ptr = qemu_get_ram_ptr(addr1);
memcpy(ptr, buf, l);
invalidate_and_set_dirty(addr1, l);
- qemu_put_ram_ptr(ptr);
}
len -= l;
buf += l;
@@ -2404,33 +2403,6 @@ void stl_phys_notdirty(hwaddr addr, uint32_t val)
}
}
-void stq_phys_notdirty(hwaddr addr, uint64_t val)
-{
- uint8_t *ptr;
- MemoryRegionSection *section;
-
- section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
-
- if (!memory_region_is_ram(section->mr) || section->readonly) {
- addr = memory_region_section_addr(section, addr);
- if (memory_region_is_ram(section->mr)) {
- section = &phys_sections[phys_section_rom];
- }
-#ifdef TARGET_WORDS_BIGENDIAN
- io_mem_write(section->mr, addr, val >> 32, 4);
- io_mem_write(section->mr, addr + 4, (uint32_t)val, 4);
-#else
- io_mem_write(section->mr, addr, (uint32_t)val, 4);
- io_mem_write(section->mr, addr + 4, val >> 32, 4);
-#endif
- } else {
- ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr)
- & TARGET_PAGE_MASK)
- + memory_region_section_addr(section, addr));
- stq_p(ptr, val);
- }
-}
-
/* warning: addr must be aligned */
static inline void stl_phys_internal(hwaddr addr, uint32_t val,
enum device_endian endian)
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 0fd9465cfa..4405dbd3bd 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -24,7 +24,6 @@
#include "net/net.h"
#include "sysemu/sysemu.h"
#include "hw/boards.h"
-#include "hw/sysbus.h"
#include "sysemu/blockdev.h"
#include "exec/address-spaces.h"
diff --git a/hw/audio/marvell_88w8618.c b/hw/audio/marvell_88w8618.c
index de06dfd7d2..c5d88a7841 100644
--- a/hw/audio/marvell_88w8618.c
+++ b/hw/audio/marvell_88w8618.c
@@ -12,7 +12,6 @@
#include "hw/sysbus.h"
#include "hw/hw.h"
#include "hw/i2c/i2c.h"
-#include "hw/sysbus.h"
#include "audio/audio.h"
#define MP_AUDIO_SIZE 0x00001000
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 3ff20e0c6f..63d7c9951f 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -105,7 +105,7 @@ static void pflash_timer (void *opaque)
DPRINTF("%s: command %02x done\n", __func__, pfl->cmd);
/* Reset flash */
pfl->status ^= 0x80;
- memory_region_rom_device_set_readable(&pfl->mem, true);
+ memory_region_rom_device_set_romd(&pfl->mem, true);
pfl->wcycle = 0;
pfl->cmd = 0;
}
@@ -281,7 +281,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
if (!pfl->wcycle) {
/* Set the device in I/O access mode */
- memory_region_rom_device_set_readable(&pfl->mem, false);
+ memory_region_rom_device_set_romd(&pfl->mem, false);
}
switch (pfl->wcycle) {
@@ -458,7 +458,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
"\n", __func__, offset, pfl->wcycle, pfl->cmd, value);
reset_flash:
- memory_region_rom_device_set_readable(&pfl->mem, true);
+ memory_region_rom_device_set_romd(&pfl->mem, true);
pfl->wcycle = 0;
pfl->cmd = 0;
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 9a7fa707ca..5f25246926 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -111,7 +111,7 @@ static void pflash_setup_mappings(pflash_t *pfl)
static void pflash_register_memory(pflash_t *pfl, int rom_mode)
{
- memory_region_rom_device_set_readable(&pfl->orig_mem, rom_mode);
+ memory_region_rom_device_set_romd(&pfl->orig_mem, rom_mode);
pfl->rom_mode = rom_mode;
}
diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index c1e08ec1a0..ff855904ba 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -1026,6 +1026,21 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev)
}
}
+static void assigned_dev_update_msi_msg(PCIDevice *pci_dev)
+{
+ AssignedDevice *assigned_dev = DO_UPCAST(AssignedDevice, dev, pci_dev);
+ uint8_t ctrl_byte = pci_get_byte(pci_dev->config + pci_dev->msi_cap +
+ PCI_MSI_FLAGS);
+
+ if (assigned_dev->assigned_irq_type != ASSIGNED_IRQ_MSI ||
+ !(ctrl_byte & PCI_MSI_FLAGS_ENABLE)) {
+ return;
+ }
+
+ kvm_irqchip_update_msi_route(kvm_state, assigned_dev->msi_virq[0],
+ msi_get_message(pci_dev, 0));
+}
+
static bool assigned_dev_msix_masked(MSIXTableEntry *entry)
{
return (entry->ctrl & cpu_to_le32(0x1)) != 0;
@@ -1201,6 +1216,9 @@ static void assigned_dev_pci_write_config(PCIDevice *pci_dev, uint32_t address,
if (range_covers_byte(address, len,
pci_dev->msi_cap + PCI_MSI_FLAGS)) {
assigned_dev_update_msi(pci_dev);
+ } else if (ranges_overlap(address, len, /* 32bit MSI only */
+ pci_dev->msi_cap + PCI_MSI_ADDRESS_LO, 6)) {
+ assigned_dev_update_msi_msg(pci_dev);
}
}
if (assigned_dev->cap.available & ASSIGNED_DEVICE_CAP_MSIX) {
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 718d97ae8a..3e68d2eba8 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -7,7 +7,7 @@ common-obj-$(CONFIG_ETRAXFS) += etraxfs_pic.o
common-obj-$(CONFIG_IMX) += imx_avic.o
common-obj-$(CONFIG_LM32) += lm32_pic.o
common-obj-$(CONFIG_REALVIEW) += realview_gic.o
-common-obj-$(CONFIG_SLAVIO) += sbi.o slavio_intctl.o sun4c_intctl.o
+common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o
common-obj-$(CONFIG_IOAPIC) += ioapic_common.o
common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o
diff --git a/hw/intc/sbi.c b/hw/intc/sbi.c
deleted file mode 100644
index 8795749de8..0000000000
--- a/hw/intc/sbi.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * QEMU Sparc SBI interrupt controller emulation
- *
- * Based on slavio_intctl, copyright (c) 2003-2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "hw/sysbus.h"
-
-//#define DEBUG_IRQ
-
-#ifdef DEBUG_IRQ
-#define DPRINTF(fmt, ...) \
- do { printf("IRQ: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif
-
-#define MAX_CPUS 16
-
-#define SBI_NREGS 16
-
-typedef struct SBIState {
- SysBusDevice busdev;
- MemoryRegion iomem;
- uint32_t regs[SBI_NREGS];
- uint32_t intreg_pending[MAX_CPUS];
- qemu_irq cpu_irqs[MAX_CPUS];
- uint32_t pil_out[MAX_CPUS];
-} SBIState;
-
-#define SBI_SIZE (SBI_NREGS * 4)
-
-static void sbi_set_irq(void *opaque, int irq, int level)
-{
-}
-
-static uint64_t sbi_mem_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- SBIState *s = opaque;
- uint32_t saddr, ret;
-
- saddr = addr >> 2;
- switch (saddr) {
- default:
- ret = s->regs[saddr];
- break;
- }
- DPRINTF("read system reg 0x" TARGET_FMT_plx " = %x\n", addr, ret);
-
- return ret;
-}
-
-static void sbi_mem_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned dize)
-{
- SBIState *s = opaque;
- uint32_t saddr;
-
- saddr = addr >> 2;
- DPRINTF("write system reg 0x" TARGET_FMT_plx " = %x\n", addr, (int)val);
- switch (saddr) {
- default:
- s->regs[saddr] = val;
- break;
- }
-}
-
-static const MemoryRegionOps sbi_mem_ops = {
- .read = sbi_mem_read,
- .write = sbi_mem_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-static const VMStateDescription vmstate_sbi = {
- .name ="sbi",
- .version_id = 1,
- .minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField []) {
- VMSTATE_UINT32_ARRAY(intreg_pending, SBIState, MAX_CPUS),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void sbi_reset(DeviceState *d)
-{
- SBIState *s = container_of(d, SBIState, busdev.qdev);
- unsigned int i;
-
- for (i = 0; i < MAX_CPUS; i++) {
- s->intreg_pending[i] = 0;
- }
-}
-
-static int sbi_init1(SysBusDevice *dev)
-{
- SBIState *s = FROM_SYSBUS(SBIState, dev);
- unsigned int i;
-
- qdev_init_gpio_in(&dev->qdev, sbi_set_irq, 32 + MAX_CPUS);
- for (i = 0; i < MAX_CPUS; i++) {
- sysbus_init_irq(dev, &s->cpu_irqs[i]);
- }
-
- memory_region_init_io(&s->iomem, &sbi_mem_ops, s, "sbi", SBI_SIZE);
- sysbus_init_mmio(dev, &s->iomem);
-
- return 0;
-}
-
-static void sbi_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = sbi_init1;
- dc->reset = sbi_reset;
- dc->vmsd = &vmstate_sbi;
-}
-
-static const TypeInfo sbi_info = {
- .name = "sbi",
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(SBIState),
- .class_init = sbi_class_init,
-};
-
-static void sbi_register_types(void)
-{
- type_register_static(&sbi_info);
-}
-
-type_init(sbi_register_types)
diff --git a/hw/intc/sun4c_intctl.c b/hw/intc/sun4c_intctl.c
deleted file mode 100644
index 1096375670..0000000000
--- a/hw/intc/sun4c_intctl.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * QEMU Sparc Sun4c interrupt controller emulation
- *
- * Based on slavio_intctl, copyright (c) 2003-2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "hw/hw.h"
-#include "hw/sparc/sun4m.h"
-#include "monitor/monitor.h"
-#include "hw/sysbus.h"
-
-//#define DEBUG_IRQ_COUNT
-//#define DEBUG_IRQ
-
-#ifdef DEBUG_IRQ
-#define DPRINTF(fmt, ...) \
- do { printf("IRQ: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif
-
-/*
- * Registers of interrupt controller in sun4c.
- *
- */
-
-#define MAX_PILS 16
-
-typedef struct Sun4c_INTCTLState {
- SysBusDevice busdev;
- MemoryRegion iomem;
-#ifdef DEBUG_IRQ_COUNT
- uint64_t irq_count;
-#endif
- qemu_irq cpu_irqs[MAX_PILS];
- const uint32_t *intbit_to_level;
- uint32_t pil_out;
- uint8_t reg;
- uint8_t pending;
-} Sun4c_INTCTLState;
-
-#define INTCTL_SIZE 1
-
-static void sun4c_check_interrupts(void *opaque);
-
-static uint64_t sun4c_intctl_mem_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- Sun4c_INTCTLState *s = opaque;
- uint32_t ret;
-
- ret = s->reg;
- DPRINTF("read reg 0x" TARGET_FMT_plx " = %x\n", addr, ret);
-
- return ret;
-}
-
-static void sun4c_intctl_mem_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- Sun4c_INTCTLState *s = opaque;
-
- DPRINTF("write reg 0x" TARGET_FMT_plx " = %x\n", addr, (unsigned)val);
- val &= 0xbf;
- s->reg = val;
- sun4c_check_interrupts(s);
-}
-
-static const MemoryRegionOps sun4c_intctl_mem_ops = {
- .read = sun4c_intctl_mem_read,
- .write = sun4c_intctl_mem_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 1,
- .max_access_size = 1,
- },
-};
-
-static const uint32_t intbit_to_level[] = { 0, 1, 4, 6, 8, 10, 0, 14, };
-
-static void sun4c_check_interrupts(void *opaque)
-{
- Sun4c_INTCTLState *s = opaque;
- uint32_t pil_pending;
- unsigned int i;
-
- pil_pending = 0;
- if (s->pending && !(s->reg & 0x80000000)) {
- for (i = 0; i < 8; i++) {
- if (s->pending & (1 << i))
- pil_pending |= 1 << intbit_to_level[i];
- }
- }
-
- for (i = 0; i < MAX_PILS; i++) {
- if (pil_pending & (1 << i)) {
- if (!(s->pil_out & (1 << i)))
- qemu_irq_raise(s->cpu_irqs[i]);
- } else {
- if (s->pil_out & (1 << i))
- qemu_irq_lower(s->cpu_irqs[i]);
- }
- }
- s->pil_out = pil_pending;
-}
-
-/*
- * "irq" here is the bit number in the system interrupt register
- */
-static void sun4c_set_irq(void *opaque, int irq, int level)
-{
- Sun4c_INTCTLState *s = opaque;
- uint32_t mask = 1 << irq;
- uint32_t pil = intbit_to_level[irq];
-
- DPRINTF("Set irq %d -> pil %d level %d\n", irq, pil,
- level);
- if (pil > 0) {
- if (level) {
-#ifdef DEBUG_IRQ_COUNT
- s->irq_count++;
-#endif
- s->pending |= mask;
- } else {
- s->pending &= ~mask;
- }
- sun4c_check_interrupts(s);
- }
-}
-
-static const VMStateDescription vmstate_sun4c_intctl = {
- .name ="sun4c_intctl",
- .version_id = 1,
- .minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField []) {
- VMSTATE_UINT8(reg, Sun4c_INTCTLState),
- VMSTATE_UINT8(pending, Sun4c_INTCTLState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void sun4c_intctl_reset(DeviceState *d)
-{
- Sun4c_INTCTLState *s = container_of(d, Sun4c_INTCTLState, busdev.qdev);
-
- s->reg = 1;
- s->pending = 0;
-}
-
-static int sun4c_intctl_init1(SysBusDevice *dev)
-{
- Sun4c_INTCTLState *s = FROM_SYSBUS(Sun4c_INTCTLState, dev);
- unsigned int i;
-
- memory_region_init_io(&s->iomem, &sun4c_intctl_mem_ops, s,
- "intctl", INTCTL_SIZE);
- sysbus_init_mmio(dev, &s->iomem);
- qdev_init_gpio_in(&dev->qdev, sun4c_set_irq, 8);
-
- for (i = 0; i < MAX_PILS; i++) {
- sysbus_init_irq(dev, &s->cpu_irqs[i]);
- }
-
- return 0;
-}
-
-static void sun4c_intctl_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = sun4c_intctl_init1;
- dc->reset = sun4c_intctl_reset;
- dc->vmsd = &vmstate_sun4c_intctl;
-}
-
-static const TypeInfo sun4c_intctl_info = {
- .name = "sun4c_intctl",
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(Sun4c_INTCTLState),
- .class_init = sun4c_intctl_class_init,
-};
-
-static void sun4c_intctl_register_types(void)
-{
- type_register_static(&sun4c_intctl_info);
-}
-
-type_init(sun4c_intctl_register_types)
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 9d521ccb19..5033d51224 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -37,7 +37,6 @@
#include "sysemu/char.h"
#include "sysemu/sysemu.h"
#include "sysemu/arch_init.h"
-#include "hw/boards.h"
#include "qemu/log.h"
#include "hw/mips/bios.h"
#include "hw/ide.h"
diff --git a/hw/misc/lm32_sys.c b/hw/misc/lm32_sys.c
index 33a3b80ce7..aeaf2b7b7b 100644
--- a/hw/misc/lm32_sys.c
+++ b/hw/misc/lm32_sys.c
@@ -34,7 +34,6 @@
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "sysemu/sysemu.h"
-#include "qemu/log.h"
enum {
R_CTRL = 0,
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 9369507422..7993f9f5b9 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -2575,6 +2575,9 @@ static void rtl8139_RxBufPtr_write(RTL8139State *s, uint32_t val)
/* this value is off by 16 */
s->RxBufPtr = MOD2(val + 0x10, s->RxBufferSize);
+ /* more buffer space may be available so try to receive */
+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
+
DPRINTF(" CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n",
s->RxBufferSize, s->RxBufAddr, s->RxBufPtr);
}
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index bed0822f0a..1ea95564a5 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -359,6 +359,34 @@ static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
return features;
}
+static void virtio_net_apply_guest_offloads(VirtIONet *n)
+{
+ tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer,
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_CSUM)),
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)),
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)),
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_ECN)),
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)));
+}
+
+static uint64_t virtio_net_guest_offloads_by_features(uint32_t features)
+{
+ static const uint64_t guest_offloads_mask =
+ (1ULL << VIRTIO_NET_F_GUEST_CSUM) |
+ (1ULL << VIRTIO_NET_F_GUEST_TSO4) |
+ (1ULL << VIRTIO_NET_F_GUEST_TSO6) |
+ (1ULL << VIRTIO_NET_F_GUEST_ECN) |
+ (1ULL << VIRTIO_NET_F_GUEST_UFO);
+
+ return guest_offloads_mask & features;
+}
+
+static inline uint64_t virtio_net_supported_guest_offloads(VirtIONet *n)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(n);
+ return virtio_net_guest_offloads_by_features(vdev->guest_features);
+}
+
static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
{
VirtIONet *n = VIRTIO_NET(vdev);
@@ -369,12 +397,9 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
virtio_net_set_mrg_rx_bufs(n, !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF)));
if (n->has_vnet_hdr) {
- tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer,
- (features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
- (features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
- (features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
- (features >> VIRTIO_NET_F_GUEST_ECN) & 1,
- (features >> VIRTIO_NET_F_GUEST_UFO) & 1);
+ n->curr_guest_offloads =
+ virtio_net_guest_offloads_by_features(features);
+ virtio_net_apply_guest_offloads(n);
}
for (i = 0; i < n->max_queues; i++) {
@@ -420,6 +445,43 @@ static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd,
return VIRTIO_NET_OK;
}
+static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
+ struct iovec *iov, unsigned int iov_cnt)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(n);
+ uint64_t offloads;
+ size_t s;
+
+ if (!((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features)) {
+ return VIRTIO_NET_ERR;
+ }
+
+ s = iov_to_buf(iov, iov_cnt, 0, &offloads, sizeof(offloads));
+ if (s != sizeof(offloads)) {
+ return VIRTIO_NET_ERR;
+ }
+
+ if (cmd == VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET) {
+ uint64_t supported_offloads;
+
+ if (!n->has_vnet_hdr) {
+ return VIRTIO_NET_ERR;
+ }
+
+ supported_offloads = virtio_net_supported_guest_offloads(n);
+ if (offloads & ~supported_offloads) {
+ return VIRTIO_NET_ERR;
+ }
+
+ n->curr_guest_offloads = offloads;
+ virtio_net_apply_guest_offloads(n);
+
+ return VIRTIO_NET_OK;
+ } else {
+ return VIRTIO_NET_ERR;
+ }
+}
+
static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd,
struct iovec *iov, unsigned int iov_cnt)
{
@@ -590,6 +652,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
status = virtio_net_handle_vlan_table(n, ctrl.cmd, iov, iov_cnt);
} else if (ctrl.class == VIRTIO_NET_CTRL_MQ) {
status = virtio_net_handle_mq(n, ctrl.cmd, iov, iov_cnt);
+ } else if (ctrl.class == VIRTIO_NET_CTRL_GUEST_OFFLOADS) {
+ status = virtio_net_handle_offloads(n, ctrl.cmd, iov, iov_cnt);
}
s = iov_from_buf(elem.in_sg, elem.in_num, 0, &status, sizeof(status));
@@ -1110,6 +1174,10 @@ static void virtio_net_save(QEMUFile *f, void *opaque)
qemu_put_be32(f, n->vqs[i].tx_waiting);
}
}
+
+ if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
+ qemu_put_be64(f, n->curr_guest_offloads);
+ }
}
static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
@@ -1167,15 +1235,6 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
error_report("virtio-net: saved image requires vnet_hdr=on");
return -1;
}
-
- if (n->has_vnet_hdr) {
- tap_set_offload(qemu_get_queue(n->nic)->peer,
- (vdev->guest_features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
- (vdev->guest_features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
- (vdev->guest_features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
- (vdev->guest_features >> VIRTIO_NET_F_GUEST_ECN) & 1,
- (vdev->guest_features >> VIRTIO_NET_F_GUEST_UFO) & 1);
- }
}
if (version_id >= 9) {
@@ -1209,6 +1268,16 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
}
}
+ if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
+ n->curr_guest_offloads = qemu_get_be64(f);
+ } else {
+ n->curr_guest_offloads = virtio_net_supported_guest_offloads(n);
+ }
+
+ if (peer_has_vnet_hdr(n)) {
+ virtio_net_apply_guest_offloads(n);
+ }
+
virtio_net_set_queues(n);
/* Find the first multicast entry in the saved MAC filter */
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 1a7e49c132..479113bd81 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -54,7 +54,7 @@ struct FWCfgState {
#define JPG_FILE 0
#define BMP_FILE 1
-static char *read_splashfile(char *filename, size_t *file_sizep,
+static char *read_splashfile(char *filename, gsize *file_sizep,
int *file_typep)
{
GError *err = NULL;
@@ -112,7 +112,7 @@ static void fw_cfg_bootsplash(FWCfgState *s)
const char *boot_splash_filename = NULL;
char *p;
char *filename, *file_data;
- size_t file_size;
+ gsize file_size;
int file_type;
const char *temp;
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index d5257ed4c5..bb3879bd88 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1959,8 +1959,6 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
pci_patch_ids(pdev, ptr, size);
}
- qemu_put_ram_ptr(ptr);
-
pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
return 0;
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index c96ac8131f..218ea23da8 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -43,8 +43,6 @@
#include "hw/ppc/xics.h"
#include "hw/pci/msi.h"
-#include "sysemu/kvm.h"
-#include "kvm_ppc.h"
#include "hw/pci/pci.h"
#include "exec/address-spaces.h"
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index f518aee216..8f0b7e8076 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1,6 +1,5 @@
#include "sysemu/sysemu.h"
#include "cpu.h"
-#include "sysemu/sysemu.h"
#include "helper_regs.h"
#include "hw/ppc/spapr.h"
#include "mmu-hash64.h"
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 4934a815ce..fe6550ca54 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -711,7 +711,6 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
ptr = memory_region_get_ram_ptr(&s->dev.rom);
memcpy(biosver, ptr + 0x41, 31);
- qemu_put_ram_ptr(ptr);
memcpy(info.image_component[1].name, "BIOS", 4);
memcpy(info.image_component[1].version, biosver,
strlen((const char *)biosver));
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 635115f097..884088150b 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -55,18 +55,6 @@
* SPARCstation 20/xx, SPARCserver 20
* SPARCstation 4
*
- * Sun4d architecture was used in the following machines:
- *
- * SPARCcenter 2000
- * SPARCserver 1000
- *
- * Sun4c architecture was used in the following machines:
- * SPARCstation 1/1+, SPARCserver 1/1+
- * SPARCstation SLC
- * SPARCstation IPC
- * SPARCstation ELC
- * SPARCstation IPX
- *
* See for example: http://www.sunhelp.org/faq/sunref1.html
*/
@@ -104,36 +92,6 @@ struct sun4m_hwdef {
uint8_t nvram_machine_id;
};
-#define MAX_IOUNITS 5
-
-struct sun4d_hwdef {
- hwaddr iounit_bases[MAX_IOUNITS], slavio_base;
- hwaddr counter_base, nvram_base, ms_kb_base;
- hwaddr serial_base;
- hwaddr espdma_base, esp_base;
- hwaddr ledma_base, le_base;
- hwaddr tcx_base;
- hwaddr sbi_base;
- uint64_t max_mem;
- const char * const default_cpu_model;
- uint32_t iounit_version;
- uint16_t machine_id;
- uint8_t nvram_machine_id;
-};
-
-struct sun4c_hwdef {
- hwaddr iommu_base, slavio_base;
- hwaddr intctl_base, counter_base, nvram_base, ms_kb_base;
- hwaddr serial_base, fd_base;
- hwaddr idreg_base, dma_base, esp_base, le_base;
- hwaddr tcx_base, aux1_base;
- uint64_t max_mem;
- const char * const default_cpu_model;
- uint32_t iommu_version;
- uint16_t machine_id;
- uint8_t nvram_machine_id;
-};
-
int DMA_get_channel_mode (int nchan)
{
return 0;
@@ -1052,7 +1010,6 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
}
enum {
- ss2_id = 0,
ss5_id = 32,
vger_id,
lx_id,
@@ -1062,8 +1019,6 @@ enum {
ss10_id = 64,
ss20_id,
ss600mp_id,
- ss1000_id = 96,
- ss2000_id,
};
static const struct sun4m_hwdef sun4m_hwdefs[] = {
@@ -1504,417 +1459,6 @@ static QEMUMachine sbook_machine = {
DEFAULT_MACHINE_OPTIONS,
};
-static const struct sun4d_hwdef sun4d_hwdefs[] = {
- /* SS-1000 */
- {
- .iounit_bases = {
- 0xfe0200000ULL,
- 0xfe1200000ULL,
- 0xfe2200000ULL,
- 0xfe3200000ULL,
- -1,
- },
- .tcx_base = 0x820000000ULL,
- .slavio_base = 0xf00000000ULL,
- .ms_kb_base = 0xf00240000ULL,
- .serial_base = 0xf00200000ULL,
- .nvram_base = 0xf00280000ULL,
- .counter_base = 0xf00300000ULL,
- .espdma_base = 0x800081000ULL,
- .esp_base = 0x800080000ULL,
- .ledma_base = 0x800040000ULL,
- .le_base = 0x800060000ULL,
- .sbi_base = 0xf02800000ULL,
- .nvram_machine_id = 0x80,
- .machine_id = ss1000_id,
- .iounit_version = 0x03000000,
- .max_mem = 0xf00000000ULL,
- .default_cpu_model = "TI SuperSparc II",
- },
- /* SS-2000 */
- {
- .iounit_bases = {
- 0xfe0200000ULL,
- 0xfe1200000ULL,
- 0xfe2200000ULL,
- 0xfe3200000ULL,
- 0xfe4200000ULL,
- },
- .tcx_base = 0x820000000ULL,
- .slavio_base = 0xf00000000ULL,
- .ms_kb_base = 0xf00240000ULL,
- .serial_base = 0xf00200000ULL,
- .nvram_base = 0xf00280000ULL,
- .counter_base = 0xf00300000ULL,
- .espdma_base = 0x800081000ULL,
- .esp_base = 0x800080000ULL,
- .ledma_base = 0x800040000ULL,
- .le_base = 0x800060000ULL,
- .sbi_base = 0xf02800000ULL,
- .nvram_machine_id = 0x80,
- .machine_id = ss2000_id,
- .iounit_version = 0x03000000,
- .max_mem = 0xf00000000ULL,
- .default_cpu_model = "TI SuperSparc II",
- },
-};
-
-static DeviceState *sbi_init(hwaddr addr, qemu_irq **parent_irq)
-{
- DeviceState *dev;
- SysBusDevice *s;
- unsigned int i;
-
- dev = qdev_create(NULL, "sbi");
- qdev_init_nofail(dev);
-
- s = SYS_BUS_DEVICE(dev);
-
- for (i = 0; i < MAX_CPUS; i++) {
- sysbus_connect_irq(s, i, *parent_irq[i]);
- }
-
- sysbus_mmio_map(s, 0, addr);
-
- return dev;
-}
-
-static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
- const char *boot_device,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename, const char *cpu_model)
-{
- unsigned int i;
- void *iounits[MAX_IOUNITS], *espdma, *ledma, *nvram;
- qemu_irq *cpu_irqs[MAX_CPUS], sbi_irq[32], sbi_cpu_irq[MAX_CPUS],
- espdma_irq, ledma_irq;
- qemu_irq esp_reset, dma_enable;
- unsigned long kernel_size;
- void *fw_cfg;
- DeviceState *dev;
-
- /* init CPUs */
- if (!cpu_model)
- cpu_model = hwdef->default_cpu_model;
-
- for(i = 0; i < smp_cpus; i++) {
- cpu_devinit(cpu_model, i, hwdef->slavio_base, &cpu_irqs[i]);
- }
-
- for (i = smp_cpus; i < MAX_CPUS; i++)
- cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
-
- /* set up devices */
- ram_init(0, RAM_size, hwdef->max_mem);
-
- prom_init(hwdef->slavio_base, bios_name);
-
- dev = sbi_init(hwdef->sbi_base, cpu_irqs);
-
- for (i = 0; i < 32; i++) {
- sbi_irq[i] = qdev_get_gpio_in(dev, i);
- }
- for (i = 0; i < MAX_CPUS; i++) {
- sbi_cpu_irq[i] = qdev_get_gpio_in(dev, 32 + i);
- }
-
- for (i = 0; i < MAX_IOUNITS; i++)
- if (hwdef->iounit_bases[i] != (hwaddr)-1)
- iounits[i] = iommu_init(hwdef->iounit_bases[i],
- hwdef->iounit_version,
- sbi_irq[0]);
-
- espdma = sparc32_dma_init(hwdef->espdma_base, sbi_irq[3],
- iounits[0], &espdma_irq, 0);
-
- /* should be lebuffer instead */
- ledma = sparc32_dma_init(hwdef->ledma_base, sbi_irq[4],
- iounits[0], &ledma_irq, 0);
-
- if (graphic_depth != 8 && graphic_depth != 24) {
- fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
- exit (1);
- }
- tcx_init(hwdef->tcx_base, 0x00100000, graphic_width, graphic_height,
- graphic_depth);
-
- lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq);
-
- nvram = m48t59_init(sbi_irq[0], hwdef->nvram_base, 0, 0x2000, 8);
-
- slavio_timer_init_all(hwdef->counter_base, sbi_irq[10], sbi_cpu_irq, smp_cpus);
-
- slavio_serial_ms_kbd_init(hwdef->ms_kb_base, sbi_irq[12],
- display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
- /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
- Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
- escc_init(hwdef->serial_base, sbi_irq[12], sbi_irq[12],
- serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
-
- if (drive_get_max_bus(IF_SCSI) > 0) {
- fprintf(stderr, "qemu: too many SCSI bus\n");
- exit(1);
- }
-
- esp_init(hwdef->esp_base, 2,
- espdma_memory_read, espdma_memory_write,
- espdma, espdma_irq, &esp_reset, &dma_enable);
-
- qdev_connect_gpio_out(espdma, 0, esp_reset);
- qdev_connect_gpio_out(espdma, 1, dma_enable);
-
- kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
- RAM_size);
-
- nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
- boot_device, RAM_size, kernel_size, graphic_width,
- graphic_height, graphic_depth, hwdef->nvram_machine_id,
- "Sun4d");
-
- fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
- fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
- fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
- fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
- fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
- fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth);
- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
- if (kernel_cmdline) {
- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
- pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
- fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
- } else {
- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
- }
- fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
- fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used
- fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_device[0]);
- qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
-}
-
-/* SPARCserver 1000 hardware initialisation */
-static void ss1000_init(QEMUMachineInitArgs *args)
-{
- ram_addr_t RAM_size = args->ram_size;
- const char *cpu_model = args->cpu_model;
- const char *kernel_filename = args->kernel_filename;
- const char *kernel_cmdline = args->kernel_cmdline;
- const char *initrd_filename = args->initrd_filename;
- const char *boot_device = args->boot_device;
- sun4d_hw_init(&sun4d_hwdefs[0], RAM_size, boot_device, kernel_filename,
- kernel_cmdline, initrd_filename, cpu_model);
-}
-
-/* SPARCcenter 2000 hardware initialisation */
-static void ss2000_init(QEMUMachineInitArgs *args)
-{
- ram_addr_t RAM_size = args->ram_size;
- const char *cpu_model = args->cpu_model;
- const char *kernel_filename = args->kernel_filename;
- const char *kernel_cmdline = args->kernel_cmdline;
- const char *initrd_filename = args->initrd_filename;
- const char *boot_device = args->boot_device;
- sun4d_hw_init(&sun4d_hwdefs[1], RAM_size, boot_device, kernel_filename,
- kernel_cmdline, initrd_filename, cpu_model);
-}
-
-static QEMUMachine ss1000_machine = {
- .name = "SS-1000",
- .desc = "Sun4d platform, SPARCserver 1000",
- .init = ss1000_init,
- .block_default_type = IF_SCSI,
- .max_cpus = 8,
- DEFAULT_MACHINE_OPTIONS,
-};
-
-static QEMUMachine ss2000_machine = {
- .name = "SS-2000",
- .desc = "Sun4d platform, SPARCcenter 2000",
- .init = ss2000_init,
- .block_default_type = IF_SCSI,
- .max_cpus = 20,
- DEFAULT_MACHINE_OPTIONS,
-};
-
-static const struct sun4c_hwdef sun4c_hwdefs[] = {
- /* SS-2 */
- {
- .iommu_base = 0xf8000000,
- .tcx_base = 0xfe000000,
- .slavio_base = 0xf6000000,
- .intctl_base = 0xf5000000,
- .counter_base = 0xf3000000,
- .ms_kb_base = 0xf0000000,
- .serial_base = 0xf1000000,
- .nvram_base = 0xf2000000,
- .fd_base = 0xf7200000,
- .dma_base = 0xf8400000,
- .esp_base = 0xf8800000,
- .le_base = 0xf8c00000,
- .aux1_base = 0xf7400003,
- .nvram_machine_id = 0x55,
- .machine_id = ss2_id,
- .max_mem = 0x10000000,
- .default_cpu_model = "Cypress CY7C601",
- },
-};
-
-static DeviceState *sun4c_intctl_init(hwaddr addr,
- qemu_irq *parent_irq)
-{
- DeviceState *dev;
- SysBusDevice *s;
- unsigned int i;
-
- dev = qdev_create(NULL, "sun4c_intctl");
- qdev_init_nofail(dev);
-
- s = SYS_BUS_DEVICE(dev);
-
- for (i = 0; i < MAX_PILS; i++) {
- sysbus_connect_irq(s, i, parent_irq[i]);
- }
- sysbus_mmio_map(s, 0, addr);
-
- return dev;
-}
-
-static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
- const char *boot_device,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename, const char *cpu_model)
-{
- void *iommu, *espdma, *ledma, *nvram;
- qemu_irq *cpu_irqs, slavio_irq[8], espdma_irq, ledma_irq;
- qemu_irq esp_reset, dma_enable;
- qemu_irq fdc_tc;
- unsigned long kernel_size;
- DriveInfo *fd[MAX_FD];
- void *fw_cfg;
- DeviceState *dev;
- unsigned int i;
-
- /* init CPU */
- if (!cpu_model)
- cpu_model = hwdef->default_cpu_model;
-
- cpu_devinit(cpu_model, 0, hwdef->slavio_base, &cpu_irqs);
-
- /* set up devices */
- ram_init(0, RAM_size, hwdef->max_mem);
-
- prom_init(hwdef->slavio_base, bios_name);
-
- dev = sun4c_intctl_init(hwdef->intctl_base, cpu_irqs);
-
- for (i = 0; i < 8; i++) {
- slavio_irq[i] = qdev_get_gpio_in(dev, i);
- }
-
- iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,
- slavio_irq[1]);
-
- espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[2],
- iommu, &espdma_irq, 0);
-
- ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
- slavio_irq[3], iommu, &ledma_irq, 1);
-
- if (graphic_depth != 8 && graphic_depth != 24) {
- fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
- exit (1);
- }
- tcx_init(hwdef->tcx_base, 0x00100000, graphic_width, graphic_height,
- graphic_depth);
-
- lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq);
-
- nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, 0x800, 2);
-
- slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[1],
- display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
- /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
- Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
- escc_init(hwdef->serial_base, slavio_irq[1],
- slavio_irq[1], serial_hds[0], serial_hds[1],
- ESCC_CLOCK, 1);
-
- if (hwdef->fd_base != (hwaddr)-1) {
- /* there is zero or one floppy drive */
- memset(fd, 0, sizeof(fd));
- fd[0] = drive_get(IF_FLOPPY, 0, 0);
- sun4m_fdctrl_init(slavio_irq[1], hwdef->fd_base, fd,
- &fdc_tc);
- } else {
- fdc_tc = *qemu_allocate_irqs(dummy_fdc_tc, NULL, 1);
- }
-
- slavio_misc_init(0, hwdef->aux1_base, 0, slavio_irq[1], fdc_tc);
-
- if (drive_get_max_bus(IF_SCSI) > 0) {
- fprintf(stderr, "qemu: too many SCSI bus\n");
- exit(1);
- }
-
- esp_init(hwdef->esp_base, 2,
- espdma_memory_read, espdma_memory_write,
- espdma, espdma_irq, &esp_reset, &dma_enable);
-
- qdev_connect_gpio_out(espdma, 0, esp_reset);
- qdev_connect_gpio_out(espdma, 1, dma_enable);
-
- kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
- RAM_size);
-
- nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
- boot_device, RAM_size, kernel_size, graphic_width,
- graphic_height, graphic_depth, hwdef->nvram_machine_id,
- "Sun4c");
-
- fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
- fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
- fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
- fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
- fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
- fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth);
- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
- if (kernel_cmdline) {
- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
- pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
- fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
- } else {
- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
- }
- fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
- fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used
- fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_device[0]);
- qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
-}
-
-/* SPARCstation 2 hardware initialisation */
-static void ss2_init(QEMUMachineInitArgs *args)
-{
- ram_addr_t RAM_size = args->ram_size;
- const char *cpu_model = args->cpu_model;
- const char *kernel_filename = args->kernel_filename;
- const char *kernel_cmdline = args->kernel_cmdline;
- const char *initrd_filename = args->initrd_filename;
- const char *boot_device = args->boot_device;
- sun4c_hw_init(&sun4c_hwdefs[0], RAM_size, boot_device, kernel_filename,
- kernel_cmdline, initrd_filename, cpu_model);
-}
-
-static QEMUMachine ss2_machine = {
- .name = "SS-2",
- .desc = "Sun4c platform, SPARCstation 2",
- .init = ss2_init,
- .block_default_type = IF_SCSI,
- DEFAULT_MACHINE_OPTIONS,
-};
-
static void sun4m_register_types(void)
{
type_register_static(&idreg_info);
@@ -1923,7 +1467,7 @@ static void sun4m_register_types(void)
type_register_static(&ram_info);
}
-static void ss2_machine_init(void)
+static void sun4m_machine_init(void)
{
qemu_register_machine(&ss5_machine);
qemu_register_machine(&ss10_machine);
@@ -1934,10 +1478,7 @@ static void ss2_machine_init(void)
qemu_register_machine(&ss4_machine);
qemu_register_machine(&scls_machine);
qemu_register_machine(&sbook_machine);
- qemu_register_machine(&ss1000_machine);
- qemu_register_machine(&ss2000_machine);
- qemu_register_machine(&ss2_machine);
}
type_init(sun4m_register_types)
-machine_init(ss2_machine_init);
+machine_init(sun4m_machine_init);
diff --git a/hw/timer/exynos4210_rtc.c b/hw/timer/exynos4210_rtc.c
index bceee44cb2..3ac77f9262 100644
--- a/hw/timer/exynos4210_rtc.c
+++ b/hw/timer/exynos4210_rtc.c
@@ -31,7 +31,6 @@
#include "hw/ptimer.h"
#include "hw/hw.h"
-#include "qemu/timer.h"
#include "sysemu/sysemu.h"
#include "hw/arm/exynos4210.h"
diff --git a/include/block/coroutine_int.h b/include/block/coroutine_int.h
index 17eb71e723..f133d65af8 100644
--- a/include/block/coroutine_int.h
+++ b/include/block/coroutine_int.h
@@ -38,6 +38,9 @@ struct Coroutine {
void *entry_arg;
Coroutine *caller;
QSLIST_ENTRY(Coroutine) pool_next;
+
+ /* Coroutines that should be woken up when we yield or terminate */
+ QTAILQ_HEAD(, Coroutine) co_queue_wakeup;
QTAILQ_ENTRY(Coroutine) co_queue_next;
};
@@ -45,5 +48,6 @@ Coroutine *qemu_coroutine_new(void);
void qemu_coroutine_delete(Coroutine *co);
CoroutineAction qemu_coroutine_switch(Coroutine *from, Coroutine *to,
CoroutineAction action);
+void coroutine_fn qemu_co_queue_run_restart(Coroutine *co);
#endif
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 2e5f11f47f..af5258d414 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -49,9 +49,6 @@ typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value);
typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
-/* This should only be used for ram local to a device. */
-void *qemu_get_ram_ptr(ram_addr_t addr);
-void qemu_put_ram_ptr(void *addr);
/* This should not be used by devices. */
int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
@@ -105,7 +102,6 @@ uint32_t lduw_phys(hwaddr addr);
uint32_t ldl_phys(hwaddr addr);
uint64_t ldq_phys(hwaddr addr);
void stl_phys_notdirty(hwaddr addr, uint32_t val);
-void stq_phys_notdirty(hwaddr addr, uint64_t val);
void stw_phys(hwaddr addr, uint32_t val);
void stl_phys(hwaddr addr, uint32_t val);
void stq_phys(hwaddr addr, uint64_t val);
diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
index 1b156fd58f..8d15f90417 100644
--- a/include/exec/memory-internal.h
+++ b/include/exec/memory-internal.h
@@ -46,6 +46,7 @@ void address_space_destroy_dispatch(AddressSpace *as);
ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
MemoryRegion *mr);
ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
+void *qemu_get_ram_ptr(ram_addr_t addr);
void qemu_ram_free(ram_addr_t addr);
void qemu_ram_free_from_ptr(ram_addr_t addr);
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 9e88320113..fdf55feea1 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -26,6 +26,9 @@
#include "exec/ioport.h"
#include "qemu/int128.h"
+#define MAX_PHYS_ADDR_SPACE_BITS 62
+#define MAX_PHYS_ADDR (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1)
+
typedef struct MemoryRegionOps MemoryRegionOps;
typedef struct MemoryRegionPortio MemoryRegionPortio;
typedef struct MemoryRegionMmio MemoryRegionMmio;
@@ -126,7 +129,7 @@ struct MemoryRegion {
ram_addr_t ram_addr;
bool subpage;
bool terminates;
- bool readable;
+ bool romd_mode;
bool ram;
bool readonly; /* For RAM regions */
bool enabled;
@@ -355,16 +358,16 @@ uint64_t memory_region_size(MemoryRegion *mr);
bool memory_region_is_ram(MemoryRegion *mr);
/**
- * memory_region_is_romd: check whether a memory region is ROMD
+ * memory_region_is_romd: check whether a memory region is in ROMD mode
*
- * Returns %true is a memory region is ROMD and currently set to allow
+ * Returns %true if a memory region is a ROM device and currently set to allow
* direct reads.
*
* @mr: the memory region being queried
*/
static inline bool memory_region_is_romd(MemoryRegion *mr)
{
- return mr->rom_device && mr->readable;
+ return mr->rom_device && mr->romd_mode;
}
/**
@@ -502,18 +505,18 @@ void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr,
void memory_region_set_readonly(MemoryRegion *mr, bool readonly);
/**
- * memory_region_rom_device_set_readable: enable/disable ROM readability
+ * memory_region_rom_device_set_romd: enable/disable ROMD mode
*
* Allows a ROM device (initialized with memory_region_init_rom_device() to
- * to be marked as readable (default) or not readable. When it is readable,
- * the device is mapped to guest memory. When not readable, reads are
- * forwarded to the #MemoryRegion.read function.
+ * set to ROMD mode (default) or MMIO mode. When it is in ROMD mode, the
+ * device is mapped to guest memory and satisfies read access directly.
+ * When in MMIO mode, reads are forwarded to the #MemoryRegion.read function.
+ * Writes are always handled by the #MemoryRegion.write function.
*
* @mr: the memory region to be updated
- * @readable: whether reads are satisified directly (%true) or via callbacks
- * (%false)
+ * @romd_mode: %true to put the region into ROMD mode
*/
-void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable);
+void memory_region_rom_device_set_romd(MemoryRegion *mr, bool romd_mode);
/**
* memory_region_set_coalescing: Enable memory coalescing for the region.
@@ -718,24 +721,34 @@ void memory_region_set_alias_offset(MemoryRegion *mr,
hwaddr offset);
/**
- * memory_region_find: locate a MemoryRegion in an address space
+ * memory_region_find: translate an address/size relative to a
+ * MemoryRegion into a #MemoryRegionSection.
*
- * Locates the first #MemoryRegion within an address space given by
- * @address_space that overlaps the range given by @addr and @size.
+ * Locates the first #MemoryRegion within @mr that overlaps the range
+ * given by @addr and @size.
*
* Returns a #MemoryRegionSection that describes a contiguous overlap.
* It will have the following characteristics:
- * .@offset_within_address_space >= @addr
- * .@offset_within_address_space + .@size <= @addr + @size
* .@size = 0 iff no overlap was found
* .@mr is non-%NULL iff an overlap was found
*
- * @address_space: a top-level (i.e. parentless) region that contains
- * the region to be found
- * @addr: start of the area within @address_space to be searched
+ * Remember that in the return value the @offset_within_region is
+ * relative to the returned region (in the .@mr field), not to the
+ * @mr argument.
+ *
+ * Similarly, the .@offset_within_address_space is relative to the
+ * address space that contains both regions, the passed and the
+ * returned one. However, in the special case where the @mr argument
+ * has no parent (and thus is the root of the address space), the
+ * following will hold:
+ * .@offset_within_address_space >= @addr
+ * .@offset_within_address_space + .@size <= @addr + @size
+ *
+ * @mr: a MemoryRegion within which @addr is a relative address
+ * @addr: start of the area within @as to be searched
* @size: size of the area to be searched
*/
-MemoryRegionSection memory_region_find(MemoryRegion *address_space,
+MemoryRegionSection memory_region_find(MemoryRegion *mr,
hwaddr addr, uint64_t size);
/**
@@ -756,13 +769,12 @@ memory_region_section_addr(MemoryRegionSection *section,
}
/**
- * memory_global_sync_dirty_bitmap: synchronize the dirty log for all memory
+ * address_space_sync_dirty_bitmap: synchronize the dirty log for all memory
*
* Synchronizes the dirty page log for an entire address space.
- * @address_space: a top-level (i.e. parentless) region that contains the
- * memory being synchronized
+ * @as: the address space that contains the memory being synchronized
*/
-void memory_global_sync_dirty_bitmap(MemoryRegion *address_space);
+void address_space_sync_dirty_bitmap(AddressSpace *as);
/**
* memory_region_transaction_begin: Start a transaction.
diff --git a/include/exec/poison.h b/include/exec/poison.h
index 7d7b23b1fc..2341a75041 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -42,7 +42,6 @@
#pragma GCC poison ldl_phys
#pragma GCC poison ldq_phys
#pragma GCC poison stl_phys_notdirty
-#pragma GCC poison stq_phys_notdirty
#pragma GCC poison stw_phys
#pragma GCC poison stl_phys
#pragma GCC poison stq_phys
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 2bd7090248..663426cee8 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -7,7 +7,6 @@
#include "hw/isa/isa.h"
#include "hw/block/fdc.h"
#include "net/net.h"
-#include "exec/memory.h"
#include "hw/i386/ioapic.h"
/* PC-style peripherals (also used by other machines). */
@@ -217,6 +216,10 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
.property = "vectors",\
/* DEV_NVECTORS_UNSPECIFIED as a uint32_t string */\
.value = stringify(0xFFFFFFFF),\
+ },{ \
+ .driver = "virtio-net-pci", \
+ .property = "ctrl_guest_offloads", \
+ .value = "off", \
},{\
.driver = "e1000",\
.property = "romfile",\
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index beeead7a1a..b315ac91a4 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -31,6 +31,8 @@
/* The feature bitmap for virtio net */
#define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */
#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */
+#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Control channel offload
+ * configuration support */
#define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */
#define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */
#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */
@@ -190,6 +192,7 @@ typedef struct VirtIONet {
size_t config_size;
char *netclient_name;
char *netclient_type;
+ uint64_t curr_guest_offloads;
} VirtIONet;
#define VIRTIO_NET_CTRL_MAC 1
@@ -229,6 +232,15 @@ struct virtio_net_ctrl_mq {
#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN 1
#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000
+/*
+ * Control network offloads
+ *
+ * Dynamic offloads are available with the
+ * VIRTIO_NET_F_CTRL_GUEST_OFFLOADS feature bit.
+ */
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS 5
+ #define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET 0
+
#define DEFINE_VIRTIO_NET_FEATURES(_state, _field) \
DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \
DEFINE_PROP_BIT("csum", _state, _field, VIRTIO_NET_F_CSUM, true), \
@@ -249,6 +261,7 @@ struct virtio_net_ctrl_mq {
DEFINE_PROP_BIT("ctrl_vlan", _state, _field, VIRTIO_NET_F_CTRL_VLAN, true), \
DEFINE_PROP_BIT("ctrl_rx_extra", _state, _field, VIRTIO_NET_F_CTRL_RX_EXTRA, true), \
DEFINE_PROP_BIT("ctrl_mac_addr", _state, _field, VIRTIO_NET_F_CTRL_MAC_ADDR, true), \
+ DEFINE_PROP_BIT("ctrl_guest_offloads", _state, _field, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, true), \
DEFINE_PROP_BIT("mq", _state, _field, VIRTIO_NET_F_MQ, false)
#define DEFINE_VIRTIO_NET_PROPERTIES(_state, _field) \
diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h
index 382f04c3c4..6cc4831df3 100644
--- a/include/qapi/qmp/qlist.h
+++ b/include/qapi/qmp/qlist.h
@@ -15,7 +15,6 @@
#include "qapi/qmp/qobject.h"
#include "qemu/queue.h"
-#include "qemu/queue.h"
typedef struct QListEntry {
QObject *value;
diff --git a/include/qemu-common.h b/include/qemu-common.h
index b9057d18cf..cb82ef3d42 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -45,6 +45,7 @@
#if defined(__GLIBC__)
# include <pty.h>
#elif defined CONFIG_BSD
+# include <termios.h>
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
# include <libutil.h>
# else
diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
index ccfccae2b4..ad4a9e5c3a 100644
--- a/include/qemu/config-file.h
+++ b/include/qemu/config-file.h
@@ -4,7 +4,6 @@
#include <stdio.h>
#include "qemu/option.h"
#include "qapi/error.h"
-#include "qemu/option.h"
QemuOptsList *qemu_find_opts(const char *group);
QemuOptsList *qemu_find_opts_err(const char *group, Error **errp);
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 1055507224..5da8452b2a 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2528,7 +2528,8 @@ setup_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
int err = 0;
int i;
- err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
+ err |= __put_user(exception_resume_pc(regs), &sc->sc_pc);
+ regs->hflags &= ~MIPS_HFLAG_BMASK;
__put_user(0, &sc->sc_regs[0]);
for (i = 1; i < 32; ++i) {
@@ -2620,6 +2621,15 @@ get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
return (sp - frame_size) & ~7;
}
+static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
+{
+ if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
+ env->hflags &= ~MIPS_HFLAG_M16;
+ env->hflags |= (env->active_tc.PC & 1) << MIPS_HFLAG_M16_SHIFT;
+ env->active_tc.PC &= ~(target_ulong) 1;
+ }
+}
+
# if defined(TARGET_ABI_MIPSO32)
/* compare linux/arch/mips/kernel/signal.c:setup_frame() */
static void setup_frame(int sig, struct target_sigaction * ka,
@@ -2662,6 +2672,7 @@ static void setup_frame(int sig, struct target_sigaction * ka,
* since it returns to userland using eret
* we cannot do this here, and we must set PC directly */
regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
+ mips_set_hflags_isa_mode_from_pc(regs);
unlock_user_struct(frame, frame_addr, 1);
return;
@@ -2709,6 +2720,7 @@ long do_sigreturn(CPUMIPSState *regs)
#endif
regs->active_tc.PC = regs->CP0_EPC;
+ mips_set_hflags_isa_mode_from_pc(regs);
/* I am not sure this is right, but it seems to work
* maybe a problem with nested signals ? */
regs->CP0_EPC = 0;
@@ -2771,6 +2783,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
* since it returns to userland using eret
* we cannot do this here, and we must set PC directly */
env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
+ mips_set_hflags_isa_mode_from_pc(env);
unlock_user_struct(frame, frame_addr, 1);
return;
@@ -2804,6 +2817,7 @@ long do_rt_sigreturn(CPUMIPSState *env)
goto badframe;
env->active_tc.PC = env->CP0_EPC;
+ mips_set_hflags_isa_mode_from_pc(env);
/* I am not sure this is right, but it seems to work
* maybe a problem with nested signals ? */
env->CP0_EPC = 0;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 30e93bc0d0..1b3c0ed5f7 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5050,10 +5050,10 @@ static int open_self_maps(void *cpu_env, int fd)
}
if (h2g_valid(min) && h2g_valid(max)) {
dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
- " %c%c%c%c %08" PRIx64 " %02x:%02x %d%s%s\n",
+ " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n",
h2g(min), h2g(max), flag_r, flag_w,
flag_x, flag_p, offset, dev_maj, dev_min, inode,
- path[0] ? " " : "", path);
+ path[0] ? " " : "", path);
}
}
diff --git a/memory.c b/memory.c
index 75ca281e97..99f046d8bb 100644
--- a/memory.c
+++ b/memory.c
@@ -213,7 +213,7 @@ struct FlatRange {
hwaddr offset_in_region;
AddrRange addr;
uint8_t dirty_log_mask;
- bool readable;
+ bool romd_mode;
bool readonly;
};
@@ -236,7 +236,7 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b)
return a->mr == b->mr
&& addrrange_equal(a->addr, b->addr)
&& a->offset_in_region == b->offset_in_region
- && a->readable == b->readable
+ && a->romd_mode == b->romd_mode
&& a->readonly == b->readonly;
}
@@ -276,7 +276,7 @@ static bool can_merge(FlatRange *r1, FlatRange *r2)
r1->addr.size),
int128_make64(r2->offset_in_region))
&& r1->dirty_log_mask == r2->dirty_log_mask
- && r1->readable == r2->readable
+ && r1->romd_mode == r2->romd_mode
&& r1->readonly == r2->readonly;
}
@@ -532,7 +532,7 @@ static void render_memory_region(FlatView *view,
fr.offset_in_region = offset_in_region;
fr.addr = addrrange_make(base, now);
fr.dirty_log_mask = mr->dirty_log_mask;
- fr.readable = mr->readable;
+ fr.romd_mode = mr->romd_mode;
fr.readonly = readonly;
flatview_insert(view, i, &fr);
++i;
@@ -552,7 +552,7 @@ static void render_memory_region(FlatView *view,
fr.offset_in_region = offset_in_region;
fr.addr = addrrange_make(base, remain);
fr.dirty_log_mask = mr->dirty_log_mask;
- fr.readable = mr->readable;
+ fr.romd_mode = mr->romd_mode;
fr.readonly = readonly;
flatview_insert(view, i, &fr);
}
@@ -768,10 +768,6 @@ static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr)
qemu_ram_free_from_ptr(mr->ram_addr);
}
-static void memory_region_destructor_iomem(MemoryRegion *mr)
-{
-}
-
static void memory_region_destructor_rom_device(MemoryRegion *mr)
{
qemu_ram_free(mr->ram_addr & TARGET_PAGE_MASK);
@@ -801,7 +797,7 @@ void memory_region_init(MemoryRegion *mr,
mr->enabled = true;
mr->terminates = false;
mr->ram = false;
- mr->readable = true;
+ mr->romd_mode = true;
mr->readonly = false;
mr->rom_device = false;
mr->destructor = memory_region_destructor_none;
@@ -929,7 +925,6 @@ void memory_region_init_io(MemoryRegion *mr,
mr->ops = ops;
mr->opaque = opaque;
mr->terminates = true;
- mr->destructor = memory_region_destructor_iomem;
mr->ram_addr = ~(ram_addr_t)0;
}
@@ -1121,11 +1116,11 @@ void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
}
}
-void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable)
+void memory_region_rom_device_set_romd(MemoryRegion *mr, bool romd_mode)
{
- if (mr->readable != readable) {
+ if (mr->romd_mode != romd_mode) {
memory_region_transaction_begin();
- mr->readable = readable;
+ mr->romd_mode = romd_mode;
memory_region_update_pending |= mr->enabled;
memory_region_transaction_commit();
}
@@ -1451,15 +1446,24 @@ static FlatRange *address_space_lookup(AddressSpace *as, AddrRange addr)
sizeof(FlatRange), cmp_flatrange_addr);
}
-MemoryRegionSection memory_region_find(MemoryRegion *address_space,
+MemoryRegionSection memory_region_find(MemoryRegion *mr,
hwaddr addr, uint64_t size)
{
- AddressSpace *as = memory_region_to_address_space(address_space);
- AddrRange range = addrrange_make(int128_make64(addr),
- int128_make64(size));
- FlatRange *fr = address_space_lookup(as, range);
MemoryRegionSection ret = { .mr = NULL, .size = 0 };
+ MemoryRegion *root;
+ AddressSpace *as;
+ AddrRange range;
+ FlatRange *fr;
+ addr += mr->addr;
+ for (root = mr; root->parent; ) {
+ root = root->parent;
+ addr += root->addr;
+ }
+
+ as = memory_region_to_address_space(root);
+ range = addrrange_make(int128_make64(addr), int128_make64(size));
+ fr = address_space_lookup(as, range);
if (!fr) {
return ret;
}
@@ -1470,6 +1474,7 @@ MemoryRegionSection memory_region_find(MemoryRegion *address_space,
}
ret.mr = fr->mr;
+ ret.address_space = as;
range = addrrange_intersection(range, fr->addr);
ret.offset_within_region = fr->offset_in_region;
ret.offset_within_region += int128_get64(int128_sub(range.start,
@@ -1480,9 +1485,8 @@ MemoryRegionSection memory_region_find(MemoryRegion *address_space,
return ret;
}
-void memory_global_sync_dirty_bitmap(MemoryRegion *address_space)
+void address_space_sync_dirty_bitmap(AddressSpace *as)
{
- AddressSpace *as = memory_region_to_address_space(address_space);
FlatRange *fr;
FOR_EACH_FLAT_RANGE(fr, as->current_map) {
@@ -1568,10 +1572,13 @@ void address_space_init(AddressSpace *as, MemoryRegion *root)
as->root = root;
as->current_map = g_new(FlatView, 1);
flatview_init(as->current_map);
+ as->ioeventfd_nb = 0;
+ as->ioeventfds = NULL;
QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
as->name = NULL;
- memory_region_transaction_commit();
address_space_init_dispatch(as);
+ memory_region_update_pending |= root->enabled;
+ memory_region_transaction_commit();
}
void address_space_destroy(AddressSpace *as)
@@ -1584,6 +1591,7 @@ void address_space_destroy(AddressSpace *as)
address_space_destroy_dispatch(as);
flatview_destroy(as->current_map);
g_free(as->current_map);
+ g_free(as->ioeventfds);
}
uint64_t io_mem_read(MemoryRegion *mr, hwaddr addr, unsigned size)
@@ -1649,9 +1657,9 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
base + mr->addr
+ (hwaddr)int128_get64(mr->size) - 1,
mr->priority,
- mr->readable ? 'R' : '-',
- !mr->readonly && !(mr->rom_device && mr->readable) ? 'W'
- : '-',
+ mr->romd_mode ? 'R' : '-',
+ !mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W'
+ : '-',
mr->name,
mr->alias->name,
mr->alias_offset,
@@ -1664,9 +1672,9 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
base + mr->addr
+ (hwaddr)int128_get64(mr->size) - 1,
mr->priority,
- mr->readable ? 'R' : '-',
- !mr->readonly && !(mr->rom_device && mr->readable) ? 'W'
- : '-',
+ mr->romd_mode ? 'R' : '-',
+ !mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W'
+ : '-',
mr->name);
}
diff --git a/monitor.c b/monitor.c
index 62aaebe660..6ce2a4e61b 100644
--- a/monitor.c
+++ b/monitor.c
@@ -63,7 +63,6 @@
#ifdef CONFIG_TRACE_SIMPLE
#include "trace/simple.h"
#endif
-#include "ui/qemu-spice.h"
#include "exec/memory.h"
#include "qmp-commands.h"
#include "hmp.h"
diff --git a/net/tap-bsd.c b/net/tap-bsd.c
index bcdb2682b5..f61d580963 100644
--- a/net/tap-bsd.c
+++ b/net/tap-bsd.c
@@ -44,7 +44,8 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
struct stat s;
#endif
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
+ defined(__OpenBSD__) || defined(__APPLE__)
/* if no ifname is given, always start the search from tap0/tun0. */
int i;
char dname[100];
diff --git a/page_cache.c b/page_cache.c
index 938a79c9ea..a05db643cc 100644
--- a/page_cache.c
+++ b/page_cache.c
@@ -21,7 +21,6 @@
#include <sys/types.h>
#include <stdbool.h>
#include <glib.h>
-#include <strings.h>
#include "qemu-common.h"
#include "migration/page_cache.h"
diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin
index ec9eeb12c6..c2a19b8930 100644
--- a/pc-bios/bios.bin
+++ b/pc-bios/bios.bin
Binary files differ
diff --git a/qapi-schema-test.json b/qapi-schema-test.json
index 9eae3501d7..4434fa3961 100644
--- a/qapi-schema-test.json
+++ b/qapi-schema-test.json
@@ -32,6 +32,21 @@
{ 'union': 'UserDefUnion',
'data': { 'a' : 'UserDefA', 'b' : 'UserDefB' } }
+# for testing native lists
+{ 'union': 'UserDefNativeListUnion',
+ 'data': { 'integer': ['int'],
+ 's8': ['int8'],
+ 's16': ['int16'],
+ 's32': ['int32'],
+ 's64': ['int64'],
+ 'u8': ['uint8'],
+ 'u16': ['uint16'],
+ 'u32': ['uint32'],
+ 'u64': ['uint64'],
+ 'number': ['number'],
+ 'boolean': ['bool'],
+ 'string': ['str'] } }
+
# testing commands
{ 'command': 'user_def_cmd', 'data': {} }
{ 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} }
diff --git a/qapi-schema.json b/qapi-schema.json
index 9302e7db01..ef1f657efb 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1609,12 +1609,12 @@
'*mode': 'NewImageMode' } }
##
-# @BlockdevAction
+# @TransactionAction
#
# A discriminated record of operations that can be performed with
# @transaction.
##
-{ 'union': 'BlockdevAction',
+{ 'union': 'TransactionAction',
'data': {
'blockdev-snapshot-sync': 'BlockdevSnapshot'
} }
@@ -1622,25 +1622,24 @@
##
# @transaction
#
-# Atomically operate on a group of one or more block devices. If
-# any operation fails, then the entire set of actions will be
-# abandoned and the appropriate error returned. The only operation
-# supported is currently blockdev-snapshot-sync.
+# Executes a number of transactionable QMP commands atomically. If any
+# operation fails, then the entire set of actions will be abandoned and the
+# appropriate error returned.
#
# List of:
-# @BlockdevAction: information needed for the device snapshot
+# @TransactionAction: information needed for the respective operation
#
# Returns: nothing on success
-# If @device is not a valid block device, DeviceNotFound
+# Errors depend on the operations of the transaction
#
-# Note: The transaction aborts on the first failure. Therefore, there will
-# be only one device or snapshot file returned in an error condition, and
+# Note: The transaction aborts on the first failure. Therefore, there will be
+# information on only one failed operation returned in an error condition, and
# subsequent actions will not have been attempted.
#
# Since 1.1
##
{ 'command': 'transaction',
- 'data': { 'actions': [ 'BlockdevAction' ] } }
+ 'data': { 'actions': [ 'TransactionAction' ] } }
##
# @blockdev-snapshot-sync
@@ -3286,7 +3285,7 @@
'*rows' : 'int' } }
##
-# @ChardevRingbuf:
+# @ChardevMemory:
#
# Configuration info for memory chardevs
#
@@ -3294,7 +3293,7 @@
#
# Since: 1.5
##
-{ 'type': 'ChardevRingbuf', 'data': { '*size' : 'int' } }
+{ 'type': 'ChardevMemory', 'data': { '*size' : 'int' } }
##
# @ChardevBackend:
@@ -3321,7 +3320,7 @@
'spicevmc' : 'ChardevSpiceChannel',
'spiceport' : 'ChardevSpicePort',
'vc' : 'ChardevVC',
- 'memory' : 'ChardevRingbuf' } }
+ 'memory' : 'ChardevMemory' } }
##
# @ChardevReturn:
diff --git a/qemu-char.c b/qemu-char.c
index cff2896065..d04b429a03 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2875,8 +2875,8 @@ static void ringbuf_chr_close(struct CharDriverState *chr)
chr->opaque = NULL;
}
-static CharDriverState *qemu_chr_open_ringbuf(ChardevRingbuf *opts,
- Error **errp)
+static CharDriverState *qemu_chr_open_memory(ChardevMemory *opts,
+ Error **errp)
{
CharDriverState *chr;
RingBufCharDriver *d;
@@ -2888,7 +2888,7 @@ static CharDriverState *qemu_chr_open_ringbuf(ChardevRingbuf *opts,
/* The size must be power of 2 */
if (d->size & (d->size - 1)) {
- error_setg(errp, "size of ringbuf chardev must be power of two");
+ error_setg(errp, "size of memory chardev must be power of two");
goto fail;
}
@@ -2920,7 +2920,7 @@ void qmp_ringbuf_write(const char *device, const char *data,
CharDriverState *chr;
const uint8_t *write_data;
int ret;
- size_t write_count;
+ gsize write_count;
chr = qemu_chr_find(device);
if (!chr) {
@@ -3190,12 +3190,12 @@ static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend,
backend->pipe->device = g_strdup(device);
}
-static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend,
- Error **errp)
+static void qemu_chr_parse_memory(QemuOpts *opts, ChardevBackend *backend,
+ Error **errp)
{
int val;
- backend->memory = g_new0(ChardevRingbuf, 1);
+ backend->memory = g_new0(ChardevMemory, 1);
val = qemu_opt_get_number(opts, "size", 0);
if (val != 0) {
@@ -3787,7 +3787,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
chr = vc_init(backend->vc);
break;
case CHARDEV_BACKEND_KIND_MEMORY:
- chr = qemu_chr_open_ringbuf(backend->memory, errp);
+ chr = qemu_chr_open_memory(backend->memory, errp);
break;
default:
error_setg(errp, "unknown chardev backend (%d)", backend->kind);
@@ -3801,6 +3801,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
chr->label = g_strdup(id);
chr->avail_connections =
(backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
+ if (!chr->filename) {
+ chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]);
+ }
QTAILQ_INSERT_TAIL(&chardevs, chr, next);
return ret;
} else {
@@ -3832,7 +3835,7 @@ static void register_types(void)
register_char_driver("socket", qemu_chr_open_socket);
register_char_driver("udp", qemu_chr_open_udp);
register_char_driver_qapi("memory", CHARDEV_BACKEND_KIND_MEMORY,
- qemu_chr_parse_ringbuf);
+ qemu_chr_parse_memory);
register_char_driver_qapi("file", CHARDEV_BACKEND_KIND_FILE,
qemu_chr_parse_file_out);
register_char_driver_qapi("stdio", CHARDEV_BACKEND_KIND_STDIO,
diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c
index 86efe1f86a..d9fea4989d 100644
--- a/qemu-coroutine-lock.c
+++ b/qemu-coroutine-lock.c
@@ -26,39 +26,11 @@
#include "block/coroutine.h"
#include "block/coroutine_int.h"
#include "qemu/queue.h"
-#include "block/aio.h"
#include "trace.h"
-/* Coroutines are awoken from a BH to allow the current coroutine to complete
- * its flow of execution. The BH may run after the CoQueue has been destroyed,
- * so keep BH data in a separate heap-allocated struct.
- */
-typedef struct {
- QEMUBH *bh;
- QTAILQ_HEAD(, Coroutine) entries;
-} CoQueueNextData;
-
-static void qemu_co_queue_next_bh(void *opaque)
-{
- CoQueueNextData *data = opaque;
- Coroutine *next;
-
- trace_qemu_co_queue_next_bh();
- while ((next = QTAILQ_FIRST(&data->entries))) {
- QTAILQ_REMOVE(&data->entries, next, co_queue_next);
- qemu_coroutine_enter(next, NULL);
- }
-
- qemu_bh_delete(data->bh);
- g_slice_free(CoQueueNextData, data);
-}
-
void qemu_co_queue_init(CoQueue *queue)
{
QTAILQ_INIT(&queue->entries);
-
- /* This will be exposed to callers once there are multiple AioContexts */
- queue->ctx = qemu_get_aio_context();
}
void coroutine_fn qemu_co_queue_wait(CoQueue *queue)
@@ -77,23 +49,37 @@ void coroutine_fn qemu_co_queue_wait_insert_head(CoQueue *queue)
assert(qemu_in_coroutine());
}
+/**
+ * qemu_co_queue_run_restart:
+ *
+ * Enter each coroutine that was previously marked for restart by
+ * qemu_co_queue_next() or qemu_co_queue_restart_all(). This function is
+ * invoked by the core coroutine code when the current coroutine yields or
+ * terminates.
+ */
+void qemu_co_queue_run_restart(Coroutine *co)
+{
+ Coroutine *next;
+
+ trace_qemu_co_queue_run_restart(co);
+ while ((next = QTAILQ_FIRST(&co->co_queue_wakeup))) {
+ QTAILQ_REMOVE(&co->co_queue_wakeup, next, co_queue_next);
+ qemu_coroutine_enter(next, NULL);
+ }
+}
+
static bool qemu_co_queue_do_restart(CoQueue *queue, bool single)
{
+ Coroutine *self = qemu_coroutine_self();
Coroutine *next;
- CoQueueNextData *data;
if (QTAILQ_EMPTY(&queue->entries)) {
return false;
}
- data = g_slice_new(CoQueueNextData);
- data->bh = aio_bh_new(queue->ctx, qemu_co_queue_next_bh, data);
- QTAILQ_INIT(&data->entries);
- qemu_bh_schedule(data->bh);
-
while ((next = QTAILQ_FIRST(&queue->entries)) != NULL) {
QTAILQ_REMOVE(&queue->entries, next, co_queue_next);
- QTAILQ_INSERT_TAIL(&data->entries, next, co_queue_next);
+ QTAILQ_INSERT_TAIL(&self->co_queue_wakeup, next, co_queue_next);
trace_qemu_co_queue_next(next);
if (single) {
break;
diff --git a/qemu-coroutine.c b/qemu-coroutine.c
index 25a14c605d..423430d3a0 100644
--- a/qemu-coroutine.c
+++ b/qemu-coroutine.c
@@ -14,6 +14,7 @@
#include "trace.h"
#include "qemu-common.h"
+#include "qemu/thread.h"
#include "block/coroutine.h"
#include "block/coroutine_int.h"
@@ -23,6 +24,7 @@ enum {
};
/** Free list to speed up creation */
+static QemuMutex pool_lock;
static QSLIST_HEAD(, Coroutine) pool = QSLIST_HEAD_INITIALIZER(pool);
static unsigned int pool_size;
@@ -30,31 +32,44 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
{
Coroutine *co;
+ qemu_mutex_lock(&pool_lock);
co = QSLIST_FIRST(&pool);
if (co) {
QSLIST_REMOVE_HEAD(&pool, pool_next);
pool_size--;
- } else {
+ }
+ qemu_mutex_unlock(&pool_lock);
+
+ if (!co) {
co = qemu_coroutine_new();
}
co->entry = entry;
+ QTAILQ_INIT(&co->co_queue_wakeup);
return co;
}
static void coroutine_delete(Coroutine *co)
{
+ qemu_mutex_lock(&pool_lock);
if (pool_size < POOL_MAX_SIZE) {
QSLIST_INSERT_HEAD(&pool, co, pool_next);
co->caller = NULL;
pool_size++;
+ qemu_mutex_unlock(&pool_lock);
return;
}
+ qemu_mutex_unlock(&pool_lock);
qemu_coroutine_delete(co);
}
-static void __attribute__((destructor)) coroutine_cleanup(void)
+static void __attribute__((constructor)) coroutine_pool_init(void)
+{
+ qemu_mutex_init(&pool_lock);
+}
+
+static void __attribute__((destructor)) coroutine_pool_cleanup(void)
{
Coroutine *co;
Coroutine *tmp;
@@ -63,6 +78,8 @@ static void __attribute__((destructor)) coroutine_cleanup(void)
QSLIST_REMOVE_HEAD(&pool, pool_next);
qemu_coroutine_delete(co);
}
+
+ qemu_mutex_destroy(&pool_lock);
}
static void coroutine_swap(Coroutine *from, Coroutine *to)
@@ -71,6 +88,8 @@ static void coroutine_swap(Coroutine *from, Coroutine *to)
ret = qemu_coroutine_switch(from, to, COROUTINE_YIELD);
+ qemu_co_queue_run_restart(to);
+
switch (ret) {
case COROUTINE_YIELD:
return;
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 5fc0eae400..8022890391 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -1958,15 +1958,11 @@ SPARCbook
The emulation is somewhat complete. SMP up to 16 CPUs is supported,
but Linux limits the number of usable CPUs to 4.
-It's also possible to simulate a SPARCstation 2 (sun4c architecture),
-SPARCserver 1000, or SPARCcenter 2000 (sun4d architecture), but these
-emulators are not usable yet.
-
-QEMU emulates the following sun4m/sun4c/sun4d peripherals:
+QEMU emulates the following sun4m peripherals:
@itemize @minus
@item
-IOMMU or IO-UNITs
+IOMMU
@item
TCX Frame buffer
@item
@@ -2019,7 +2015,7 @@ qemu-system-sparc -prom-env 'auto-boot?=false' \
-prom-env 'boot-device=sd(0,2,0):d' -prom-env 'boot-args=linux single'
@end example
-@item -M [SS-4|SS-5|SS-10|SS-20|SS-600MP|LX|Voyager|SPARCClassic] [|SPARCbook|SS-2|SS-1000|SS-2000]
+@item -M [SS-4|SS-5|SS-10|SS-20|SS-600MP|LX|Voyager|SPARCClassic] [|SPARCbook]
Set the emulated machine type. Default is SS-5.
diff --git a/qemu-io.c b/qemu-io.c
index 475a8bd034..5e6680b247 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -1635,12 +1635,43 @@ static const cmdinfo_t alloc_cmd = {
.oneline = "checks if a sector is present in the file",
};
+
+static int map_is_allocated(int64_t sector_num, int64_t nb_sectors, int64_t *pnum)
+{
+ int num, num_checked;
+ int ret, firstret;
+
+ num_checked = MIN(nb_sectors, INT_MAX);
+ ret = bdrv_is_allocated(bs, sector_num, num_checked, &num);
+ if (ret < 0) {
+ return ret;
+ }
+
+ firstret = ret;
+ *pnum = num;
+
+ while (nb_sectors > 0 && ret == firstret) {
+ sector_num += num;
+ nb_sectors -= num;
+
+ num_checked = MIN(nb_sectors, INT_MAX);
+ ret = bdrv_is_allocated(bs, sector_num, num_checked, &num);
+ if (ret == firstret) {
+ *pnum += num;
+ } else {
+ break;
+ }
+ }
+
+ return firstret;
+}
+
static int map_f(int argc, char **argv)
{
int64_t offset;
int64_t nb_sectors;
char s1[64];
- int num, num_checked;
+ int64_t num;
int ret;
const char *retstr;
@@ -1648,12 +1679,17 @@ static int map_f(int argc, char **argv)
nb_sectors = bs->total_sectors;
do {
- num_checked = MIN(nb_sectors, INT_MAX);
- ret = bdrv_is_allocated(bs, offset, num_checked, &num);
+ ret = map_is_allocated(offset, nb_sectors, &num);
+ if (ret < 0) {
+ error_report("Failed to get allocation status: %s", strerror(-ret));
+ return 0;
+ }
+
retstr = ret ? " allocated" : "not allocated";
cvtstr(offset << 9ULL, s1, sizeof(s1));
- printf("[% 24" PRId64 "] % 8d/% 8d sectors %s at offset %s (%d)\n",
- offset << 9ULL, num, num_checked, retstr, s1, ret);
+ printf("[% 24" PRId64 "] % 8" PRId64 "/% 8" PRId64 " sectors %s "
+ "at offset %s (%d)\n",
+ offset << 9ULL, num, nb_sectors, retstr, s1, ret);
offset += num;
nb_sectors -= num;
diff --git a/qemu-options.hx b/qemu-options.hx
index fb62b75ccb..bf94862b58 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1779,7 +1779,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
"-chardev msmouse,id=id[,mux=on|off]\n"
"-chardev vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]]\n"
" [,mux=on|off]\n"
- "-chardev ringbuf,id=id[,size=size]\n"
+ "-chardev memory,id=id[,size=size]\n"
"-chardev file,id=id,path=path[,mux=on|off]\n"
"-chardev pipe,id=id,path=path[,mux=on|off]\n"
#ifdef _WIN32
@@ -1817,7 +1817,7 @@ Backend is one of:
@option{udp},
@option{msmouse},
@option{vc},
-@option{ringbuf},
+@option{memory},
@option{file},
@option{pipe},
@option{console},
@@ -1926,7 +1926,7 @@ the console, in pixels.
@option{cols} and @option{rows} specify that the console be sized to fit a text
console with the given dimensions.
-@item -chardev ringbuf ,id=@var{id} [,size=@var{size}]
+@item -chardev memory ,id=@var{id} [,size=@var{size}]
Create a ring buffer with fixed size @option{size}.
@var{size} must be a power of two, and defaults to @code{64K}).
@@ -2528,6 +2528,7 @@ Redirect the monitor to host device @var{dev} (same devices as the
serial port).
The default device is @code{vc} in graphical mode and @code{stdio} in
non graphical mode.
+Use @code{-monitor none} to disable the default monitor.
ETEXI
DEF("qmp", HAS_ARG, QEMU_OPTION_qmp, \
"-qmp dev like -monitor but opens in 'control' mode\n",
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index 05279c11eb..e7947b340c 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -640,9 +640,29 @@ static QObject *parse_literal(JSONParserContext *ctxt)
case JSON_STRING:
obj = QOBJECT(qstring_from_escaped_str(ctxt, token));
break;
- case JSON_INTEGER:
- obj = QOBJECT(qint_from_int(strtoll(token_get_value(token), NULL, 10)));
- break;
+ case JSON_INTEGER: {
+ /* A possibility exists that this is a whole-valued float where the
+ * fractional part was left out due to being 0 (.0). It's not a big
+ * deal to treat these as ints in the parser, so long as users of the
+ * resulting QObject know to expect a QInt in place of a QFloat in
+ * cases like these.
+ *
+ * However, in some cases these values will overflow/underflow a
+ * QInt/int64 container, thus we should assume these are to be handled
+ * as QFloats/doubles rather than silently changing their values.
+ *
+ * strtoll() indicates these instances by setting errno to ERANGE
+ */
+ int64_t value;
+
+ errno = 0; /* strtoll doesn't set errno on success */
+ value = strtoll(token_get_value(token), NULL, 10);
+ if (errno != ERANGE) {
+ obj = QOBJECT(qint_from_int(value));
+ break;
+ }
+ /* fall through to JSON_FLOAT */
+ }
case JSON_FLOAT:
/* FIXME dependent on locale */
obj = QOBJECT(qfloat_from_double(strtod(token_get_value(token), NULL)));
diff --git a/qom/object.c b/qom/object.c
index ec88231fa9..803b94bb66 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -442,7 +442,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename,
int i;
Object *inst;
- for (i = 0; i < OBJECT_CLASS_CAST_CACHE; i++) {
+ for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
if (obj->class->cast_cache[i] == typename) {
goto out;
}
@@ -458,7 +458,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename,
assert(obj == inst);
- if (obj == inst) {
+ if (obj && obj == inst) {
for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
obj->class->cast_cache[i - 1] = obj->class->cast_cache[i];
}
diff --git a/roms/configure-seabios.sh b/roms/configure-seabios.sh
index 4bb6c2b90f..98f59a24ba 100755
--- a/roms/configure-seabios.sh
+++ b/roms/configure-seabios.sh
@@ -2,4 +2,4 @@
config="$1"
make -C seabios clean distclean
cp "$config" seabios/.config
-make -C seabios olddefconfig
+make -C seabios oldnoconfig
diff --git a/roms/seabios b/roms/seabios
-Subproject 88cb66ea542906ffff8a80ef397b9e3adbb3311
+Subproject d4f7d90f47462b4e8836899adc5060fbde5253e
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 9e19920970..fd42d71da1 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -16,8 +16,21 @@ import os
import getopt
import errno
-def generate_fwd_struct(name, members):
+def generate_fwd_struct(name, members, builtin_type=False):
+ if builtin_type:
+ return mcgen('''
+
+typedef struct %(name)sList
+{
+ %(type)s value;
+ struct %(name)sList *next;
+} %(name)sList;
+''',
+ type=c_type(name),
+ name=name)
+
return mcgen('''
+
typedef struct %(name)s %(name)s;
typedef struct %(name)sList
@@ -164,6 +177,7 @@ void qapi_free_%(type)s(%(c_type)s obj);
def generate_type_cleanup(name):
ret = mcgen('''
+
void qapi_free_%(type)s(%(c_type)s obj)
{
QapiDeallocVisitor *md;
@@ -184,8 +198,9 @@ void qapi_free_%(type)s(%(c_type)s obj)
try:
- opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:",
- ["source", "header", "prefix=", "output-dir="])
+ opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
+ ["source", "header", "builtins",
+ "prefix=", "output-dir="])
except getopt.GetoptError, err:
print str(err)
sys.exit(1)
@@ -197,6 +212,7 @@ h_file = 'qapi-types.h'
do_c = False
do_h = False
+do_builtins = False
for o, a in opts:
if o in ("-p", "--prefix"):
@@ -207,6 +223,8 @@ for o, a in opts:
do_c = True
elif o in ("-h", "--header"):
do_h = True
+ elif o in ("-b", "--builtins"):
+ do_builtins = True
if not do_c and not do_h:
do_c = True
@@ -282,6 +300,11 @@ fdecl.write(mcgen('''
exprs = parse_schema(sys.stdin)
exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
+fdecl.write(guardstart("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
+for typename in builtin_types:
+ fdecl.write(generate_fwd_struct(typename, None, builtin_type=True))
+fdecl.write(guardend("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
+
for expr in exprs:
ret = "\n"
if expr.has_key('type'):
@@ -298,6 +321,22 @@ for expr in exprs:
continue
fdecl.write(ret)
+# to avoid header dependency hell, we always generate declarations
+# for built-in types in our header files and simply guard them
+fdecl.write(guardstart("QAPI_TYPES_BUILTIN_CLEANUP_DECL"))
+for typename in builtin_types:
+ fdecl.write(generate_type_cleanup_decl(typename + "List"))
+fdecl.write(guardend("QAPI_TYPES_BUILTIN_CLEANUP_DECL"))
+
+# ...this doesn't work for cases where we link in multiple objects that
+# have the functions defined, so we use -b option to provide control
+# over these cases
+if do_builtins:
+ fdef.write(guardstart("QAPI_TYPES_BUILTIN_CLEANUP_DEF"))
+ for typename in builtin_types:
+ fdef.write(generate_type_cleanup(typename + "List"))
+ fdef.write(guardend("QAPI_TYPES_BUILTIN_CLEANUP_DEF"))
+
for expr in exprs:
ret = "\n"
if expr.has_key('type'):
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index a276540a18..6cac05acd5 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -174,7 +174,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **
''',
abbrev = de_camel_case(name).upper(),
enum = c_fun(de_camel_case(key),False).upper(),
- c_type=members[key],
+ c_type=type_name(members[key]),
c_name=c_fun(key))
ret += mcgen('''
@@ -202,12 +202,14 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **
return ret
-def generate_declaration(name, members, genlist=True):
- ret = mcgen('''
+def generate_declaration(name, members, genlist=True, builtin_type=False):
+ ret = ""
+ if not builtin_type:
+ ret += mcgen('''
void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp);
''',
- name=name)
+ name=name)
if genlist:
ret += mcgen('''
@@ -235,8 +237,9 @@ void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **e
name=name)
try:
- opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:",
- ["source", "header", "prefix=", "output-dir="])
+ opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
+ ["source", "header", "builtins", "prefix=",
+ "output-dir="])
except getopt.GetoptError, err:
print str(err)
sys.exit(1)
@@ -248,6 +251,7 @@ h_file = 'qapi-visit.h'
do_c = False
do_h = False
+do_builtins = False
for o, a in opts:
if o in ("-p", "--prefix"):
@@ -258,6 +262,8 @@ for o, a in opts:
do_c = True
elif o in ("-h", "--header"):
do_h = True
+ elif o in ("-b", "--builtins"):
+ do_builtins = True
if not do_c and not do_h:
do_c = True
@@ -324,11 +330,29 @@ fdecl.write(mcgen('''
#include "qapi/visitor.h"
#include "%(prefix)sqapi-types.h"
+
''',
prefix=prefix, guard=guardname(h_file)))
exprs = parse_schema(sys.stdin)
+# to avoid header dependency hell, we always generate declarations
+# for built-in types in our header files and simply guard them
+fdecl.write(guardstart("QAPI_VISIT_BUILTIN_VISITOR_DECL"))
+for typename in builtin_types:
+ fdecl.write(generate_declaration(typename, None, genlist=True,
+ builtin_type=True))
+fdecl.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DECL"))
+
+# ...this doesn't work for cases where we link in multiple objects that
+# have the functions defined, so we use -b option to provide control
+# over these cases
+if do_builtins:
+ fdef.write(guardstart("QAPI_VISIT_BUILTIN_VISITOR_DEF"))
+ for typename in builtin_types:
+ fdef.write(generate_visit_list(typename, None))
+ fdef.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DEF"))
+
for expr in exprs:
if expr.has_key('type'):
ret = generate_visit_struct(expr['type'], expr['data'])
diff --git a/scripts/qapi.py b/scripts/qapi.py
index afc5f32aeb..02ad668ca3 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -11,6 +11,12 @@
from ordereddict import OrderedDict
+builtin_types = [
+ 'str', 'int', 'number', 'bool',
+ 'int8', 'int16', 'int32', 'int64',
+ 'uint8', 'uint16', 'uint32', 'uint64'
+]
+
def tokenize(data):
while len(data):
ch = data[0]
@@ -242,3 +248,20 @@ def guardname(filename):
for substr in [".", " ", "-"]:
guard = guard.replace(substr, "_")
return guard.upper() + '_H'
+
+def guardstart(name):
+ return mcgen('''
+
+#ifndef %(name)s
+#define %(name)s
+
+''',
+ name=guardname(name))
+
+def guardend(name):
+ return mcgen('''
+
+#endif /* %(name)s */
+
+''',
+ name=guardname(name))
diff --git a/slirp/misc.c b/slirp/misc.c
index 8ecced547f..0bcc481939 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -242,8 +242,6 @@ strdup(str)
}
#endif
-#include "monitor/monitor.h"
-
void lprint(const char *format, ...)
{
va_list args;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index a1b7b8c1a8..71135bdef1 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -95,7 +95,7 @@ static TCGv_i32 cpu_exclusive_info;
#endif
/* FIXME: These should be removed. */
-static TCGv cpu_F0s, cpu_F1s;
+static TCGv_i32 cpu_F0s, cpu_F1s;
static TCGv_i64 cpu_F0d, cpu_F1d;
#include "exec/gen-icount.h"
@@ -138,16 +138,16 @@ void arm_translate_init(void)
#include "helper.h"
}
-static inline TCGv load_cpu_offset(int offset)
+static inline TCGv_i32 load_cpu_offset(int offset)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_ld_i32(tmp, cpu_env, offset);
return tmp;
}
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
-static inline void store_cpu_offset(TCGv var, int offset)
+static inline void store_cpu_offset(TCGv_i32 var, int offset)
{
tcg_gen_st_i32(var, cpu_env, offset);
tcg_temp_free_i32(var);
@@ -157,7 +157,7 @@ static inline void store_cpu_offset(TCGv var, int offset)
store_cpu_offset(var, offsetof(CPUARMState, name))
/* Set a variable to the value of a CPU register. */
-static void load_reg_var(DisasContext *s, TCGv var, int reg)
+static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
{
if (reg == 15) {
uint32_t addr;
@@ -173,16 +173,16 @@ static void load_reg_var(DisasContext *s, TCGv var, int reg)
}
/* Create a new temporary and set it to the value of a CPU register. */
-static inline TCGv load_reg(DisasContext *s, int reg)
+static inline TCGv_i32 load_reg(DisasContext *s, int reg)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
load_reg_var(s, tmp, reg);
return tmp;
}
/* Set a CPU register. The source must be a temporary and will be
marked as dead. */
-static void store_reg(DisasContext *s, int reg, TCGv var)
+static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
{
if (reg == 15) {
tcg_gen_andi_i32(var, var, ~1);
@@ -202,9 +202,9 @@ static void store_reg(DisasContext *s, int reg, TCGv var)
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
-static inline void gen_set_cpsr(TCGv var, uint32_t mask)
+static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
{
- TCGv tmp_mask = tcg_const_i32(mask);
+ TCGv_i32 tmp_mask = tcg_const_i32(mask);
gen_helper_cpsr_write(cpu_env, var, tmp_mask);
tcg_temp_free_i32(tmp_mask);
}
@@ -213,16 +213,16 @@ static inline void gen_set_cpsr(TCGv var, uint32_t mask)
static void gen_exception(int excp)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_movi_i32(tmp, excp);
gen_helper_exception(cpu_env, tmp);
tcg_temp_free_i32(tmp);
}
-static void gen_smul_dual(TCGv a, TCGv b)
+static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
{
- TCGv tmp1 = tcg_temp_new_i32();
- TCGv tmp2 = tcg_temp_new_i32();
+ TCGv_i32 tmp1 = tcg_temp_new_i32();
+ TCGv_i32 tmp2 = tcg_temp_new_i32();
tcg_gen_ext16s_i32(tmp1, a);
tcg_gen_ext16s_i32(tmp2, b);
tcg_gen_mul_i32(tmp1, tmp1, tmp2);
@@ -235,9 +235,9 @@ static void gen_smul_dual(TCGv a, TCGv b)
}
/* Byteswap each halfword. */
-static void gen_rev16(TCGv var)
+static void gen_rev16(TCGv_i32 var)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_shri_i32(tmp, var, 8);
tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
tcg_gen_shli_i32(var, var, 8);
@@ -247,7 +247,7 @@ static void gen_rev16(TCGv var)
}
/* Byteswap low halfword and sign extend. */
-static void gen_revsh(TCGv var)
+static void gen_revsh(TCGv_i32 var)
{
tcg_gen_ext16u_i32(var, var);
tcg_gen_bswap16_i32(var, var);
@@ -255,7 +255,7 @@ static void gen_revsh(TCGv var)
}
/* Unsigned bitfield extract. */
-static void gen_ubfx(TCGv var, int shift, uint32_t mask)
+static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
{
if (shift)
tcg_gen_shri_i32(var, var, shift);
@@ -263,7 +263,7 @@ static void gen_ubfx(TCGv var, int shift, uint32_t mask)
}
/* Signed bitfield extract. */
-static void gen_sbfx(TCGv var, int shift, int width)
+static void gen_sbfx(TCGv_i32 var, int shift, int width)
{
uint32_t signbit;
@@ -278,7 +278,7 @@ static void gen_sbfx(TCGv var, int shift, int width)
}
/* Return (b << 32) + a. Mark inputs as dead */
-static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv b)
+static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
{
TCGv_i64 tmp64 = tcg_temp_new_i64();
@@ -292,7 +292,7 @@ static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv b)
}
/* Return (b << 32) - a. Mark inputs as dead. */
-static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv b)
+static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
{
TCGv_i64 tmp64 = tcg_temp_new_i64();
@@ -306,10 +306,10 @@ static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv b)
}
/* 32x32->64 multiply. Marks inputs as dead. */
-static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
+static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
{
- TCGv lo = tcg_temp_new_i32();
- TCGv hi = tcg_temp_new_i32();
+ TCGv_i32 lo = tcg_temp_new_i32();
+ TCGv_i32 hi = tcg_temp_new_i32();
TCGv_i64 ret;
tcg_gen_mulu2_i32(lo, hi, a, b);
@@ -318,16 +318,16 @@ static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
ret = tcg_temp_new_i64();
tcg_gen_concat_i32_i64(ret, lo, hi);
- tcg_temp_free(lo);
- tcg_temp_free(hi);
+ tcg_temp_free_i32(lo);
+ tcg_temp_free_i32(hi);
return ret;
}
-static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
+static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
{
- TCGv lo = tcg_temp_new_i32();
- TCGv hi = tcg_temp_new_i32();
+ TCGv_i32 lo = tcg_temp_new_i32();
+ TCGv_i32 hi = tcg_temp_new_i32();
TCGv_i64 ret;
tcg_gen_muls2_i32(lo, hi, a, b);
@@ -336,16 +336,16 @@ static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
ret = tcg_temp_new_i64();
tcg_gen_concat_i32_i64(ret, lo, hi);
- tcg_temp_free(lo);
- tcg_temp_free(hi);
+ tcg_temp_free_i32(lo);
+ tcg_temp_free_i32(hi);
return ret;
}
/* Swap low and high halfwords. */
-static void gen_swap_half(TCGv var)
+static void gen_swap_half(TCGv_i32 var)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_shri_i32(tmp, var, 16);
tcg_gen_shli_i32(var, var, 16);
tcg_gen_or_i32(var, var, tmp);
@@ -359,9 +359,9 @@ static void gen_swap_half(TCGv var)
t0 = (t0 + t1) ^ tmp;
*/
-static void gen_add16(TCGv t0, TCGv t1)
+static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_xor_i32(tmp, t0, t1);
tcg_gen_andi_i32(tmp, tmp, 0x8000);
tcg_gen_andi_i32(t0, t0, ~0x8000);
@@ -373,34 +373,34 @@ static void gen_add16(TCGv t0, TCGv t1)
}
/* Set CF to the top bit of var. */
-static void gen_set_CF_bit31(TCGv var)
+static void gen_set_CF_bit31(TCGv_i32 var)
{
tcg_gen_shri_i32(cpu_CF, var, 31);
}
/* Set N and Z flags from var. */
-static inline void gen_logic_CC(TCGv var)
+static inline void gen_logic_CC(TCGv_i32 var)
{
tcg_gen_mov_i32(cpu_NF, var);
tcg_gen_mov_i32(cpu_ZF, var);
}
/* T0 += T1 + CF. */
-static void gen_adc(TCGv t0, TCGv t1)
+static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
{
tcg_gen_add_i32(t0, t0, t1);
tcg_gen_add_i32(t0, t0, cpu_CF);
}
/* dest = T0 + T1 + CF. */
-static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
+static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
tcg_gen_add_i32(dest, t0, t1);
tcg_gen_add_i32(dest, dest, cpu_CF);
}
/* dest = T0 - T1 + CF - 1. */
-static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
+static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
tcg_gen_sub_i32(dest, t0, t1);
tcg_gen_add_i32(dest, dest, cpu_CF);
@@ -408,9 +408,9 @@ static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
}
/* dest = T0 + T1. Compute C, N, V and Z flags */
-static void gen_add_CC(TCGv dest, TCGv t0, TCGv t1)
+static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_movi_i32(tmp, 0);
tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
@@ -422,9 +422,9 @@ static void gen_add_CC(TCGv dest, TCGv t0, TCGv t1)
}
/* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
-static void gen_adc_CC(TCGv dest, TCGv t0, TCGv t1)
+static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
if (TCG_TARGET_HAS_add2_i32) {
tcg_gen_movi_i32(tmp, 0);
tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
@@ -450,9 +450,9 @@ static void gen_adc_CC(TCGv dest, TCGv t0, TCGv t1)
}
/* dest = T0 - T1. Compute C, N, V and Z flags */
-static void gen_sub_CC(TCGv dest, TCGv t0, TCGv t1)
+static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
- TCGv tmp;
+ TCGv_i32 tmp;
tcg_gen_sub_i32(cpu_NF, t0, t1);
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
@@ -465,18 +465,18 @@ static void gen_sub_CC(TCGv dest, TCGv t0, TCGv t1)
}
/* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
-static void gen_sbc_CC(TCGv dest, TCGv t0, TCGv t1)
+static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_not_i32(tmp, t1);
gen_adc_CC(dest, t0, tmp);
- tcg_temp_free(tmp);
+ tcg_temp_free_i32(tmp);
}
#define GEN_SHIFT(name) \
-static void gen_##name(TCGv dest, TCGv t0, TCGv t1) \
+static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
{ \
- TCGv tmp1, tmp2, tmp3; \
+ TCGv_i32 tmp1, tmp2, tmp3; \
tmp1 = tcg_temp_new_i32(); \
tcg_gen_andi_i32(tmp1, t1, 0xff); \
tmp2 = tcg_const_i32(0); \
@@ -492,9 +492,9 @@ GEN_SHIFT(shl)
GEN_SHIFT(shr)
#undef GEN_SHIFT
-static void gen_sar(TCGv dest, TCGv t0, TCGv t1)
+static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
- TCGv tmp1, tmp2;
+ TCGv_i32 tmp1, tmp2;
tmp1 = tcg_temp_new_i32();
tcg_gen_andi_i32(tmp1, t1, 0xff);
tmp2 = tcg_const_i32(0x1f);
@@ -504,17 +504,17 @@ static void gen_sar(TCGv dest, TCGv t0, TCGv t1)
tcg_temp_free_i32(tmp1);
}
-static void tcg_gen_abs_i32(TCGv dest, TCGv src)
+static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
{
- TCGv c0 = tcg_const_i32(0);
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 c0 = tcg_const_i32(0);
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_neg_i32(tmp, src);
tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
tcg_temp_free_i32(c0);
tcg_temp_free_i32(tmp);
}
-static void shifter_out_im(TCGv var, int shift)
+static void shifter_out_im(TCGv_i32 var, int shift)
{
if (shift == 0) {
tcg_gen_andi_i32(cpu_CF, var, 1);
@@ -527,7 +527,8 @@ static void shifter_out_im(TCGv var, int shift)
}
/* Shift by immediate. Includes special handling for shift == 0. */
-static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
+static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
+ int shift, int flags)
{
switch (shiftop) {
case 0: /* LSL */
@@ -564,7 +565,7 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
shifter_out_im(var, shift - 1);
tcg_gen_rotri_i32(var, var, shift); break;
} else {
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_shli_i32(tmp, cpu_CF, 31);
if (flags)
shifter_out_im(var, 0);
@@ -575,8 +576,8 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
}
};
-static inline void gen_arm_shift_reg(TCGv var, int shiftop,
- TCGv shift, int flags)
+static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
+ TCGv_i32 shift, int flags)
{
if (flags) {
switch (shiftop) {
@@ -612,7 +613,7 @@ static inline void gen_arm_shift_reg(TCGv var, int shiftop,
case 4: gen_pas_helper(glue(pfx,add8)); break; \
case 7: gen_pas_helper(glue(pfx,sub8)); break; \
}
-static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
+static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
{
TCGv_ptr tmp;
@@ -659,7 +660,7 @@ static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
case 5: gen_pas_helper(glue(pfx,sub16)); break; \
case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
}
-static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
+static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
{
TCGv_ptr tmp;
@@ -698,7 +699,7 @@ static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
static void gen_test_cc(int cc, int label)
{
- TCGv tmp;
+ TCGv_i32 tmp;
int inv;
switch (cc) {
@@ -792,7 +793,7 @@ static const uint8_t table_logic_cc[16] = {
/* Set PC and Thumb state from an immediate address. */
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
{
- TCGv tmp;
+ TCGv_i32 tmp;
s->is_jmp = DISAS_UPDATE;
if (s->thumb != (addr & 1)) {
@@ -805,7 +806,7 @@ static inline void gen_bx_im(DisasContext *s, uint32_t addr)
}
/* Set PC and Thumb state from var. var is marked as dead. */
-static inline void gen_bx(DisasContext *s, TCGv var)
+static inline void gen_bx(DisasContext *s, TCGv_i32 var)
{
s->is_jmp = DISAS_UPDATE;
tcg_gen_andi_i32(cpu_R[15], var, ~1);
@@ -817,7 +818,7 @@ static inline void gen_bx(DisasContext *s, TCGv var)
to r15 in ARM architecture v7 and above. The source must be a temporary
and will be marked as dead. */
static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
- int reg, TCGv var)
+ int reg, TCGv_i32 var)
{
if (reg == 15 && ENABLE_ARCH_7) {
gen_bx(s, var);
@@ -831,7 +832,7 @@ static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
* the results of a LDR/LDM/POP into r15, and corresponds to the cases
* in the ARM ARM which use the LoadWritePC() pseudocode function. */
static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
- int reg, TCGv var)
+ int reg, TCGv_i32 var)
{
if (reg == 15 && ENABLE_ARCH_5) {
gen_bx(s, var);
@@ -840,63 +841,6 @@ static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
}
}
-static inline TCGv gen_ld8s(TCGv addr, int index)
-{
- TCGv tmp = tcg_temp_new_i32();
- tcg_gen_qemu_ld8s(tmp, addr, index);
- return tmp;
-}
-static inline TCGv gen_ld8u(TCGv addr, int index)
-{
- TCGv tmp = tcg_temp_new_i32();
- tcg_gen_qemu_ld8u(tmp, addr, index);
- return tmp;
-}
-static inline TCGv gen_ld16s(TCGv addr, int index)
-{
- TCGv tmp = tcg_temp_new_i32();
- tcg_gen_qemu_ld16s(tmp, addr, index);
- return tmp;
-}
-static inline TCGv gen_ld16u(TCGv addr, int index)
-{
- TCGv tmp = tcg_temp_new_i32();
- tcg_gen_qemu_ld16u(tmp, addr, index);
- return tmp;
-}
-static inline TCGv gen_ld32(TCGv addr, int index)
-{
- TCGv tmp = tcg_temp_new_i32();
- tcg_gen_qemu_ld32u(tmp, addr, index);
- return tmp;
-}
-static inline TCGv_i64 gen_ld64(TCGv addr, int index)
-{
- TCGv_i64 tmp = tcg_temp_new_i64();
- tcg_gen_qemu_ld64(tmp, addr, index);
- return tmp;
-}
-static inline void gen_st8(TCGv val, TCGv addr, int index)
-{
- tcg_gen_qemu_st8(val, addr, index);
- tcg_temp_free_i32(val);
-}
-static inline void gen_st16(TCGv val, TCGv addr, int index)
-{
- tcg_gen_qemu_st16(val, addr, index);
- tcg_temp_free_i32(val);
-}
-static inline void gen_st32(TCGv val, TCGv addr, int index)
-{
- tcg_gen_qemu_st32(val, addr, index);
- tcg_temp_free_i32(val);
-}
-static inline void gen_st64(TCGv_i64 val, TCGv addr, int index)
-{
- tcg_gen_qemu_st64(val, addr, index);
- tcg_temp_free_i64(val);
-}
-
static inline void gen_set_pc_im(uint32_t val)
{
tcg_gen_movi_i32(cpu_R[15], val);
@@ -910,10 +854,10 @@ static inline void gen_lookup_tb(DisasContext *s)
}
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
- TCGv var)
+ TCGv_i32 var)
{
int val, rm, shift, shiftop;
- TCGv offset;
+ TCGv_i32 offset;
if (!(insn & (1 << 25))) {
/* immediate */
@@ -938,10 +882,10 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
}
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
- int extra, TCGv var)
+ int extra, TCGv_i32 var)
{
int val, rm;
- TCGv offset;
+ TCGv_i32 offset;
if (insn & (1 << 22)) {
/* immediate */
@@ -1104,7 +1048,7 @@ VFP_GEN_FTOI(tosiz)
#define VFP_GEN_FIX(name) \
static inline void gen_vfp_##name(int dp, int shift, int neon) \
{ \
- TCGv tmp_shift = tcg_const_i32(shift); \
+ TCGv_i32 tmp_shift = tcg_const_i32(shift); \
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
if (dp) { \
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
@@ -1124,7 +1068,7 @@ VFP_GEN_FIX(uhto)
VFP_GEN_FIX(ulto)
#undef VFP_GEN_FIX
-static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv addr)
+static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
{
if (dp)
tcg_gen_qemu_ld64(cpu_F0d, addr, IS_USER(s));
@@ -1132,7 +1076,7 @@ static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv addr)
tcg_gen_qemu_ld32u(cpu_F0s, addr, IS_USER(s));
}
-static inline void gen_vfp_st(DisasContext *s, int dp, TCGv addr)
+static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
{
if (dp)
tcg_gen_qemu_st64(cpu_F0d, addr, IS_USER(s));
@@ -1164,14 +1108,14 @@ neon_reg_offset (int reg, int n)
return vfp_reg_offset(0, sreg);
}
-static TCGv neon_load_reg(int reg, int pass)
+static TCGv_i32 neon_load_reg(int reg, int pass)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
return tmp;
}
-static void neon_store_reg(int reg, int pass, TCGv var)
+static void neon_store_reg(int reg, int pass, TCGv_i32 var)
{
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
tcg_temp_free_i32(var);
@@ -1228,14 +1172,14 @@ static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
}
-static inline TCGv iwmmxt_load_creg(int reg)
+static inline TCGv_i32 iwmmxt_load_creg(int reg)
{
- TCGv var = tcg_temp_new_i32();
+ TCGv_i32 var = tcg_temp_new_i32();
tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
return var;
}
-static inline void iwmmxt_store_creg(int reg, TCGv var)
+static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
{
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
tcg_temp_free_i32(var);
@@ -1353,7 +1297,7 @@ IWMMXT_OP_ENV(packsq)
static void gen_op_iwmmxt_set_mup(void)
{
- TCGv tmp;
+ TCGv_i32 tmp;
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
tcg_gen_ori_i32(tmp, tmp, 2);
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
@@ -1361,7 +1305,7 @@ static void gen_op_iwmmxt_set_mup(void)
static void gen_op_iwmmxt_set_cup(void)
{
- TCGv tmp;
+ TCGv_i32 tmp;
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
tcg_gen_ori_i32(tmp, tmp, 1);
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
@@ -1369,7 +1313,7 @@ static void gen_op_iwmmxt_set_cup(void)
static void gen_op_iwmmxt_setpsr_nz(void)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
}
@@ -1381,11 +1325,12 @@ static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
}
-static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
+static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
+ TCGv_i32 dest)
{
int rd;
uint32_t offset;
- TCGv tmp;
+ TCGv_i32 tmp;
rd = (insn >> 16) & 0xf;
tmp = load_reg(s, rd);
@@ -1415,10 +1360,10 @@ static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
return 0;
}
-static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest)
+static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
{
int rd = (insn >> 0) & 0xf;
- TCGv tmp;
+ TCGv_i32 tmp;
if (insn & (1 << 8)) {
if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
@@ -1443,8 +1388,8 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
{
int rd, wrd;
int rdhi, rdlo, rd0, rd1, i;
- TCGv addr;
- TCGv tmp, tmp2, tmp3;
+ TCGv_i32 addr;
+ TCGv_i32 tmp, tmp2, tmp3;
if ((insn & 0x0e000e00) == 0x0c000000) {
if ((insn & 0x0fe00ff0) == 0x0c400000) {
@@ -1482,13 +1427,15 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
tcg_gen_qemu_ld64(cpu_M0, addr, IS_USER(s));
i = 0;
} else { /* WLDRW wRd */
- tmp = gen_ld32(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
}
} else {
+ tmp = tcg_temp_new_i32();
if (insn & (1 << 22)) { /* WLDRH */
- tmp = gen_ld16u(addr, IS_USER(s));
+ tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
} else { /* WLDRB */
- tmp = gen_ld8u(addr, IS_USER(s));
+ tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
}
}
if (i) {
@@ -1500,28 +1447,28 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
} else {
if ((insn >> 28) == 0xf) { /* WSTRW wCx */
tmp = iwmmxt_load_creg(wrd);
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
} else {
gen_op_iwmmxt_movq_M0_wRn(wrd);
tmp = tcg_temp_new_i32();
if (insn & (1 << 8)) {
if (insn & (1 << 22)) { /* WSTRD */
- tcg_temp_free_i32(tmp);
tcg_gen_qemu_st64(cpu_M0, addr, IS_USER(s));
} else { /* WSTRW wRd */
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
}
} else {
if (insn & (1 << 22)) { /* WSTRH */
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
- gen_st16(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
} else { /* WSTRB */
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
- gen_st8(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
}
}
}
+ tcg_temp_free_i32(tmp);
}
tcg_temp_free_i32(addr);
return 0;
@@ -1796,12 +1743,12 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
tmp3 = tcg_const_i32((insn & 1) << 5);
break;
default:
- TCGV_UNUSED(tmp2);
- TCGV_UNUSED(tmp3);
+ TCGV_UNUSED_I32(tmp2);
+ TCGV_UNUSED_I32(tmp3);
}
gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
- tcg_temp_free(tmp3);
- tcg_temp_free(tmp2);
+ tcg_temp_free_i32(tmp3);
+ tcg_temp_free_i32(tmp2);
tcg_temp_free_i32(tmp);
gen_op_iwmmxt_movq_wRn_M0(wrd);
gen_op_iwmmxt_set_mup();
@@ -2260,7 +2207,7 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
tmp = tcg_const_i32((insn >> 20) & 3);
iwmmxt_load_reg(cpu_V1, rd1);
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
- tcg_temp_free(tmp);
+ tcg_temp_free_i32(tmp);
gen_op_iwmmxt_movq_wRn_M0(wrd);
gen_op_iwmmxt_set_mup();
break;
@@ -2316,7 +2263,7 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
gen_op_iwmmxt_movq_M0_wRn(rd0);
tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
- tcg_temp_free(tmp);
+ tcg_temp_free_i32(tmp);
gen_op_iwmmxt_movq_wRn_M0(wrd);
gen_op_iwmmxt_set_mup();
gen_op_iwmmxt_set_cup();
@@ -2446,7 +2393,7 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
{
int acc, rd0, rd1, rdhi, rdlo;
- TCGv tmp, tmp2;
+ TCGv_i32 tmp, tmp2;
if ((insn & 0x0ff00f10) == 0x0e200010) {
/* Multiply with Internal Accumulate Format */
@@ -2532,22 +2479,22 @@ static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
/* Move between integer and VFP cores. */
-static TCGv gen_vfp_mrs(void)
+static TCGv_i32 gen_vfp_mrs(void)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_mov_i32(tmp, cpu_F0s);
return tmp;
}
-static void gen_vfp_msr(TCGv tmp)
+static void gen_vfp_msr(TCGv_i32 tmp)
{
tcg_gen_mov_i32(cpu_F0s, tmp);
tcg_temp_free_i32(tmp);
}
-static void gen_neon_dup_u8(TCGv var, int shift)
+static void gen_neon_dup_u8(TCGv_i32 var, int shift)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
if (shift)
tcg_gen_shri_i32(var, var, shift);
tcg_gen_ext8u_i32(var, var);
@@ -2558,39 +2505,39 @@ static void gen_neon_dup_u8(TCGv var, int shift)
tcg_temp_free_i32(tmp);
}
-static void gen_neon_dup_low16(TCGv var)
+static void gen_neon_dup_low16(TCGv_i32 var)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_ext16u_i32(var, var);
tcg_gen_shli_i32(tmp, var, 16);
tcg_gen_or_i32(var, var, tmp);
tcg_temp_free_i32(tmp);
}
-static void gen_neon_dup_high16(TCGv var)
+static void gen_neon_dup_high16(TCGv_i32 var)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_andi_i32(var, var, 0xffff0000);
tcg_gen_shri_i32(tmp, var, 16);
tcg_gen_or_i32(var, var, tmp);
tcg_temp_free_i32(tmp);
}
-static TCGv gen_load_and_replicate(DisasContext *s, TCGv addr, int size)
+static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
{
/* Load a single Neon element and replicate into a 32 bit TCG reg */
- TCGv tmp;
+ TCGv_i32 tmp = tcg_temp_new_i32();
switch (size) {
case 0:
- tmp = gen_ld8u(addr, IS_USER(s));
+ tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
gen_neon_dup_u8(tmp, 0);
break;
case 1:
- tmp = gen_ld16u(addr, IS_USER(s));
+ tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
gen_neon_dup_low16(tmp);
break;
case 2:
- tmp = gen_ld32(addr, IS_USER(s));
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
break;
default: /* Avoid compiler warnings. */
abort();
@@ -2604,9 +2551,9 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
{
uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
int dp, veclen;
- TCGv addr;
- TCGv tmp;
- TCGv tmp2;
+ TCGv_i32 addr;
+ TCGv_i32 tmp;
+ TCGv_i32 tmp2;
if (!arm_feature(env, ARM_FEATURE_VFP))
return 1;
@@ -3428,7 +3375,7 @@ static inline void gen_jmp (DisasContext *s, uint32_t dest)
}
}
-static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
+static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
{
if (x)
tcg_gen_sari_i32(t0, t0, 16);
@@ -3475,9 +3422,9 @@ static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr)
}
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
-static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
+static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
{
- TCGv tmp;
+ TCGv_i32 tmp;
if (spsr) {
/* ??? This is also undefined in system mode. */
if (IS_USER(s))
@@ -3499,16 +3446,16 @@ static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
/* Returns nonzero if access to the PSR is not permitted. */
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
{
- TCGv tmp;
+ TCGv_i32 tmp;
tmp = tcg_temp_new_i32();
tcg_gen_movi_i32(tmp, val);
return gen_set_psr(s, mask, spsr, tmp);
}
/* Generate an old-style exception return. Marks pc as dead. */
-static void gen_exception_return(DisasContext *s, TCGv pc)
+static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
{
- TCGv tmp;
+ TCGv_i32 tmp;
store_reg(s, 15, pc);
tmp = load_cpu_field(spsr);
gen_set_cpsr(tmp, 0xffffffff);
@@ -3517,7 +3464,7 @@ static void gen_exception_return(DisasContext *s, TCGv pc)
}
/* Generate a v6 exception return. Marks both values as dead. */
-static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
+static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
{
gen_set_cpsr(cpsr, 0xffffffff);
tcg_temp_free_i32(cpsr);
@@ -3530,7 +3477,7 @@ gen_set_condexec (DisasContext *s)
{
if (s->condexec_mask) {
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_movi_i32(tmp, val);
store_cpu_field(tmp, condexec_bits);
}
@@ -3561,7 +3508,7 @@ static void gen_nop_hint(DisasContext *s, int val)
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
-static inline void gen_neon_add(int size, TCGv t0, TCGv t1)
+static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
{
switch (size) {
case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
@@ -3571,7 +3518,7 @@ static inline void gen_neon_add(int size, TCGv t0, TCGv t1)
}
}
-static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
+static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
{
switch (size) {
case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
@@ -3633,22 +3580,22 @@ static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
default: return 1; \
}} while (0)
-static TCGv neon_load_scratch(int scratch)
+static TCGv_i32 neon_load_scratch(int scratch)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
return tmp;
}
-static void neon_store_scratch(int scratch, TCGv var)
+static void neon_store_scratch(int scratch, TCGv_i32 var)
{
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
tcg_temp_free_i32(var);
}
-static inline TCGv neon_get_scalar(int size, int reg)
+static inline TCGv_i32 neon_get_scalar(int size, int reg)
{
- TCGv tmp;
+ TCGv_i32 tmp;
if (size == 1) {
tmp = neon_load_reg(reg & 7, reg >> 4);
if (reg & 8) {
@@ -3664,7 +3611,7 @@ static inline TCGv neon_get_scalar(int size, int reg)
static int gen_neon_unzip(int rd, int rm, int size, int q)
{
- TCGv tmp, tmp2;
+ TCGv_i32 tmp, tmp2;
if (!q && size == 2) {
return 1;
}
@@ -3703,7 +3650,7 @@ static int gen_neon_unzip(int rd, int rm, int size, int q)
static int gen_neon_zip(int rd, int rm, int size, int q)
{
- TCGv tmp, tmp2;
+ TCGv_i32 tmp, tmp2;
if (!q && size == 2) {
return 1;
}
@@ -3740,9 +3687,9 @@ static int gen_neon_zip(int rd, int rm, int size, int q)
return 0;
}
-static void gen_neon_trn_u8(TCGv t0, TCGv t1)
+static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
{
- TCGv rd, tmp;
+ TCGv_i32 rd, tmp;
rd = tcg_temp_new_i32();
tmp = tcg_temp_new_i32();
@@ -3762,9 +3709,9 @@ static void gen_neon_trn_u8(TCGv t0, TCGv t1)
tcg_temp_free_i32(rd);
}
-static void gen_neon_trn_u16(TCGv t0, TCGv t1)
+static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
{
- TCGv rd, tmp;
+ TCGv_i32 rd, tmp;
rd = tcg_temp_new_i32();
tmp = tcg_temp_new_i32();
@@ -3816,9 +3763,9 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
int load;
int shift;
int n;
- TCGv addr;
- TCGv tmp;
- TCGv tmp2;
+ TCGv_i32 addr;
+ TCGv_i32 tmp;
+ TCGv_i32 tmp2;
TCGv_i64 tmp64;
if (!s->vfp_enabled)
@@ -3865,32 +3812,36 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
tcg_gen_addi_i32(addr, addr, 1 << size);
}
if (size == 3) {
+ tmp64 = tcg_temp_new_i64();
if (load) {
- tmp64 = gen_ld64(addr, IS_USER(s));
+ tcg_gen_qemu_ld64(tmp64, addr, IS_USER(s));
neon_store_reg64(tmp64, rd);
- tcg_temp_free_i64(tmp64);
} else {
- tmp64 = tcg_temp_new_i64();
neon_load_reg64(tmp64, rd);
- gen_st64(tmp64, addr, IS_USER(s));
+ tcg_gen_qemu_st64(tmp64, addr, IS_USER(s));
}
+ tcg_temp_free_i64(tmp64);
tcg_gen_addi_i32(addr, addr, stride);
} else {
for (pass = 0; pass < 2; pass++) {
if (size == 2) {
if (load) {
- tmp = gen_ld32(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
neon_store_reg(rd, pass, tmp);
} else {
tmp = neon_load_reg(rd, pass);
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
}
tcg_gen_addi_i32(addr, addr, stride);
} else if (size == 1) {
if (load) {
- tmp = gen_ld16u(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
tcg_gen_addi_i32(addr, addr, stride);
- tmp2 = gen_ld16u(addr, IS_USER(s));
+ tmp2 = tcg_temp_new_i32();
+ tcg_gen_qemu_ld16u(tmp2, addr, IS_USER(s));
tcg_gen_addi_i32(addr, addr, stride);
tcg_gen_shli_i32(tmp2, tmp2, 16);
tcg_gen_or_i32(tmp, tmp, tmp2);
@@ -3900,16 +3851,19 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
tmp = neon_load_reg(rd, pass);
tmp2 = tcg_temp_new_i32();
tcg_gen_shri_i32(tmp2, tmp, 16);
- gen_st16(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
tcg_gen_addi_i32(addr, addr, stride);
- gen_st16(tmp2, addr, IS_USER(s));
+ tcg_gen_qemu_st16(tmp2, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp2);
tcg_gen_addi_i32(addr, addr, stride);
}
} else /* size == 0 */ {
if (load) {
- TCGV_UNUSED(tmp2);
+ TCGV_UNUSED_I32(tmp2);
for (n = 0; n < 4; n++) {
- tmp = gen_ld8u(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
tcg_gen_addi_i32(addr, addr, stride);
if (n == 0) {
tmp2 = tmp;
@@ -3929,7 +3883,8 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
} else {
tcg_gen_shri_i32(tmp, tmp2, n * 8);
}
- gen_st8(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
tcg_gen_addi_i32(addr, addr, stride);
}
tcg_temp_free_i32(tmp2);
@@ -4049,15 +4004,16 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
load_reg_var(s, addr, rn);
for (reg = 0; reg < nregs; reg++) {
if (load) {
+ tmp = tcg_temp_new_i32();
switch (size) {
case 0:
- tmp = gen_ld8u(addr, IS_USER(s));
+ tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
break;
case 1:
- tmp = gen_ld16u(addr, IS_USER(s));
+ tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
break;
case 2:
- tmp = gen_ld32(addr, IS_USER(s));
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
break;
default: /* Avoid compiler warnings. */
abort();
@@ -4075,15 +4031,16 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
tcg_gen_shri_i32(tmp, tmp, shift);
switch (size) {
case 0:
- gen_st8(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
break;
case 1:
- gen_st16(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
break;
case 2:
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
break;
}
+ tcg_temp_free_i32(tmp);
}
rd += stride;
tcg_gen_addi_i32(addr, addr, 1 << size);
@@ -4093,13 +4050,13 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
}
}
if (rm != 15) {
- TCGv base;
+ TCGv_i32 base;
base = load_reg(s, rn);
if (rm == 13) {
tcg_gen_addi_i32(base, base, stride);
} else {
- TCGv index;
+ TCGv_i32 index;
index = load_reg(s, rm);
tcg_gen_add_i32(base, base, index);
tcg_temp_free_i32(index);
@@ -4110,14 +4067,14 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
}
/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
-static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
+static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
{
tcg_gen_and_i32(t, t, c);
tcg_gen_andc_i32(f, f, c);
tcg_gen_or_i32(dest, t, f);
}
-static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
+static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
{
switch (size) {
case 0: gen_helper_neon_narrow_u8(dest, src); break;
@@ -4127,7 +4084,7 @@ static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
}
}
-static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
+static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
{
switch (size) {
case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
@@ -4137,7 +4094,7 @@ static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
}
}
-static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
+static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
{
switch (size) {
case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
@@ -4147,7 +4104,7 @@ static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
}
}
-static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
+static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
{
switch (size) {
case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
@@ -4157,7 +4114,7 @@ static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
}
}
-static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
+static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
int q, int u)
{
if (q) {
@@ -4191,7 +4148,7 @@ static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
}
}
-static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
+static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
{
if (u) {
switch (size) {
@@ -4252,7 +4209,8 @@ static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
}
}
-static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
+static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
+ int size, int u)
{
TCGv_i64 tmp;
@@ -4282,7 +4240,8 @@ static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
}
}
-static void gen_neon_narrow_op(int op, int u, int size, TCGv dest, TCGv_i64 src)
+static void gen_neon_narrow_op(int op, int u, int size,
+ TCGv_i32 dest, TCGv_i64 src)
{
if (op) {
if (u) {
@@ -4493,7 +4452,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
int pairwise;
int u;
uint32_t imm, mask;
- TCGv tmp, tmp2, tmp3, tmp4, tmp5;
+ TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
TCGv_i64 tmp64;
if (!s->vfp_enabled)
@@ -5450,11 +5409,11 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
tmp = neon_load_reg(rn, 1);
neon_store_scratch(2, tmp);
}
- TCGV_UNUSED(tmp3);
+ TCGV_UNUSED_I32(tmp3);
for (pass = 0; pass < 2; pass++) {
if (src1_wide) {
neon_load_reg64(cpu_V0, rn + pass);
- TCGV_UNUSED(tmp);
+ TCGV_UNUSED_I32(tmp);
} else {
if (pass == 1 && rd == rn) {
tmp = neon_load_scratch(2);
@@ -5467,7 +5426,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
}
if (src2_wide) {
neon_load_reg64(cpu_V1, rm + pass);
- TCGV_UNUSED(tmp2);
+ TCGV_UNUSED_I32(tmp2);
} else {
if (pass == 1 && rd == rm) {
tmp2 = neon_load_scratch(2);
@@ -5881,7 +5840,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
if (rm & 1) {
return 1;
}
- TCGV_UNUSED(tmp2);
+ TCGV_UNUSED_I32(tmp2);
for (pass = 0; pass < 2; pass++) {
neon_load_reg64(cpu_V0, rm + pass);
tmp = tcg_temp_new_i32();
@@ -5963,7 +5922,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
if (neon_2rm_is_float_op(op)) {
tcg_gen_ld_f32(cpu_F0s, cpu_env,
neon_reg_offset(rm, pass));
- TCGV_UNUSED(tmp);
+ TCGV_UNUSED_I32(tmp);
} else {
tmp = neon_load_reg(rm, pass);
}
@@ -6036,7 +5995,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
default: abort();
}
- tcg_temp_free(tmp2);
+ tcg_temp_free_i32(tmp2);
if (op == NEON_2RM_VCLE0) {
tcg_gen_not_i32(tmp, tmp);
}
@@ -6049,7 +6008,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
default: abort();
}
- tcg_temp_free(tmp2);
+ tcg_temp_free_i32(tmp2);
if (op == NEON_2RM_VCLT0) {
tcg_gen_not_i32(tmp, tmp);
}
@@ -6062,7 +6021,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
default: abort();
}
- tcg_temp_free(tmp2);
+ tcg_temp_free_i32(tmp2);
break;
case NEON_2RM_VABS:
switch(size) {
@@ -6075,14 +6034,14 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
case NEON_2RM_VNEG:
tmp2 = tcg_const_i32(0);
gen_neon_rsb(size, tmp, tmp2);
- tcg_temp_free(tmp2);
+ tcg_temp_free_i32(tmp2);
break;
case NEON_2RM_VCGT0_F:
{
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
tmp2 = tcg_const_i32(0);
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
- tcg_temp_free(tmp2);
+ tcg_temp_free_i32(tmp2);
tcg_temp_free_ptr(fpstatus);
break;
}
@@ -6091,7 +6050,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
tmp2 = tcg_const_i32(0);
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
- tcg_temp_free(tmp2);
+ tcg_temp_free_i32(tmp2);
tcg_temp_free_ptr(fpstatus);
break;
}
@@ -6100,7 +6059,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
tmp2 = tcg_const_i32(0);
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
- tcg_temp_free(tmp2);
+ tcg_temp_free_i32(tmp2);
tcg_temp_free_ptr(fpstatus);
break;
}
@@ -6109,7 +6068,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
tmp2 = tcg_const_i32(0);
gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
- tcg_temp_free(tmp2);
+ tcg_temp_free_i32(tmp2);
tcg_temp_free_ptr(fpstatus);
break;
}
@@ -6118,7 +6077,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
tmp2 = tcg_const_i32(0);
gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
- tcg_temp_free(tmp2);
+ tcg_temp_free_i32(tmp2);
tcg_temp_free_ptr(fpstatus);
break;
}
@@ -6346,7 +6305,7 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tmp64);
store_reg(s, rt2, tmp);
} else {
- TCGv tmp;
+ TCGv_i32 tmp;
if (ri->type & ARM_CP_CONST) {
tmp = tcg_const_i32(ri->resetvalue);
} else if (ri->readfn) {
@@ -6377,7 +6336,7 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
}
if (is64) {
- TCGv tmplo, tmphi;
+ TCGv_i32 tmplo, tmphi;
TCGv_i64 tmp64 = tcg_temp_new_i64();
tmplo = load_reg(s, rt);
tmphi = load_reg(s, rt2);
@@ -6395,7 +6354,7 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tmp64);
} else {
if (ri->writefn) {
- TCGv tmp;
+ TCGv_i32 tmp;
TCGv_ptr tmpptr;
gen_set_pc_im(s->pc);
tmp = load_reg(s, rt);
@@ -6404,7 +6363,7 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
tcg_temp_free_ptr(tmpptr);
tcg_temp_free_i32(tmp);
} else {
- TCGv tmp = load_reg(s, rt);
+ TCGv_i32 tmp = load_reg(s, rt);
store_cpu_offset(tmp, ri->fieldoffset);
}
}
@@ -6426,7 +6385,7 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
/* Store a 64-bit value to a register pair. Clobbers val. */
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
{
- TCGv tmp;
+ TCGv_i32 tmp;
tmp = tcg_temp_new_i32();
tcg_gen_trunc_i64_i32(tmp, val);
store_reg(s, rlow, tmp);
@@ -6440,7 +6399,7 @@ static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
{
TCGv_i64 tmp;
- TCGv tmp2;
+ TCGv_i32 tmp2;
/* Load value and extend to 64 bits. */
tmp = tcg_temp_new_i64();
@@ -6455,8 +6414,8 @@ static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
{
TCGv_i64 tmp;
- TCGv tmpl;
- TCGv tmph;
+ TCGv_i32 tmpl;
+ TCGv_i32 tmph;
/* Load 64-bit value rd:rn. */
tmpl = load_reg(s, rlow);
@@ -6470,7 +6429,7 @@ static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
}
/* Set N and Z flags from hi|lo. */
-static void gen_logicq_cc(TCGv lo, TCGv hi)
+static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
{
tcg_gen_mov_i32(cpu_NF, hi);
tcg_gen_or_i32(cpu_ZF, lo, hi);
@@ -6486,20 +6445,20 @@ static void gen_logicq_cc(TCGv lo, TCGv hi)
this sequence is effectively atomic. In user emulation mode we
throw an exception and handle the atomic operation elsewhere. */
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
- TCGv addr, int size)
+ TCGv_i32 addr, int size)
{
- TCGv tmp;
+ TCGv_i32 tmp = tcg_temp_new_i32();
switch (size) {
case 0:
- tmp = gen_ld8u(addr, IS_USER(s));
+ tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
break;
case 1:
- tmp = gen_ld16u(addr, IS_USER(s));
+ tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
break;
case 2:
case 3:
- tmp = gen_ld32(addr, IS_USER(s));
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
break;
default:
abort();
@@ -6507,9 +6466,10 @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
tcg_gen_mov_i32(cpu_exclusive_val, tmp);
store_reg(s, rt, tmp);
if (size == 3) {
- TCGv tmp2 = tcg_temp_new_i32();
+ TCGv_i32 tmp2 = tcg_temp_new_i32();
tcg_gen_addi_i32(tmp2, addr, 4);
- tmp = gen_ld32(tmp2, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, tmp2, IS_USER(s));
tcg_temp_free_i32(tmp2);
tcg_gen_mov_i32(cpu_exclusive_high, tmp);
store_reg(s, rt2, tmp);
@@ -6524,7 +6484,7 @@ static void gen_clrex(DisasContext *s)
#ifdef CONFIG_USER_ONLY
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
- TCGv addr, int size)
+ TCGv_i32 addr, int size)
{
tcg_gen_mov_i32(cpu_exclusive_test, addr);
tcg_gen_movi_i32(cpu_exclusive_info,
@@ -6533,9 +6493,9 @@ 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 addr, int size)
+ TCGv_i32 addr, int size)
{
- TCGv tmp;
+ TCGv_i32 tmp;
int done_label;
int fail_label;
@@ -6548,16 +6508,17 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
fail_label = gen_new_label();
done_label = gen_new_label();
tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
+ tmp = tcg_temp_new_i32();
switch (size) {
case 0:
- tmp = gen_ld8u(addr, IS_USER(s));
+ tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
break;
case 1:
- tmp = gen_ld16u(addr, IS_USER(s));
+ tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
break;
case 2:
case 3:
- tmp = gen_ld32(addr, IS_USER(s));
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
break;
default:
abort();
@@ -6565,9 +6526,10 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
tcg_temp_free_i32(tmp);
if (size == 3) {
- TCGv tmp2 = tcg_temp_new_i32();
+ TCGv_i32 tmp2 = tcg_temp_new_i32();
tcg_gen_addi_i32(tmp2, addr, 4);
- tmp = gen_ld32(tmp2, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, tmp2, IS_USER(s));
tcg_temp_free_i32(tmp2);
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
tcg_temp_free_i32(tmp);
@@ -6575,22 +6537,24 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
tmp = load_reg(s, rt);
switch (size) {
case 0:
- gen_st8(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
break;
case 1:
- gen_st16(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
break;
case 2:
case 3:
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
break;
default:
abort();
}
+ tcg_temp_free_i32(tmp);
if (size == 3) {
tcg_gen_addi_i32(addr, addr, 4);
tmp = load_reg(s, rt2);
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
}
tcg_gen_movi_i32(cpu_R[rd], 0);
tcg_gen_br(done_label);
@@ -6636,10 +6600,12 @@ static void gen_srs(DisasContext *s,
}
tcg_gen_addi_i32(addr, addr, offset);
tmp = load_reg(s, 14);
- gen_st32(tmp, addr, 0);
+ tcg_gen_qemu_st32(tmp, addr, 0);
+ tcg_temp_free_i32(tmp);
tmp = load_cpu_field(spsr);
tcg_gen_addi_i32(addr, addr, 4);
- gen_st32(tmp, addr, 0);
+ tcg_gen_qemu_st32(tmp, addr, 0);
+ tcg_temp_free_i32(tmp);
if (writeback) {
switch (amode) {
case 0:
@@ -6668,10 +6634,10 @@ static void gen_srs(DisasContext *s,
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
{
unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
- TCGv tmp;
- TCGv tmp2;
- TCGv tmp3;
- TCGv addr;
+ TCGv_i32 tmp;
+ TCGv_i32 tmp2;
+ TCGv_i32 tmp3;
+ TCGv_i32 addr;
TCGv_i64 tmp64;
insn = arm_ldl_code(env, s->pc, s->bswap_code);
@@ -6782,9 +6748,11 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
if (offset)
tcg_gen_addi_i32(addr, addr, offset);
/* Load PC into tmp and CPSR into tmp2. */
- tmp = gen_ld32(addr, 0);
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, 0);
tcg_gen_addi_i32(addr, addr, 4);
- tmp2 = gen_ld32(addr, 0);
+ tmp2 = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, 0);
if (insn & (1 << 21)) {
/* Base writeback. */
switch (i) {
@@ -7084,7 +7052,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
rn = (insn >> 16) & 0xf;
tmp = load_reg(s, rn);
} else {
- TCGV_UNUSED(tmp);
+ TCGV_UNUSED_I32(tmp);
}
rd = (insn >> 12) & 0xf;
switch(op1) {
@@ -7285,11 +7253,11 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
}
if (insn & (1 << 21)) { /* mult accumulate */
- TCGv al = load_reg(s, rn);
- TCGv ah = load_reg(s, rd);
+ TCGv_i32 al = load_reg(s, rn);
+ TCGv_i32 ah = load_reg(s, rd);
tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
- tcg_temp_free(al);
- tcg_temp_free(ah);
+ tcg_temp_free_i32(al);
+ tcg_temp_free_i32(ah);
}
if (insn & (1 << 20)) {
gen_logicq_cc(tmp, tmp2);
@@ -7348,7 +7316,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
abort();
}
}
- tcg_temp_free(addr);
+ tcg_temp_free_i32(addr);
} else {
/* SWP instruction */
rm = (insn) & 0xf;
@@ -7358,13 +7326,15 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
so it is good enough. */
addr = load_reg(s, rn);
tmp = load_reg(s, rm);
+ tmp2 = tcg_temp_new_i32();
if (insn & (1 << 22)) {
- tmp2 = gen_ld8u(addr, IS_USER(s));
- gen_st8(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_ld8u(tmp2, addr, IS_USER(s));
+ tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
} else {
- tmp2 = gen_ld32(addr, IS_USER(s));
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_ld32u(tmp2, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
}
+ tcg_temp_free_i32(tmp);
tcg_temp_free_i32(addr);
store_reg(s, rd, tmp2);
}
@@ -7381,16 +7351,17 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
address_offset = 0;
if (insn & (1 << 20)) {
/* load */
+ tmp = tcg_temp_new_i32();
switch(sh) {
case 1:
- tmp = gen_ld16u(addr, IS_USER(s));
+ tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
break;
case 2:
- tmp = gen_ld8s(addr, IS_USER(s));
+ tcg_gen_qemu_ld8s(tmp, addr, IS_USER(s));
break;
default:
case 3:
- tmp = gen_ld16s(addr, IS_USER(s));
+ tcg_gen_qemu_ld16s(tmp, addr, IS_USER(s));
break;
}
load = 1;
@@ -7400,17 +7371,21 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
if (sh & 1) {
/* store */
tmp = load_reg(s, rd);
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
tcg_gen_addi_i32(addr, addr, 4);
tmp = load_reg(s, rd + 1);
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
load = 0;
} else {
/* load */
- tmp = gen_ld32(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
store_reg(s, rd, tmp);
tcg_gen_addi_i32(addr, addr, 4);
- tmp = gen_ld32(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
rd++;
load = 1;
}
@@ -7418,7 +7393,8 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
} else {
/* store */
tmp = load_reg(s, rd);
- gen_st16(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
load = 0;
}
/* Perform base writeback before the loaded value to
@@ -7748,18 +7724,21 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
gen_add_data_offset(s, insn, tmp2);
if (insn & (1 << 20)) {
/* load */
+ tmp = tcg_temp_new_i32();
if (insn & (1 << 22)) {
- tmp = gen_ld8u(tmp2, i);
+ tcg_gen_qemu_ld8u(tmp, tmp2, i);
} else {
- tmp = gen_ld32(tmp2, i);
+ tcg_gen_qemu_ld32u(tmp, tmp2, i);
}
} else {
/* store */
tmp = load_reg(s, rd);
- if (insn & (1 << 22))
- gen_st8(tmp, tmp2, i);
- else
- gen_st32(tmp, tmp2, i);
+ if (insn & (1 << 22)) {
+ tcg_gen_qemu_st8(tmp, tmp2, i);
+ } else {
+ tcg_gen_qemu_st32(tmp, tmp2, i);
+ }
+ tcg_temp_free_i32(tmp);
}
if (!(insn & (1 << 24))) {
gen_add_data_offset(s, insn, tmp2);
@@ -7778,7 +7757,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
case 0x09:
{
int j, n, user, loaded_base;
- TCGv loaded_var;
+ TCGv_i32 loaded_var;
/* load/store multiple words */
/* XXX: store correct base if write back */
user = 0;
@@ -7794,7 +7773,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
/* compute total size */
loaded_base = 0;
- TCGV_UNUSED(loaded_var);
+ TCGV_UNUSED_I32(loaded_var);
n = 0;
for(i=0;i<16;i++) {
if (insn & (1 << i))
@@ -7823,7 +7802,8 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
if (insn & (1 << i)) {
if (insn & (1 << 20)) {
/* load */
- tmp = gen_ld32(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
if (user) {
tmp2 = tcg_const_i32(i);
gen_helper_set_user_reg(cpu_env, tmp2, tmp);
@@ -7850,7 +7830,8 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
} else {
tmp = load_reg(s, i);
}
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
}
j++;
/* no need to add after the last transfer */
@@ -7944,7 +7925,8 @@ thumb2_logic_op(int op)
Returns zero if the opcode is valid. */
static int
-gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
+gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
+ TCGv_i32 t0, TCGv_i32 t1)
{
int logic_cc;
@@ -8018,10 +8000,10 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
{
uint32_t insn, imm, shift, offset;
uint32_t rd, rn, rm, rs;
- TCGv tmp;
- TCGv tmp2;
- TCGv tmp3;
- TCGv addr;
+ TCGv_i32 tmp;
+ TCGv_i32 tmp2;
+ TCGv_i32 tmp3;
+ TCGv_i32 addr;
TCGv_i64 tmp64;
int op;
int shiftop;
@@ -8106,18 +8088,22 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
}
if (insn & (1 << 20)) {
/* ldrd */
- tmp = gen_ld32(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
store_reg(s, rs, tmp);
tcg_gen_addi_i32(addr, addr, 4);
- tmp = gen_ld32(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
store_reg(s, rd, tmp);
} else {
/* strd */
tmp = load_reg(s, rs);
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
tcg_gen_addi_i32(addr, addr, 4);
tmp = load_reg(s, rd);
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
}
if (insn & (1 << 21)) {
/* Base writeback. */
@@ -8130,7 +8116,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
}
} else if ((insn & (1 << 23)) == 0) {
/* Load/store exclusive word. */
- addr = tcg_temp_local_new();
+ addr = tcg_temp_local_new_i32();
load_reg_var(s, addr, rn);
tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
if (insn & (1 << 20)) {
@@ -8138,7 +8124,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
} else {
gen_store_exclusive(s, rd, rs, 15, addr, 2);
}
- tcg_temp_free(addr);
+ tcg_temp_free_i32(addr);
} else if ((insn & (1 << 6)) == 0) {
/* Table Branch. */
if (rn == 15) {
@@ -8153,10 +8139,12 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
/* tbh */
tcg_gen_add_i32(addr, addr, tmp);
tcg_temp_free_i32(tmp);
- tmp = gen_ld16u(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
} else { /* tbb */
tcg_temp_free_i32(tmp);
- tmp = gen_ld8u(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
}
tcg_temp_free_i32(addr);
tcg_gen_shli_i32(tmp, tmp, 1);
@@ -8169,14 +8157,14 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
if (op == 2) {
goto illegal_op;
}
- addr = tcg_temp_local_new();
+ addr = tcg_temp_local_new_i32();
load_reg_var(s, addr, rn);
if (insn & (1 << 20)) {
gen_load_exclusive(s, rs, rd, addr, op);
} else {
gen_store_exclusive(s, rm, rs, rd, addr, op);
}
- tcg_temp_free(addr);
+ tcg_temp_free_i32(addr);
}
} else {
/* Load/store multiple, RFE, SRS. */
@@ -8191,9 +8179,11 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
if ((insn & (1 << 24)) == 0)
tcg_gen_addi_i32(addr, addr, -8);
/* Load PC into tmp and CPSR into tmp2. */
- tmp = gen_ld32(addr, 0);
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, 0);
tcg_gen_addi_i32(addr, addr, 4);
- tmp2 = gen_ld32(addr, 0);
+ tmp2 = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp2, addr, 0);
if (insn & (1 << 21)) {
/* Base writeback. */
if (insn & (1 << 24)) {
@@ -8213,7 +8203,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
}
} else {
int i, loaded_base = 0;
- TCGv loaded_var;
+ TCGv_i32 loaded_var;
/* Load/store multiple. */
addr = load_reg(s, rn);
offset = 0;
@@ -8225,13 +8215,14 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
tcg_gen_addi_i32(addr, addr, -offset);
}
- TCGV_UNUSED(loaded_var);
+ TCGV_UNUSED_I32(loaded_var);
for (i = 0; i < 16; i++) {
if ((insn & (1 << i)) == 0)
continue;
if (insn & (1 << 20)) {
/* Load. */
- tmp = gen_ld32(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
if (i == 15) {
gen_bx(s, tmp);
} else if (i == rn) {
@@ -8243,7 +8234,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
} else {
/* Store. */
tmp = load_reg(s, i);
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
}
tcg_gen_addi_i32(addr, addr, 4);
}
@@ -9015,13 +9007,25 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
}
if (insn & (1 << 20)) {
/* Load. */
+ tmp = tcg_temp_new_i32();
switch (op) {
- case 0: tmp = gen_ld8u(addr, user); break;
- case 4: tmp = gen_ld8s(addr, user); break;
- case 1: tmp = gen_ld16u(addr, user); break;
- case 5: tmp = gen_ld16s(addr, user); break;
- case 2: tmp = gen_ld32(addr, user); break;
+ case 0:
+ tcg_gen_qemu_ld8u(tmp, addr, user);
+ break;
+ case 4:
+ tcg_gen_qemu_ld8s(tmp, addr, user);
+ break;
+ case 1:
+ tcg_gen_qemu_ld16u(tmp, addr, user);
+ break;
+ case 5:
+ tcg_gen_qemu_ld16s(tmp, addr, user);
+ break;
+ case 2:
+ tcg_gen_qemu_ld32u(tmp, addr, user);
+ break;
default:
+ tcg_temp_free_i32(tmp);
tcg_temp_free_i32(addr);
goto illegal_op;
}
@@ -9034,13 +9038,21 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
/* Store. */
tmp = load_reg(s, rs);
switch (op) {
- case 0: gen_st8(tmp, addr, user); break;
- case 1: gen_st16(tmp, addr, user); break;
- case 2: gen_st32(tmp, addr, user); break;
+ case 0:
+ tcg_gen_qemu_st8(tmp, addr, user);
+ break;
+ case 1:
+ tcg_gen_qemu_st16(tmp, addr, user);
+ break;
+ case 2:
+ tcg_gen_qemu_st32(tmp, addr, user);
+ break;
default:
+ tcg_temp_free_i32(tmp);
tcg_temp_free_i32(addr);
goto illegal_op;
}
+ tcg_temp_free_i32(tmp);
}
if (postinc)
tcg_gen_addi_i32(addr, addr, imm);
@@ -9064,9 +9076,9 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
uint32_t val, insn, op, rm, rn, rd, shift, cond;
int32_t offset;
int i;
- TCGv tmp;
- TCGv tmp2;
- TCGv addr;
+ TCGv_i32 tmp;
+ TCGv_i32 tmp2;
+ TCGv_i32 addr;
if (s->condexec_mask) {
cond = s->condexec_cond;
@@ -9169,7 +9181,8 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
val &= ~(uint32_t)2;
addr = tcg_temp_new_i32();
tcg_gen_movi_i32(addr, val);
- tmp = gen_ld32(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
tcg_temp_free_i32(addr);
store_reg(s, rd, tmp);
break;
@@ -9234,7 +9247,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
} else if (op != 0xf) { /* mvn doesn't read its first operand */
tmp = load_reg(s, rd);
} else {
- TCGV_UNUSED(tmp);
+ TCGV_UNUSED_I32(tmp);
}
tmp2 = load_reg(s, rm);
@@ -9364,37 +9377,43 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
tcg_gen_add_i32(addr, addr, tmp);
tcg_temp_free_i32(tmp);
- if (op < 3) /* store */
+ if (op < 3) { /* store */
tmp = load_reg(s, rd);
+ } else {
+ tmp = tcg_temp_new_i32();
+ }
switch (op) {
case 0: /* str */
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
break;
case 1: /* strh */
- gen_st16(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
break;
case 2: /* strb */
- gen_st8(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
break;
case 3: /* ldrsb */
- tmp = gen_ld8s(addr, IS_USER(s));
+ tcg_gen_qemu_ld8s(tmp, addr, IS_USER(s));
break;
case 4: /* ldr */
- tmp = gen_ld32(addr, IS_USER(s));
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
break;
case 5: /* ldrh */
- tmp = gen_ld16u(addr, IS_USER(s));
+ tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
break;
case 6: /* ldrb */
- tmp = gen_ld8u(addr, IS_USER(s));
+ tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
break;
case 7: /* ldrsh */
- tmp = gen_ld16s(addr, IS_USER(s));
+ tcg_gen_qemu_ld16s(tmp, addr, IS_USER(s));
break;
}
- if (op >= 3) /* load */
+ if (op >= 3) { /* load */
store_reg(s, rd, tmp);
+ } else {
+ tcg_temp_free_i32(tmp);
+ }
tcg_temp_free_i32(addr);
break;
@@ -9408,12 +9427,14 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
if (insn & (1 << 11)) {
/* load */
- tmp = gen_ld32(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
store_reg(s, rd, tmp);
} else {
/* store */
tmp = load_reg(s, rd);
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
}
tcg_temp_free_i32(addr);
break;
@@ -9428,12 +9449,14 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
if (insn & (1 << 11)) {
/* load */
- tmp = gen_ld8u(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
store_reg(s, rd, tmp);
} else {
/* store */
tmp = load_reg(s, rd);
- gen_st8(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
}
tcg_temp_free_i32(addr);
break;
@@ -9448,12 +9471,14 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
if (insn & (1 << 11)) {
/* load */
- tmp = gen_ld16u(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
store_reg(s, rd, tmp);
} else {
/* store */
tmp = load_reg(s, rd);
- gen_st16(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
}
tcg_temp_free_i32(addr);
break;
@@ -9467,12 +9492,14 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
if (insn & (1 << 11)) {
/* load */
- tmp = gen_ld32(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
store_reg(s, rd, tmp);
} else {
/* store */
tmp = load_reg(s, rd);
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
}
tcg_temp_free_i32(addr);
break;
@@ -9538,28 +9565,32 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
if (insn & (1 << i)) {
if (insn & (1 << 11)) {
/* pop */
- tmp = gen_ld32(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
store_reg(s, i, tmp);
} else {
/* push */
tmp = load_reg(s, i);
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
}
/* advance to the next address. */
tcg_gen_addi_i32(addr, addr, 4);
}
}
- TCGV_UNUSED(tmp);
+ TCGV_UNUSED_I32(tmp);
if (insn & (1 << 8)) {
if (insn & (1 << 11)) {
/* pop pc */
- tmp = gen_ld32(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
/* don't set the pc until the rest of the instruction
has completed */
} else {
/* push lr */
tmp = load_reg(s, 14);
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
}
tcg_gen_addi_i32(addr, addr, 4);
}
@@ -9674,15 +9705,16 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
case 12:
{
/* load/store multiple */
- TCGv loaded_var;
- TCGV_UNUSED(loaded_var);
+ TCGv_i32 loaded_var;
+ TCGV_UNUSED_I32(loaded_var);
rn = (insn >> 8) & 0x7;
addr = load_reg(s, rn);
for (i = 0; i < 8; i++) {
if (insn & (1 << i)) {
if (insn & (1 << 11)) {
/* load */
- tmp = gen_ld32(addr, IS_USER(s));
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
if (i == rn) {
loaded_var = tmp;
} else {
@@ -9691,7 +9723,8 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
} else {
/* store */
tmp = load_reg(s, i);
- gen_st32(tmp, addr, IS_USER(s));
+ tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+ tcg_temp_free_i32(tmp);
}
/* advance to the next address */
tcg_gen_addi_i32(addr, addr, 4);
@@ -9851,7 +9884,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
complications trying to do it at the end of the block. */
if (dc->condexec_mask || dc->condexec_cond)
{
- TCGv tmp = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_movi_i32(tmp, 0);
store_cpu_field(tmp, condexec_bits);
}
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index cedf03df43..6e761e03b6 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -668,6 +668,7 @@ void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra);
hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address,
int rw);
#endif
+target_ulong exception_resume_pc (CPUMIPSState *env);
static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 918a898699..4116de93c3 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -2902,13 +2902,13 @@ target_ulong helper_bitrev(target_ulong rt)
return (target_ulong)rd;
}
-#define BIT_INSV(name, posfilter, sizefilter, ret_type) \
+#define BIT_INSV(name, posfilter, ret_type) \
target_ulong helper_##name(CPUMIPSState *env, target_ulong rs, \
target_ulong rt) \
{ \
uint32_t pos, size, msb, lsb; \
- target_ulong filter; \
- target_ulong temp, temprs, temprt; \
+ uint32_t const sizefilter = 0x3F; \
+ target_ulong temp; \
target_ulong dspc; \
\
dspc = env->active_tc.DSPControl; \
@@ -2923,18 +2923,14 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong rs, \
return rt; \
} \
\
- filter = ((int64_t)0x01 << size) - 1; \
- filter = filter << pos; \
- temprs = (rs << pos) & filter; \
- temprt = rt & ~filter; \
- temp = temprs | temprt; \
+ temp = deposit64(rt, pos, size, rs); \
\
return (target_long)(ret_type)temp; \
}
-BIT_INSV(insv, 0x1F, 0x3F, int32_t);
+BIT_INSV(insv, 0x1F, int32_t);
#ifdef TARGET_MIPS64
-BIT_INSV(dinsv, 0x7F, 0x3F, target_long);
+BIT_INSV(dinsv, 0x7F, target_long);
#endif
#undef BIT_INSV
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 3a54acf706..36929ddee7 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -366,8 +366,7 @@ static const char * const excp_names[EXCP_LAST + 1] = {
[EXCP_CACHE] = "cache error",
};
-#if !defined(CONFIG_USER_ONLY)
-static target_ulong exception_resume_pc (CPUMIPSState *env)
+target_ulong exception_resume_pc (CPUMIPSState *env)
{
target_ulong bad_pc;
target_ulong isa_mode;
@@ -383,6 +382,7 @@ static target_ulong exception_resume_pc (CPUMIPSState *env)
return bad_pc;
}
+#if !defined(CONFIG_USER_ONLY)
static void set_hflags_for_handler (CPUMIPSState *env)
{
/* Exception handlers are entered in 32-bit mode. */
diff --git a/target-moxie/helper.c b/target-moxie/helper.c
index 6e0ac2aa2a..5cfe889ad4 100644
--- a/target-moxie/helper.c
+++ b/target-moxie/helper.c
@@ -116,7 +116,7 @@ int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
return 1;
}
-target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+hwaddr cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
{
return addr;
}
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 725071e6a7..3ab2946cfb 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -30,8 +30,6 @@
#include "cpu.h"
#include "sysemu/cpus.h"
#include "sysemu/device_tree.h"
-#include "hw/sysbus.h"
-#include "hw/ppc/spapr.h"
#include "mmu-hash64.h"
#include "hw/sysbus.h"
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 0ce82cf830..6304c4d90b 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -34,7 +34,10 @@
#include "exec/cpu-defs.h"
#define TARGET_PAGE_BITS 12
-#define TARGET_PHYS_ADDR_SPACE_BITS 64
+/* Actually 64-bits, limited by the memory API to 62 bits. We
+ * never use that much.
+ */
+#define TARGET_PHYS_ADDR_SPACE_BITS 62
#define TARGET_VIRT_ADDR_SPACE_BITS 64
#include "exec/cpu-all.h"
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index ab1adfd7ea..290b5809aa 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -292,19 +292,6 @@ static const sparc_def_t sparc_defs[] = {
},
#else
{
- .name = "Fujitsu MB86900",
- .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
- .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
- .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
- .mmu_bm = 0x00004000,
- .mmu_ctpr_mask = 0x007ffff0,
- .mmu_cxr_mask = 0x0000003f,
- .mmu_sfsr_mask = 0xffffffff,
- .mmu_trcr_mask = 0xffffffff,
- .nwindows = 7,
- .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
- },
- {
.name = "Fujitsu MB86904",
.iu_version = 0x04 << 24, /* Impl 0, ver 4 */
.fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
@@ -331,48 +318,6 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
- .name = "LSI L64811",
- .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
- .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
- .mmu_version = 0x10 << 24,
- .mmu_bm = 0x00004000,
- .mmu_ctpr_mask = 0x007ffff0,
- .mmu_cxr_mask = 0x0000003f,
- .mmu_sfsr_mask = 0xffffffff,
- .mmu_trcr_mask = 0xffffffff,
- .nwindows = 8,
- .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
- CPU_FEATURE_FSMULD,
- },
- {
- .name = "Cypress CY7C601",
- .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
- .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
- .mmu_version = 0x10 << 24,
- .mmu_bm = 0x00004000,
- .mmu_ctpr_mask = 0x007ffff0,
- .mmu_cxr_mask = 0x0000003f,
- .mmu_sfsr_mask = 0xffffffff,
- .mmu_trcr_mask = 0xffffffff,
- .nwindows = 8,
- .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
- CPU_FEATURE_FSMULD,
- },
- {
- .name = "Cypress CY7C611",
- .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
- .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
- .mmu_version = 0x10 << 24,
- .mmu_bm = 0x00004000,
- .mmu_ctpr_mask = 0x007ffff0,
- .mmu_cxr_mask = 0x0000003f,
- .mmu_sfsr_mask = 0xffffffff,
- .mmu_trcr_mask = 0xffffffff,
- .nwindows = 8,
- .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
- CPU_FEATURE_FSMULD,
- },
- {
.name = "TI MicroSparc I",
.iu_version = 0x41000000,
.fpu_version = 4 << 17,
@@ -495,73 +440,6 @@ static const sparc_def_t sparc_defs[] = {
.features = CPU_DEFAULT_FEATURES,
},
{
- .name = "Ross RT625",
- .iu_version = 0x1e000000,
- .fpu_version = 1 << 17,
- .mmu_version = 0x1e000000,
- .mmu_bm = 0x00004000,
- .mmu_ctpr_mask = 0x007ffff0,
- .mmu_cxr_mask = 0x0000003f,
- .mmu_sfsr_mask = 0xffffffff,
- .mmu_trcr_mask = 0xffffffff,
- .nwindows = 8,
- .features = CPU_DEFAULT_FEATURES,
- },
- {
- .name = "Ross RT620",
- .iu_version = 0x1f000000,
- .fpu_version = 1 << 17,
- .mmu_version = 0x1f000000,
- .mmu_bm = 0x00004000,
- .mmu_ctpr_mask = 0x007ffff0,
- .mmu_cxr_mask = 0x0000003f,
- .mmu_sfsr_mask = 0xffffffff,
- .mmu_trcr_mask = 0xffffffff,
- .nwindows = 8,
- .features = CPU_DEFAULT_FEATURES,
- },
- {
- .name = "BIT B5010",
- .iu_version = 0x20000000,
- .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
- .mmu_version = 0x20000000,
- .mmu_bm = 0x00004000,
- .mmu_ctpr_mask = 0x007ffff0,
- .mmu_cxr_mask = 0x0000003f,
- .mmu_sfsr_mask = 0xffffffff,
- .mmu_trcr_mask = 0xffffffff,
- .nwindows = 8,
- .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
- CPU_FEATURE_FSMULD,
- },
- {
- .name = "Matsushita MN10501",
- .iu_version = 0x50000000,
- .fpu_version = 0 << 17,
- .mmu_version = 0x50000000,
- .mmu_bm = 0x00004000,
- .mmu_ctpr_mask = 0x007ffff0,
- .mmu_cxr_mask = 0x0000003f,
- .mmu_sfsr_mask = 0xffffffff,
- .mmu_trcr_mask = 0xffffffff,
- .nwindows = 8,
- .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
- CPU_FEATURE_FSMULD,
- },
- {
- .name = "Weitek W8601",
- .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
- .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
- .mmu_version = 0x10 << 24,
- .mmu_bm = 0x00004000,
- .mmu_ctpr_mask = 0x007ffff0,
- .mmu_cxr_mask = 0x0000003f,
- .mmu_sfsr_mask = 0xffffffff,
- .mmu_trcr_mask = 0xffffffff,
- .nwindows = 8,
- .features = CPU_DEFAULT_FEATURES,
- },
- {
.name = "LEON2",
.iu_version = 0xf2000000,
.fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
diff --git a/tests/qemu-iotests/054 b/tests/qemu-iotests/054
new file mode 100755
index 0000000000..b36042958c
--- /dev/null
+++ b/tests/qemu-iotests/054
@@ -0,0 +1,58 @@
+#!/bin/bash
+#
+# Test huge qcow2 images
+#
+# Copyright (C) 2013 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=kwolf@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+echo
+echo "creating too large image (1 EB)"
+_make_test_img $((1024*1024))T
+
+echo
+echo "creating too large image (1 EB) using qcow2.py"
+_make_test_img 4G
+./qcow2.py $TEST_IMG set-header size $((1024 ** 6))
+_check_test_img
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/054.out b/tests/qemu-iotests/054.out
new file mode 100644
index 0000000000..0b2fe301ea
--- /dev/null
+++ b/tests/qemu-iotests/054.out
@@ -0,0 +1,10 @@
+QA output created by 054
+
+creating too large image (1 EB)
+qemu-img: The image size is too large for file format 'qcow2'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1152921504606846976
+
+creating too large image (1 EB) using qcow2.py
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296
+qemu-img: Could not open 'TEST_DIR/t.qcow2': File too large
+*** done
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 31eb62b604..e9ba3586b5 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -167,7 +167,7 @@ _cleanup_test_img()
_check_test_img()
{
- $QEMU_IMG check "$@" -f $IMGFMT $TEST_IMG 2>&1 | \
+ $QEMU_IMG check "$@" -f $IMGFMT $TEST_IMG 2>&1 | _filter_testdir | \
sed -e '/allocated.*fragmented.*compressed clusters/d' \
-e 's/qemu-img: This image format does not support checks/No errors were found on the image./' \
-e '/Image end offset: [0-9]\+/d'
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index bf944d9123..387b050987 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -60,3 +60,4 @@
#051 rw auto
052 rw auto backing
053 rw auto
+054 rw auto
diff --git a/tests/qemu-iotests/qcow2.py b/tests/qemu-iotests/qcow2.py
index fecf5b9a59..44a2b45641 100755
--- a/tests/qemu-iotests/qcow2.py
+++ b/tests/qemu-iotests/qcow2.py
@@ -149,6 +149,22 @@ def cmd_dump_header(fd):
h.dump()
h.dump_extensions()
+def cmd_set_header(fd, name, value):
+ try:
+ value = int(value, 0)
+ except:
+ print "'%s' is not a valid number" % value
+ sys.exit(1)
+
+ fields = (field[2] for field in QcowHeader.fields)
+ if not name in fields:
+ print "'%s' is not a known header field" % name
+ sys.exit(1)
+
+ h = QcowHeader(fd)
+ h.__dict__[name] = value
+ h.update(fd)
+
def cmd_add_header_ext(fd, magic, data):
try:
magic = int(magic, 0)
@@ -205,6 +221,7 @@ def cmd_set_feature_bit(fd, group, bit):
cmds = [
[ 'dump-header', cmd_dump_header, 0, 'Dump image header and header extensions' ],
+ [ 'set-header', cmd_set_header, 2, 'Set a field in the header'],
[ 'add-header-ext', cmd_add_header_ext, 2, 'Add a header extension' ],
[ 'del-header-ext', cmd_del_header_ext, 1, 'Delete a header extension' ],
[ 'set-feature-bit', cmd_set_feature_bit, 2, 'Set a feature bit'],
diff --git a/tests/tcg/linux-test.c b/tests/tcg/linux-test.c
index 83cb32ddb9..1c6c01318e 100644
--- a/tests/tcg/linux-test.c
+++ b/tests/tcg/linux-test.c
@@ -39,7 +39,6 @@
#include <dirent.h>
#include <setjmp.h>
#include <sys/shm.h>
-#include <sched.h>
#define TESTPATH "/tmp/linux-test.tmp"
#define TESTPORT 7654
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 955a4c0b0a..2741eef3fa 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -61,6 +61,31 @@ Visitor *visitor_input_test_init(TestInputVisitorData *data,
return v;
}
+/* similar to visitor_input_test_init(), but does not expect a string
+ * literal/format json_string argument and so can be used for
+ * programatically generated strings (and we can't pass in programatically
+ * generated strings via %s format parameters since qobject_from_jsonv()
+ * will wrap those in double-quotes and treat the entire object as a
+ * string)
+ */
+static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
+ const char *json_string)
+{
+ Visitor *v;
+
+ data->obj = qobject_from_json(json_string);
+
+ g_assert(data->obj != NULL);
+
+ data->qiv = qmp_input_visitor_new(data->obj);
+ g_assert(data->qiv != NULL);
+
+ v = qmp_input_get_visitor(data->qiv);
+ g_assert(v != NULL);
+
+ return v;
+}
+
static void test_visitor_in_int(TestInputVisitorData *data,
const void *unused)
{
@@ -75,6 +100,24 @@ static void test_visitor_in_int(TestInputVisitorData *data,
g_assert_cmpint(res, ==, value);
}
+static void test_visitor_in_int_overflow(TestInputVisitorData *data,
+ const void *unused)
+{
+ int64_t res = 0;
+ Error *errp = NULL;
+ Visitor *v;
+
+ /* this will overflow a Qint/int64, so should be deserialized into
+ * a QFloat/double field instead, leading to an error if we pass it
+ * to visit_type_int. confirm this.
+ */
+ v = visitor_input_test_init(data, "%f", DBL_MAX);
+
+ visit_type_int(v, &res, NULL, &errp);
+ g_assert(error_is_set(&errp));
+ error_free(errp);
+}
+
static void test_visitor_in_bool(TestInputVisitorData *data,
const void *unused)
{
@@ -259,6 +302,287 @@ static void test_visitor_in_union(TestInputVisitorData *data,
qapi_free_UserDefUnion(tmp);
}
+static void test_native_list_integer_helper(TestInputVisitorData *data,
+ const void *unused,
+ UserDefNativeListUnionKind kind)
+{
+ UserDefNativeListUnion *cvalue = NULL;
+ Error *err = NULL;
+ Visitor *v;
+ GString *gstr_list = g_string_new("");
+ GString *gstr_union = g_string_new("");
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ g_string_append_printf(gstr_list, "%d", i);
+ if (i != 31) {
+ g_string_append(gstr_list, ", ");
+ }
+ }
+ g_string_append_printf(gstr_union, "{ 'type': '%s', 'data': [ %s ] }",
+ UserDefNativeListUnionKind_lookup[kind],
+ gstr_list->str);
+ v = visitor_input_test_init_raw(data, gstr_union->str);
+
+ visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
+ g_assert(err == NULL);
+ g_assert(cvalue != NULL);
+ g_assert_cmpint(cvalue->kind, ==, kind);
+
+ switch (kind) {
+ case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
+ intList *elem = NULL;
+ for (i = 0, elem = cvalue->integer; elem; elem = elem->next, i++) {
+ g_assert_cmpint(elem->value, ==, i);
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
+ int8List *elem = NULL;
+ for (i = 0, elem = cvalue->s8; elem; elem = elem->next, i++) {
+ g_assert_cmpint(elem->value, ==, i);
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
+ int16List *elem = NULL;
+ for (i = 0, elem = cvalue->s16; elem; elem = elem->next, i++) {
+ g_assert_cmpint(elem->value, ==, i);
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
+ int32List *elem = NULL;
+ for (i = 0, elem = cvalue->s32; elem; elem = elem->next, i++) {
+ g_assert_cmpint(elem->value, ==, i);
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
+ int64List *elem = NULL;
+ for (i = 0, elem = cvalue->s64; elem; elem = elem->next, i++) {
+ g_assert_cmpint(elem->value, ==, i);
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
+ uint8List *elem = NULL;
+ for (i = 0, elem = cvalue->u8; elem; elem = elem->next, i++) {
+ g_assert_cmpint(elem->value, ==, i);
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
+ uint16List *elem = NULL;
+ for (i = 0, elem = cvalue->u16; elem; elem = elem->next, i++) {
+ g_assert_cmpint(elem->value, ==, i);
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
+ uint32List *elem = NULL;
+ for (i = 0, elem = cvalue->u32; elem; elem = elem->next, i++) {
+ g_assert_cmpint(elem->value, ==, i);
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
+ uint64List *elem = NULL;
+ for (i = 0, elem = cvalue->u64; elem; elem = elem->next, i++) {
+ g_assert_cmpint(elem->value, ==, i);
+ }
+ break;
+ }
+ default:
+ g_assert(false);
+ }
+
+ g_string_free(gstr_union, true);
+ g_string_free(gstr_list, true);
+ qapi_free_UserDefNativeListUnion(cvalue);
+}
+
+static void test_visitor_in_native_list_int(TestInputVisitorData *data,
+ const void *unused)
+{
+ test_native_list_integer_helper(data, unused,
+ USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
+}
+
+static void test_visitor_in_native_list_int8(TestInputVisitorData *data,
+ const void *unused)
+{
+ test_native_list_integer_helper(data, unused,
+ USER_DEF_NATIVE_LIST_UNION_KIND_S8);
+}
+
+static void test_visitor_in_native_list_int16(TestInputVisitorData *data,
+ const void *unused)
+{
+ test_native_list_integer_helper(data, unused,
+ USER_DEF_NATIVE_LIST_UNION_KIND_S16);
+}
+
+static void test_visitor_in_native_list_int32(TestInputVisitorData *data,
+ const void *unused)
+{
+ test_native_list_integer_helper(data, unused,
+ USER_DEF_NATIVE_LIST_UNION_KIND_S32);
+}
+
+static void test_visitor_in_native_list_int64(TestInputVisitorData *data,
+ const void *unused)
+{
+ test_native_list_integer_helper(data, unused,
+ USER_DEF_NATIVE_LIST_UNION_KIND_S64);
+}
+
+static void test_visitor_in_native_list_uint8(TestInputVisitorData *data,
+ const void *unused)
+{
+ test_native_list_integer_helper(data, unused,
+ USER_DEF_NATIVE_LIST_UNION_KIND_U8);
+}
+
+static void test_visitor_in_native_list_uint16(TestInputVisitorData *data,
+ const void *unused)
+{
+ test_native_list_integer_helper(data, unused,
+ USER_DEF_NATIVE_LIST_UNION_KIND_U16);
+}
+
+static void test_visitor_in_native_list_uint32(TestInputVisitorData *data,
+ const void *unused)
+{
+ test_native_list_integer_helper(data, unused,
+ USER_DEF_NATIVE_LIST_UNION_KIND_U32);
+}
+
+static void test_visitor_in_native_list_uint64(TestInputVisitorData *data,
+ const void *unused)
+{
+ test_native_list_integer_helper(data, unused,
+ USER_DEF_NATIVE_LIST_UNION_KIND_U64);
+}
+
+static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
+ const void *unused)
+{
+ UserDefNativeListUnion *cvalue = NULL;
+ boolList *elem = NULL;
+ Error *err = NULL;
+ Visitor *v;
+ GString *gstr_list = g_string_new("");
+ GString *gstr_union = g_string_new("");
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ g_string_append_printf(gstr_list, "%s",
+ (i % 3 == 0) ? "true" : "false");
+ if (i != 31) {
+ g_string_append(gstr_list, ", ");
+ }
+ }
+ g_string_append_printf(gstr_union, "{ 'type': 'boolean', 'data': [ %s ] }",
+ gstr_list->str);
+ v = visitor_input_test_init_raw(data, gstr_union->str);
+
+ visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
+ g_assert(err == NULL);
+ g_assert(cvalue != NULL);
+ g_assert_cmpint(cvalue->kind, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
+
+ for (i = 0, elem = cvalue->boolean; elem; elem = elem->next, i++) {
+ g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
+ }
+
+ g_string_free(gstr_union, true);
+ g_string_free(gstr_list, true);
+ qapi_free_UserDefNativeListUnion(cvalue);
+}
+
+static void test_visitor_in_native_list_string(TestInputVisitorData *data,
+ const void *unused)
+{
+ UserDefNativeListUnion *cvalue = NULL;
+ strList *elem = NULL;
+ Error *err = NULL;
+ Visitor *v;
+ GString *gstr_list = g_string_new("");
+ GString *gstr_union = g_string_new("");
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ g_string_append_printf(gstr_list, "'%d'", i);
+ if (i != 31) {
+ g_string_append(gstr_list, ", ");
+ }
+ }
+ g_string_append_printf(gstr_union, "{ 'type': 'string', 'data': [ %s ] }",
+ gstr_list->str);
+ v = visitor_input_test_init_raw(data, gstr_union->str);
+
+ visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
+ g_assert(err == NULL);
+ g_assert(cvalue != NULL);
+ g_assert_cmpint(cvalue->kind, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
+
+ for (i = 0, elem = cvalue->string; elem; elem = elem->next, i++) {
+ gchar str[8];
+ sprintf(str, "%d", i);
+ g_assert_cmpstr(elem->value, ==, str);
+ }
+
+ g_string_free(gstr_union, true);
+ g_string_free(gstr_list, true);
+ qapi_free_UserDefNativeListUnion(cvalue);
+}
+
+#define DOUBLE_STR_MAX 16
+
+static void test_visitor_in_native_list_number(TestInputVisitorData *data,
+ const void *unused)
+{
+ UserDefNativeListUnion *cvalue = NULL;
+ numberList *elem = NULL;
+ Error *err = NULL;
+ Visitor *v;
+ GString *gstr_list = g_string_new("");
+ GString *gstr_union = g_string_new("");
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ g_string_append_printf(gstr_list, "%f", (double)i / 3);
+ if (i != 31) {
+ g_string_append(gstr_list, ", ");
+ }
+ }
+ g_string_append_printf(gstr_union, "{ 'type': 'number', 'data': [ %s ] }",
+ gstr_list->str);
+ v = visitor_input_test_init_raw(data, gstr_union->str);
+
+ visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
+ g_assert(err == NULL);
+ g_assert(cvalue != NULL);
+ g_assert_cmpint(cvalue->kind, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
+
+ for (i = 0, elem = cvalue->number; elem; elem = elem->next, i++) {
+ GString *double_expected = g_string_new("");
+ GString *double_actual = g_string_new("");
+
+ g_string_printf(double_expected, "%.6f", (double)i / 3);
+ g_string_printf(double_actual, "%.6f", elem->value);
+ g_assert_cmpstr(double_expected->str, ==, double_actual->str);
+
+ g_string_free(double_expected, true);
+ g_string_free(double_actual, true);
+ }
+
+ g_string_free(gstr_union, true);
+ g_string_free(gstr_list, true);
+ qapi_free_UserDefNativeListUnion(cvalue);
+}
+
static void input_visitor_test_add(const char *testpath,
TestInputVisitorData *data,
void (*test_func)(TestInputVisitorData *data, const void *user_data))
@@ -292,6 +616,8 @@ int main(int argc, char **argv)
input_visitor_test_add("/visitor/input/int",
&in_visitor_data, test_visitor_in_int);
+ input_visitor_test_add("/visitor/input/int_overflow",
+ &in_visitor_data, test_visitor_in_int_overflow);
input_visitor_test_add("/visitor/input/bool",
&in_visitor_data, test_visitor_in_bool);
input_visitor_test_add("/visitor/input/number",
@@ -310,6 +636,38 @@ int main(int argc, char **argv)
&in_visitor_data, test_visitor_in_union);
input_visitor_test_add("/visitor/input/errors",
&in_visitor_data, test_visitor_in_errors);
+ input_visitor_test_add("/visitor/input/native_list/int",
+ &in_visitor_data,
+ test_visitor_in_native_list_int);
+ input_visitor_test_add("/visitor/input/native_list/int8",
+ &in_visitor_data,
+ test_visitor_in_native_list_int8);
+ input_visitor_test_add("/visitor/input/native_list/int16",
+ &in_visitor_data,
+ test_visitor_in_native_list_int16);
+ input_visitor_test_add("/visitor/input/native_list/int32",
+ &in_visitor_data,
+ test_visitor_in_native_list_int32);
+ input_visitor_test_add("/visitor/input/native_list/int64",
+ &in_visitor_data,
+ test_visitor_in_native_list_int64);
+ input_visitor_test_add("/visitor/input/native_list/uint8",
+ &in_visitor_data,
+ test_visitor_in_native_list_uint8);
+ input_visitor_test_add("/visitor/input/native_list/uint16",
+ &in_visitor_data,
+ test_visitor_in_native_list_uint16);
+ input_visitor_test_add("/visitor/input/native_list/uint32",
+ &in_visitor_data,
+ test_visitor_in_native_list_uint32);
+ input_visitor_test_add("/visitor/input/native_list/uint64",
+ &in_visitor_data, test_visitor_in_native_list_uint64);
+ input_visitor_test_add("/visitor/input/native_list/bool",
+ &in_visitor_data, test_visitor_in_native_list_bool);
+ input_visitor_test_add("/visitor/input/native_list/str",
+ &in_visitor_data, test_visitor_in_native_list_string);
+ input_visitor_test_add("/visitor/input/native_list/number",
+ &in_visitor_data, test_visitor_in_native_list_number);
g_test_run();
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 71367e6efa..0942a41875 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -431,6 +431,314 @@ static void test_visitor_out_union(TestOutputVisitorData *data,
QDECREF(qdict);
}
+static void init_native_list(UserDefNativeListUnion *cvalue)
+{
+ int i;
+ switch (cvalue->kind) {
+ case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
+ intList **list = &cvalue->integer;
+ for (i = 0; i < 32; i++) {
+ *list = g_new0(intList, 1);
+ (*list)->value = i;
+ (*list)->next = NULL;
+ list = &(*list)->next;
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
+ int8List **list = &cvalue->s8;
+ for (i = 0; i < 32; i++) {
+ *list = g_new0(int8List, 1);
+ (*list)->value = i;
+ (*list)->next = NULL;
+ list = &(*list)->next;
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
+ int16List **list = &cvalue->s16;
+ for (i = 0; i < 32; i++) {
+ *list = g_new0(int16List, 1);
+ (*list)->value = i;
+ (*list)->next = NULL;
+ list = &(*list)->next;
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
+ int32List **list = &cvalue->s32;
+ for (i = 0; i < 32; i++) {
+ *list = g_new0(int32List, 1);
+ (*list)->value = i;
+ (*list)->next = NULL;
+ list = &(*list)->next;
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
+ int64List **list = &cvalue->s64;
+ for (i = 0; i < 32; i++) {
+ *list = g_new0(int64List, 1);
+ (*list)->value = i;
+ (*list)->next = NULL;
+ list = &(*list)->next;
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
+ uint8List **list = &cvalue->u8;
+ for (i = 0; i < 32; i++) {
+ *list = g_new0(uint8List, 1);
+ (*list)->value = i;
+ (*list)->next = NULL;
+ list = &(*list)->next;
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
+ uint16List **list = &cvalue->u16;
+ for (i = 0; i < 32; i++) {
+ *list = g_new0(uint16List, 1);
+ (*list)->value = i;
+ (*list)->next = NULL;
+ list = &(*list)->next;
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
+ uint32List **list = &cvalue->u32;
+ for (i = 0; i < 32; i++) {
+ *list = g_new0(uint32List, 1);
+ (*list)->value = i;
+ (*list)->next = NULL;
+ list = &(*list)->next;
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
+ uint64List **list = &cvalue->u64;
+ for (i = 0; i < 32; i++) {
+ *list = g_new0(uint64List, 1);
+ (*list)->value = i;
+ (*list)->next = NULL;
+ list = &(*list)->next;
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN: {
+ boolList **list = &cvalue->boolean;
+ for (i = 0; i < 32; i++) {
+ *list = g_new0(boolList, 1);
+ (*list)->value = (i % 3 == 0);
+ (*list)->next = NULL;
+ list = &(*list)->next;
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_STRING: {
+ strList **list = &cvalue->string;
+ for (i = 0; i < 32; i++) {
+ *list = g_new0(strList, 1);
+ (*list)->value = g_strdup_printf("%d", i);
+ (*list)->next = NULL;
+ list = &(*list)->next;
+ }
+ break;
+ }
+ case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER: {
+ numberList **list = &cvalue->number;
+ for (i = 0; i < 32; i++) {
+ *list = g_new0(numberList, 1);
+ (*list)->value = (double)i / 3;
+ (*list)->next = NULL;
+ list = &(*list)->next;
+ }
+ break;
+ }
+ default:
+ g_assert(false);
+ }
+}
+
+static void check_native_list(QObject *qobj,
+ UserDefNativeListUnionKind kind)
+{
+ QDict *qdict;
+ QList *qlist;
+ int i;
+
+ g_assert(qobj);
+ g_assert(qobject_type(qobj) == QTYPE_QDICT);
+ qdict = qobject_to_qdict(qobj);
+ g_assert(qdict);
+ g_assert(qdict_haskey(qdict, "data"));
+ qlist = qlist_copy(qobject_to_qlist(qdict_get(qdict, "data")));
+
+ switch (kind) {
+ case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
+ case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
+ case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
+ case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
+ case USER_DEF_NATIVE_LIST_UNION_KIND_U8:
+ case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
+ case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
+ case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
+ /* all integer elements in JSON arrays get stored into QInts when
+ * we convert to QObjects, so we can check them all in the same
+ * fashion, so simply fall through here
+ */
+ case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
+ for (i = 0; i < 32; i++) {
+ QObject *tmp;
+ QInt *qvalue;
+ tmp = qlist_peek(qlist);
+ g_assert(tmp);
+ qvalue = qobject_to_qint(tmp);
+ g_assert_cmpint(qint_get_int(qvalue), ==, i);
+ qobject_decref(qlist_pop(qlist));
+ }
+ break;
+ case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN:
+ for (i = 0; i < 32; i++) {
+ QObject *tmp;
+ QBool *qvalue;
+ tmp = qlist_peek(qlist);
+ g_assert(tmp);
+ qvalue = qobject_to_qbool(tmp);
+ g_assert_cmpint(qbool_get_int(qvalue), ==, (i % 3 == 0) ? 1 : 0);
+ qobject_decref(qlist_pop(qlist));
+ }
+ break;
+ case USER_DEF_NATIVE_LIST_UNION_KIND_STRING:
+ for (i = 0; i < 32; i++) {
+ QObject *tmp;
+ QString *qvalue;
+ gchar str[8];
+ tmp = qlist_peek(qlist);
+ g_assert(tmp);
+ qvalue = qobject_to_qstring(tmp);
+ sprintf(str, "%d", i);
+ g_assert_cmpstr(qstring_get_str(qvalue), ==, str);
+ qobject_decref(qlist_pop(qlist));
+ }
+ break;
+ case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER:
+ for (i = 0; i < 32; i++) {
+ QObject *tmp;
+ QFloat *qvalue;
+ GString *double_expected = g_string_new("");
+ GString *double_actual = g_string_new("");
+
+ tmp = qlist_peek(qlist);
+ g_assert(tmp);
+ qvalue = qobject_to_qfloat(tmp);
+ g_string_printf(double_expected, "%.6f", (double)i / 3);
+ g_string_printf(double_actual, "%.6f", qfloat_get_double(qvalue));
+ g_assert_cmpstr(double_actual->str, ==, double_expected->str);
+
+ qobject_decref(qlist_pop(qlist));
+ g_string_free(double_expected, true);
+ g_string_free(double_actual, true);
+ }
+ break;
+ default:
+ g_assert(false);
+ }
+ QDECREF(qlist);
+}
+
+static void test_native_list(TestOutputVisitorData *data,
+ const void *unused,
+ UserDefNativeListUnionKind kind)
+{
+ UserDefNativeListUnion *cvalue = g_new0(UserDefNativeListUnion, 1);
+ Error *err = NULL;
+ QObject *obj;
+
+ cvalue->kind = kind;
+ init_native_list(cvalue);
+
+ visit_type_UserDefNativeListUnion(data->ov, &cvalue, NULL, &err);
+ g_assert(err == NULL);
+
+ obj = qmp_output_get_qobject(data->qov);
+ check_native_list(obj, cvalue->kind);
+ qapi_free_UserDefNativeListUnion(cvalue);
+ qobject_decref(obj);
+}
+
+static void test_visitor_out_native_list_int(TestOutputVisitorData *data,
+ const void *unused)
+{
+ test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
+}
+
+static void test_visitor_out_native_list_int8(TestOutputVisitorData *data,
+ const void *unused)
+{
+ test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S8);
+}
+
+static void test_visitor_out_native_list_int16(TestOutputVisitorData *data,
+ const void *unused)
+{
+ test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S16);
+}
+
+static void test_visitor_out_native_list_int32(TestOutputVisitorData *data,
+ const void *unused)
+{
+ test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S32);
+}
+
+static void test_visitor_out_native_list_int64(TestOutputVisitorData *data,
+ const void *unused)
+{
+ test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S64);
+}
+
+static void test_visitor_out_native_list_uint8(TestOutputVisitorData *data,
+ const void *unused)
+{
+ test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U8);
+}
+
+static void test_visitor_out_native_list_uint16(TestOutputVisitorData *data,
+ const void *unused)
+{
+ test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U16);
+}
+
+static void test_visitor_out_native_list_uint32(TestOutputVisitorData *data,
+ const void *unused)
+{
+ test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U32);
+}
+
+static void test_visitor_out_native_list_uint64(TestOutputVisitorData *data,
+ const void *unused)
+{
+ test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U64);
+}
+
+static void test_visitor_out_native_list_bool(TestOutputVisitorData *data,
+ const void *unused)
+{
+ test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
+}
+
+static void test_visitor_out_native_list_str(TestOutputVisitorData *data,
+ const void *unused)
+{
+ test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
+}
+
+static void test_visitor_out_native_list_number(TestOutputVisitorData *data,
+ const void *unused)
+{
+ test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
+}
+
static void output_visitor_test_add(const char *testpath,
TestOutputVisitorData *data,
void (*test_func)(TestOutputVisitorData *data, const void *user_data))
@@ -471,6 +779,30 @@ int main(int argc, char **argv)
&out_visitor_data, test_visitor_out_list_qapi_free);
output_visitor_test_add("/visitor/output/union",
&out_visitor_data, test_visitor_out_union);
+ output_visitor_test_add("/visitor/output/native_list/int",
+ &out_visitor_data, test_visitor_out_native_list_int);
+ output_visitor_test_add("/visitor/output/native_list/int8",
+ &out_visitor_data, test_visitor_out_native_list_int8);
+ output_visitor_test_add("/visitor/output/native_list/int16",
+ &out_visitor_data, test_visitor_out_native_list_int16);
+ output_visitor_test_add("/visitor/output/native_list/int32",
+ &out_visitor_data, test_visitor_out_native_list_int32);
+ output_visitor_test_add("/visitor/output/native_list/int64",
+ &out_visitor_data, test_visitor_out_native_list_int64);
+ output_visitor_test_add("/visitor/output/native_list/uint8",
+ &out_visitor_data, test_visitor_out_native_list_uint8);
+ output_visitor_test_add("/visitor/output/native_list/uint16",
+ &out_visitor_data, test_visitor_out_native_list_uint16);
+ output_visitor_test_add("/visitor/output/native_list/uint32",
+ &out_visitor_data, test_visitor_out_native_list_uint32);
+ output_visitor_test_add("/visitor/output/native_list/uint64",
+ &out_visitor_data, test_visitor_out_native_list_uint64);
+ output_visitor_test_add("/visitor/output/native_list/bool",
+ &out_visitor_data, test_visitor_out_native_list_bool);
+ output_visitor_test_add("/visitor/output/native_list/string",
+ &out_visitor_data, test_visitor_out_native_list_str);
+ output_visitor_test_add("/visitor/output/native_list/number",
+ &out_visitor_data, test_visitor_out_native_list_number);
g_test_run();
diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c
index 8c8adac6a9..ee7916b806 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -23,6 +23,25 @@
#include "qapi/qmp-output-visitor.h"
#include "qapi/string-input-visitor.h"
#include "qapi/string-output-visitor.h"
+#include "qapi-types.h"
+#include "qapi-visit.h"
+#include "qapi/dealloc-visitor.h"
+
+enum PrimitiveTypeKind {
+ PTYPE_STRING = 0,
+ PTYPE_BOOLEAN,
+ PTYPE_NUMBER,
+ PTYPE_INTEGER,
+ PTYPE_U8,
+ PTYPE_U16,
+ PTYPE_U32,
+ PTYPE_U64,
+ PTYPE_S8,
+ PTYPE_S16,
+ PTYPE_S32,
+ PTYPE_S64,
+ PTYPE_EOL,
+};
typedef struct PrimitiveType {
union {
@@ -40,26 +59,42 @@ typedef struct PrimitiveType {
int64_t s64;
intmax_t max;
} value;
- enum {
- PTYPE_STRING = 0,
- PTYPE_BOOLEAN,
- PTYPE_NUMBER,
- PTYPE_INTEGER,
- PTYPE_U8,
- PTYPE_U16,
- PTYPE_U32,
- PTYPE_U64,
- PTYPE_S8,
- PTYPE_S16,
- PTYPE_S32,
- PTYPE_S64,
- PTYPE_EOL,
- } type;
+ enum PrimitiveTypeKind type;
const char *description;
} PrimitiveType;
+typedef struct PrimitiveList {
+ union {
+ strList *strings;
+ boolList *booleans;
+ numberList *numbers;
+ intList *integers;
+ int8List *s8_integers;
+ int16List *s16_integers;
+ int32List *s32_integers;
+ int64List *s64_integers;
+ uint8List *u8_integers;
+ uint16List *u16_integers;
+ uint32List *u32_integers;
+ uint64List *u64_integers;
+ } value;
+ enum PrimitiveTypeKind type;
+ const char *description;
+} PrimitiveList;
+
/* test helpers */
+typedef void (*VisitorFunc)(Visitor *v, void **native, Error **errp);
+
+static void dealloc_helper(void *native_in, VisitorFunc visit, Error **errp)
+{
+ QapiDeallocVisitor *qdv = qapi_dealloc_visitor_new();
+
+ visit(qapi_dealloc_get_visitor(qdv), &native_in, errp);
+
+ qapi_dealloc_visitor_cleanup(qdv);
+}
+
static void visit_primitive_type(Visitor *v, void **native, Error **errp)
{
PrimitiveType *pt = *native;
@@ -105,6 +140,51 @@ static void visit_primitive_type(Visitor *v, void **native, Error **errp)
}
}
+static void visit_primitive_list(Visitor *v, void **native, Error **errp)
+{
+ PrimitiveList *pl = *native;
+ switch (pl->type) {
+ case PTYPE_STRING:
+ visit_type_strList(v, &pl->value.strings, NULL, errp);
+ break;
+ case PTYPE_BOOLEAN:
+ visit_type_boolList(v, &pl->value.booleans, NULL, errp);
+ break;
+ case PTYPE_NUMBER:
+ visit_type_numberList(v, &pl->value.numbers, NULL, errp);
+ break;
+ case PTYPE_INTEGER:
+ visit_type_intList(v, &pl->value.integers, NULL, errp);
+ break;
+ case PTYPE_S8:
+ visit_type_int8List(v, &pl->value.s8_integers, NULL, errp);
+ break;
+ case PTYPE_S16:
+ visit_type_int16List(v, &pl->value.s16_integers, NULL, errp);
+ break;
+ case PTYPE_S32:
+ visit_type_int32List(v, &pl->value.s32_integers, NULL, errp);
+ break;
+ case PTYPE_S64:
+ visit_type_int64List(v, &pl->value.s64_integers, NULL, errp);
+ break;
+ case PTYPE_U8:
+ visit_type_uint8List(v, &pl->value.u8_integers, NULL, errp);
+ break;
+ case PTYPE_U16:
+ visit_type_uint16List(v, &pl->value.u16_integers, NULL, errp);
+ break;
+ case PTYPE_U32:
+ visit_type_uint32List(v, &pl->value.u32_integers, NULL, errp);
+ break;
+ case PTYPE_U64:
+ visit_type_uint64List(v, &pl->value.u64_integers, NULL, errp);
+ break;
+ default:
+ g_assert(false);
+ }
+}
+
typedef struct TestStruct
{
int64_t integer;
@@ -206,12 +286,11 @@ static void visit_nested_struct_list(Visitor *v, void **native, Error **errp)
/* test cases */
-typedef void (*VisitorFunc)(Visitor *v, void **native, Error **errp);
-
typedef enum VisitorCapabilities {
VCAP_PRIMITIVES = 1,
VCAP_STRUCTURES = 2,
VCAP_LISTS = 4,
+ VCAP_PRIMITIVE_LISTS = 8,
} VisitorCapabilities;
typedef struct SerializeOps {
@@ -229,17 +308,6 @@ typedef struct TestArgs {
void *test_data;
} TestArgs;
-#define FLOAT_STRING_PRECISION 6 /* corresponding to n in %.nf formatting */
-static gsize calc_float_string_storage(double value)
-{
- int whole_value = value;
- gsize i = 0;
- do {
- i++;
- } while (whole_value /= 10);
- return i + 2 + FLOAT_STRING_PRECISION;
-}
-
static void test_primitives(gconstpointer opaque)
{
TestArgs *args = (TestArgs *) opaque;
@@ -248,7 +316,6 @@ static void test_primitives(gconstpointer opaque)
PrimitiveType *pt_copy = g_malloc0(sizeof(*pt_copy));
Error *err = NULL;
void *serialize_data;
- char *double1, *double2;
pt_copy->type = pt->type;
ops->serialize(pt, &serialize_data, visit_primitive_type, &err);
@@ -260,14 +327,17 @@ static void test_primitives(gconstpointer opaque)
g_assert_cmpstr(pt->value.string, ==, pt_copy->value.string);
g_free((char *)pt_copy->value.string);
} else if (pt->type == PTYPE_NUMBER) {
+ GString *double_expected = g_string_new("");
+ GString *double_actual = g_string_new("");
/* we serialize with %f for our reference visitors, so rather than fuzzy
* floating math to test "equality", just compare the formatted values
*/
- double1 = g_malloc0(calc_float_string_storage(pt->value.number));
- double2 = g_malloc0(calc_float_string_storage(pt_copy->value.number));
- g_assert_cmpstr(double1, ==, double2);
- g_free(double1);
- g_free(double2);
+ g_string_printf(double_expected, "%.6f", pt->value.number);
+ g_string_printf(double_actual, "%.6f", pt_copy->value.number);
+ g_assert_cmpstr(double_actual->str, ==, double_expected->str);
+
+ g_string_free(double_expected, true);
+ g_string_free(double_actual, true);
} else if (pt->type == PTYPE_BOOLEAN) {
g_assert_cmpint(!!pt->value.max, ==, !!pt->value.max);
} else {
@@ -279,6 +349,328 @@ static void test_primitives(gconstpointer opaque)
g_free(pt_copy);
}
+static void test_primitive_lists(gconstpointer opaque)
+{
+ TestArgs *args = (TestArgs *) opaque;
+ const SerializeOps *ops = args->ops;
+ PrimitiveType *pt = args->test_data;
+ PrimitiveList pl = { .value = { 0 } };
+ PrimitiveList pl_copy = { .value = { 0 } };
+ PrimitiveList *pl_copy_ptr = &pl_copy;
+ Error *err = NULL;
+ void *serialize_data;
+ void *cur_head = NULL;
+ int i;
+
+ pl.type = pl_copy.type = pt->type;
+
+ /* build up our list of primitive types */
+ for (i = 0; i < 32; i++) {
+ switch (pl.type) {
+ case PTYPE_STRING: {
+ strList *tmp = g_new0(strList, 1);
+ tmp->value = g_strdup(pt->value.string);
+ if (pl.value.strings == NULL) {
+ pl.value.strings = tmp;
+ } else {
+ tmp->next = pl.value.strings;
+ pl.value.strings = tmp;
+ }
+ break;
+ }
+ case PTYPE_INTEGER: {
+ intList *tmp = g_new0(intList, 1);
+ tmp->value = pt->value.integer;
+ if (pl.value.integers == NULL) {
+ pl.value.integers = tmp;
+ } else {
+ tmp->next = pl.value.integers;
+ pl.value.integers = tmp;
+ }
+ break;
+ }
+ case PTYPE_S8: {
+ int8List *tmp = g_new0(int8List, 1);
+ tmp->value = pt->value.s8;
+ if (pl.value.s8_integers == NULL) {
+ pl.value.s8_integers = tmp;
+ } else {
+ tmp->next = pl.value.s8_integers;
+ pl.value.s8_integers = tmp;
+ }
+ break;
+ }
+ case PTYPE_S16: {
+ int16List *tmp = g_new0(int16List, 1);
+ tmp->value = pt->value.s16;
+ if (pl.value.s16_integers == NULL) {
+ pl.value.s16_integers = tmp;
+ } else {
+ tmp->next = pl.value.s16_integers;
+ pl.value.s16_integers = tmp;
+ }
+ break;
+ }
+ case PTYPE_S32: {
+ int32List *tmp = g_new0(int32List, 1);
+ tmp->value = pt->value.s32;
+ if (pl.value.s32_integers == NULL) {
+ pl.value.s32_integers = tmp;
+ } else {
+ tmp->next = pl.value.s32_integers;
+ pl.value.s32_integers = tmp;
+ }
+ break;
+ }
+ case PTYPE_S64: {
+ int64List *tmp = g_new0(int64List, 1);
+ tmp->value = pt->value.s64;
+ if (pl.value.s64_integers == NULL) {
+ pl.value.s64_integers = tmp;
+ } else {
+ tmp->next = pl.value.s64_integers;
+ pl.value.s64_integers = tmp;
+ }
+ break;
+ }
+ case PTYPE_U8: {
+ uint8List *tmp = g_new0(uint8List, 1);
+ tmp->value = pt->value.u8;
+ if (pl.value.u8_integers == NULL) {
+ pl.value.u8_integers = tmp;
+ } else {
+ tmp->next = pl.value.u8_integers;
+ pl.value.u8_integers = tmp;
+ }
+ break;
+ }
+ case PTYPE_U16: {
+ uint16List *tmp = g_new0(uint16List, 1);
+ tmp->value = pt->value.u16;
+ if (pl.value.u16_integers == NULL) {
+ pl.value.u16_integers = tmp;
+ } else {
+ tmp->next = pl.value.u16_integers;
+ pl.value.u16_integers = tmp;
+ }
+ break;
+ }
+ case PTYPE_U32: {
+ uint32List *tmp = g_new0(uint32List, 1);
+ tmp->value = pt->value.u32;
+ if (pl.value.u32_integers == NULL) {
+ pl.value.u32_integers = tmp;
+ } else {
+ tmp->next = pl.value.u32_integers;
+ pl.value.u32_integers = tmp;
+ }
+ break;
+ }
+ case PTYPE_U64: {
+ uint64List *tmp = g_new0(uint64List, 1);
+ tmp->value = pt->value.u64;
+ if (pl.value.u64_integers == NULL) {
+ pl.value.u64_integers = tmp;
+ } else {
+ tmp->next = pl.value.u64_integers;
+ pl.value.u64_integers = tmp;
+ }
+ break;
+ }
+ case PTYPE_NUMBER: {
+ numberList *tmp = g_new0(numberList, 1);
+ tmp->value = pt->value.number;
+ if (pl.value.numbers == NULL) {
+ pl.value.numbers = tmp;
+ } else {
+ tmp->next = pl.value.numbers;
+ pl.value.numbers = tmp;
+ }
+ break;
+ }
+ case PTYPE_BOOLEAN: {
+ boolList *tmp = g_new0(boolList, 1);
+ tmp->value = pt->value.boolean;
+ if (pl.value.booleans == NULL) {
+ pl.value.booleans = tmp;
+ } else {
+ tmp->next = pl.value.booleans;
+ pl.value.booleans = tmp;
+ }
+ break;
+ }
+ default:
+ g_assert(0);
+ }
+ }
+
+ ops->serialize((void **)&pl, &serialize_data, visit_primitive_list, &err);
+ ops->deserialize((void **)&pl_copy_ptr, serialize_data, visit_primitive_list, &err);
+
+ g_assert(err == NULL);
+ i = 0;
+
+ /* compare our deserialized list of primitives to the original */
+ do {
+ switch (pl_copy.type) {
+ case PTYPE_STRING: {
+ strList *ptr;
+ if (cur_head) {
+ ptr = cur_head;
+ cur_head = ptr->next;
+ } else {
+ cur_head = ptr = pl_copy.value.strings;
+ }
+ g_assert_cmpstr(pt->value.string, ==, ptr->value);
+ break;
+ }
+ case PTYPE_INTEGER: {
+ intList *ptr;
+ if (cur_head) {
+ ptr = cur_head;
+ cur_head = ptr->next;
+ } else {
+ cur_head = ptr = pl_copy.value.integers;
+ }
+ g_assert_cmpint(pt->value.integer, ==, ptr->value);
+ break;
+ }
+ case PTYPE_S8: {
+ int8List *ptr;
+ if (cur_head) {
+ ptr = cur_head;
+ cur_head = ptr->next;
+ } else {
+ cur_head = ptr = pl_copy.value.s8_integers;
+ }
+ g_assert_cmpint(pt->value.s8, ==, ptr->value);
+ break;
+ }
+ case PTYPE_S16: {
+ int16List *ptr;
+ if (cur_head) {
+ ptr = cur_head;
+ cur_head = ptr->next;
+ } else {
+ cur_head = ptr = pl_copy.value.s16_integers;
+ }
+ g_assert_cmpint(pt->value.s16, ==, ptr->value);
+ break;
+ }
+ case PTYPE_S32: {
+ int32List *ptr;
+ if (cur_head) {
+ ptr = cur_head;
+ cur_head = ptr->next;
+ } else {
+ cur_head = ptr = pl_copy.value.s32_integers;
+ }
+ g_assert_cmpint(pt->value.s32, ==, ptr->value);
+ break;
+ }
+ case PTYPE_S64: {
+ int64List *ptr;
+ if (cur_head) {
+ ptr = cur_head;
+ cur_head = ptr->next;
+ } else {
+ cur_head = ptr = pl_copy.value.s64_integers;
+ }
+ g_assert_cmpint(pt->value.s64, ==, ptr->value);
+ break;
+ }
+ case PTYPE_U8: {
+ uint8List *ptr;
+ if (cur_head) {
+ ptr = cur_head;
+ cur_head = ptr->next;
+ } else {
+ cur_head = ptr = pl_copy.value.u8_integers;
+ }
+ g_assert_cmpint(pt->value.u8, ==, ptr->value);
+ break;
+ }
+ case PTYPE_U16: {
+ uint16List *ptr;
+ if (cur_head) {
+ ptr = cur_head;
+ cur_head = ptr->next;
+ } else {
+ cur_head = ptr = pl_copy.value.u16_integers;
+ }
+ g_assert_cmpint(pt->value.u16, ==, ptr->value);
+ break;
+ }
+ case PTYPE_U32: {
+ uint32List *ptr;
+ if (cur_head) {
+ ptr = cur_head;
+ cur_head = ptr->next;
+ } else {
+ cur_head = ptr = pl_copy.value.u32_integers;
+ }
+ g_assert_cmpint(pt->value.u32, ==, ptr->value);
+ break;
+ }
+ case PTYPE_U64: {
+ uint64List *ptr;
+ if (cur_head) {
+ ptr = cur_head;
+ cur_head = ptr->next;
+ } else {
+ cur_head = ptr = pl_copy.value.u64_integers;
+ }
+ g_assert_cmpint(pt->value.u64, ==, ptr->value);
+ break;
+ }
+ case PTYPE_NUMBER: {
+ numberList *ptr;
+ GString *double_expected = g_string_new("");
+ GString *double_actual = g_string_new("");
+ if (cur_head) {
+ ptr = cur_head;
+ cur_head = ptr->next;
+ } else {
+ cur_head = ptr = pl_copy.value.numbers;
+ }
+ /* we serialize with %f for our reference visitors, so rather than
+ * fuzzy floating math to test "equality", just compare the
+ * formatted values
+ */
+ g_string_printf(double_expected, "%.6f", pt->value.number);
+ g_string_printf(double_actual, "%.6f", ptr->value);
+ g_assert_cmpstr(double_actual->str, ==, double_expected->str);
+ g_string_free(double_expected, true);
+ g_string_free(double_actual, true);
+ break;
+ }
+ case PTYPE_BOOLEAN: {
+ boolList *ptr;
+ if (cur_head) {
+ ptr = cur_head;
+ cur_head = ptr->next;
+ } else {
+ cur_head = ptr = pl_copy.value.booleans;
+ }
+ g_assert_cmpint(!!pt->value.boolean, ==, !!ptr->value);
+ break;
+ }
+ default:
+ g_assert(0);
+ }
+ i++;
+ } while (cur_head);
+
+ g_assert_cmpint(i, ==, 33);
+
+ ops->cleanup(serialize_data);
+ dealloc_helper(&pl, visit_primitive_list, &err);
+ g_assert(!err);
+ dealloc_helper(&pl_copy, visit_primitive_list, &err);
+ g_assert(!err);
+ g_free(args);
+}
+
static void test_struct(gconstpointer opaque)
{
TestArgs *args = (TestArgs *) opaque;
@@ -728,7 +1120,8 @@ static const SerializeOps visitors[] = {
.serialize = qmp_serialize,
.deserialize = qmp_deserialize,
.cleanup = qmp_cleanup,
- .caps = VCAP_PRIMITIVES | VCAP_STRUCTURES | VCAP_LISTS
+ .caps = VCAP_PRIMITIVES | VCAP_STRUCTURES | VCAP_LISTS |
+ VCAP_PRIMITIVE_LISTS
},
{
.type = "String",
@@ -782,6 +1175,19 @@ static void add_visitor_type(const SerializeOps *ops)
args->test_data = NULL;
g_test_add_data_func(testname, args, test_nested_struct_list);
}
+
+ if (ops->caps & VCAP_PRIMITIVE_LISTS) {
+ i = 0;
+ while (pt_values[i].type != PTYPE_EOL) {
+ sprintf(testname, "%s/primitive_list/%s", testname_prefix,
+ pt_values[i].description);
+ args = g_malloc0(sizeof(*args));
+ args->ops = ops;
+ args->test_data = &pt_values[i];
+ g_test_add_data_func(testname, args, test_primitive_lists);
+ i++;
+ }
+ }
}
int main(int argc, char **argv)
diff --git a/trace-events b/trace-events
index 9c73931f37..c5f1ccb96d 100644
--- a/trace-events
+++ b/trace-events
@@ -813,9 +813,6 @@ xen_map_cache_return(void* ptr) "%p"
xen_map_block(uint64_t phys_addr, uint64_t size) "%#"PRIx64", size %#"PRIx64
xen_unmap_block(void* addr, unsigned long size) "%p, size %#lx"
-# exec.c
-qemu_put_ram_ptr(void* addr) "%p"
-
# hw/xen_platform.c
xen_platform_log(char *s) "xen platform: %s"
@@ -825,7 +822,7 @@ qemu_coroutine_yield(void *from, void *to) "from %p to %p"
qemu_coroutine_terminate(void *co) "self %p"
# qemu-coroutine-lock.c
-qemu_co_queue_next_bh(void) ""
+qemu_co_queue_run_restart(void *co) "co %p"
qemu_co_queue_next(void *nxt) "next %p"
qemu_co_mutex_lock_entry(void *mutex, void *self) "mutex %p self %p"
qemu_co_mutex_lock_return(void *mutex, void *self) "mutex %p self %p"
diff --git a/translate-all.c b/translate-all.c
index da93608f03..211be314cb 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -55,7 +55,6 @@
#else
#include "exec/address-spaces.h"
#endif
-#include "qemu/timer.h"
#include "exec/cputlb.h"
#include "translate-all.h"
@@ -1359,7 +1358,7 @@ void tb_invalidate_phys_addr(hwaddr addr)
section = phys_page_find(address_space_memory.dispatch,
addr >> TARGET_PAGE_BITS);
if (!(memory_region_is_ram(section->mr)
- || (section->mr->rom_device && section->mr->readable))) {
+ || memory_region_is_romd(section->mr))) {
return;
}
ram_addr = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
diff --git a/ui/cocoa.m b/ui/cocoa.m
index 1971d9cb09..be491794dc 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -35,6 +35,9 @@
#ifndef MAC_OS_X_VERSION_10_5
#define MAC_OS_X_VERSION_10_5 1050
#endif
+#ifndef MAC_OS_X_VERSION_10_6
+#define MAC_OS_X_VERSION_10_6 1060
+#endif
//#define DEBUG
@@ -771,9 +774,20 @@ QemuCocoaView *cocoaView;
NSOpenPanel *op = [[NSOpenPanel alloc] init];
[op setPrompt:@"Boot image"];
[op setMessage:@"Select the disk image you want to boot.\n\nHit the \"Cancel\" button to quit"];
- [op beginSheetForDirectory:nil file:nil types:[NSArray arrayWithObjects:@"img",@"iso",@"dmg",@"qcow",@"cow",@"cloop",@"vmdk",nil]
+ NSArray *filetypes = [NSArray arrayWithObjects:@"img", @"iso", @"dmg",
+ @"qcow", @"cow", @"cloop", @"vmdk", nil];
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
+ [op setAllowedFileTypes:filetypes];
+ [op beginSheetModalForWindow:normalWindow
+ completionHandler:^(NSInteger returnCode)
+ { [self openPanelDidEnd:op
+ returnCode:returnCode contextInfo:NULL ]; } ];
+#else
+ // Compatibility code for pre-10.6, using deprecated method
+ [op beginSheetForDirectory:nil file:nil types:filetypes
modalForWindow:normalWindow modalDelegate:self
didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
+#endif
} else {
// or launch QEMU, with the global args
[self startEmulationWithArgc:gArgc argv:(char **)gArgv];
@@ -810,7 +824,7 @@ QemuCocoaView *cocoaView;
exit(0);
} else if(returnCode == NSOKButton) {
const char *bin = "qemu";
- char *img = (char*)[ [ sheet filename ] cStringUsingEncoding:NSASCIIStringEncoding];
+ char *img = (char*)[ [ [ sheet URL ] path ] cStringUsingEncoding:NSASCIIStringEncoding];
char **argv = (char**)malloc( sizeof(char*)*3 );
@@ -851,22 +865,10 @@ QemuCocoaView *cocoaView;
-// Dock Connection
-typedef struct CPSProcessSerNum
-{
- UInt32 lo;
- UInt32 hi;
-} CPSProcessSerNum;
-
-OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
-OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
-OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
-
int main (int argc, const char * argv[]) {
gArgc = argc;
gArgv = (char **)argv;
- CPSProcessSerNum PSN;
int i;
/* In case we don't need to display a window, let's not do that */
@@ -890,12 +892,13 @@ int main (int argc, const char * argv[]) {
}
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
- [NSApplication sharedApplication];
- if (!CPSGetCurrentProcess(&PSN))
- if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
- if (!CPSSetFrontProcess(&PSN))
- [NSApplication sharedApplication];
+ // Pull this console process up to being a fully-fledged graphical
+ // app with a menubar and Dock icon
+ ProcessSerialNumber psn = { 0, kCurrentProcess };
+ TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+
+ [NSApplication sharedApplication];
// Add menus
NSMenu *menu;
@@ -960,6 +963,8 @@ int main (int argc, const char * argv[]) {
static void cocoa_update(DisplayChangeListener *dcl,
int x, int y, int w, int h)
{
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
COCOA_DEBUG("qemu_cocoa: cocoa_update\n");
NSRect rect;
@@ -973,18 +978,24 @@ static void cocoa_update(DisplayChangeListener *dcl,
h * [cocoaView cdy]);
}
[cocoaView setNeedsDisplayInRect:rect];
+
+ [pool release];
}
static void cocoa_switch(DisplayChangeListener *dcl,
DisplaySurface *surface)
{
- COCOA_DEBUG("qemu_cocoa: cocoa_resize\n");
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
[cocoaView switchSurface:surface];
+ [pool release];
}
static void cocoa_refresh(DisplayChangeListener *dcl)
{
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n");
if (kbd_mouse_is_absolute()) {
@@ -1007,6 +1018,7 @@ static void cocoa_refresh(DisplayChangeListener *dcl)
}
} while(event != nil);
graphic_hw_update(NULL);
+ [pool release];
}
static void cocoa_cleanup(void)
diff --git a/ui/input.c b/ui/input.c
index 8ca1a03e12..92c44ca810 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -28,6 +28,7 @@
#include "qapi/error.h"
#include "qmp-commands.h"
#include "qapi-types.h"
+#include "ui/keymaps.h"
struct QEMUPutMouseEntry {
QEMUPutMouseEvent *qemu_put_mouse_event;
@@ -260,10 +261,10 @@ static void free_keycodes(void)
static void release_keys(void *opaque)
{
while (keycodes_size > 0) {
- if (keycodes[--keycodes_size] & 0x80) {
- kbd_put_keycode(0xe0);
+ if (keycodes[--keycodes_size] & SCANCODE_GREY) {
+ kbd_put_keycode(SCANCODE_EMUL0);
}
- kbd_put_keycode(keycodes[keycodes_size] | 0x80);
+ kbd_put_keycode(keycodes[keycodes_size] | SCANCODE_UP);
}
free_keycodes();
@@ -297,10 +298,10 @@ void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time,
return;
}
- if (keycode & 0x80) {
- kbd_put_keycode(0xe0);
+ if (keycode & SCANCODE_GREY) {
+ kbd_put_keycode(SCANCODE_EMUL0);
}
- kbd_put_keycode(keycode & 0x7f);
+ kbd_put_keycode(keycode & SCANCODE_KEYCODEMASK);
keycodes = g_realloc(keycodes, sizeof(int) * (keycodes_size + 1));
keycodes[keycodes_size++] = keycode;
diff --git a/vl.c b/vl.c
index 59dc0b45da..510d2c2ce4 100644
--- a/vl.c
+++ b/vl.c
@@ -3366,8 +3366,10 @@ int main(int argc, char **argv, char **envp)
break;
}
case QEMU_OPTION_monitor:
- monitor_parse(optarg, "readline");
default_monitor = 0;
+ if (strncmp(optarg, "none", 4)) {
+ monitor_parse(optarg, "readline");
+ }
break;
case QEMU_OPTION_qmp:
monitor_parse(optarg, "control");