Merge branch 'linux-user.next' of git://git.linaro.org/people/pmaydell/qemu-arm
* 'linux-user.next' of git://git.linaro.org/people/pmaydell/qemu-arm:
linux-user: ARM: Ignore immediate value for svc in thumb mode
linux-user: Use init_guest_space when -R and -B are specified
linux-user: Factor out guest space probing into a function
flatload: fix bss clearing
linux-user: make host_to_target_cmsg support SO_TIMESTAMP cmsg_type
linux-user: make do_setsockopt support SOL_RAW ICMP_FILTER socket option
linux-user: pass sockaddr from host to target
linux-user: Move target_to_host_errno_table[] setup out of ioctl loop
linux-user: Fix SNDCTL_DSP_MAP{IN, OUT}BUF ioctl definitions
linux-user: Fix incorrect TARGET_BLKBSZGET, TARGET_BLKBSZSET
diff --git a/Makefile.objs b/Makefile.objs
index 5ebbcfa..309d066 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -77,6 +77,7 @@
common-obj-y += block-migration.o iohandler.o
common-obj-y += pflib.o
common-obj-y += bitmap.o bitops.o
+common-obj-y += page_cache.o
common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
common-obj-$(CONFIG_WIN32) += version.o
@@ -211,6 +212,7 @@
# qapi
qapi-obj-y = qapi/
+qapi-obj-y += qapi-types.o qapi-visit.o
common-obj-y += qmp-marshal.o qapi-visit.o qapi-types.o
common-obj-y += qmp.o hmp.o
diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt
index 9ba7079..2878058 100644
--- a/QMP/qmp-events.txt
+++ b/QMP/qmp-events.txt
@@ -1,6 +1,23 @@
QEMU Monitor Protocol Events
============================
+BALLOON_CHANGE
+--------------
+
+Emitted when the guest changes the actual BALLOON level. This
+value is equivalent to the 'actual' field return by the
+'query-balloon' command
+
+Data:
+
+- "actual": actual level of the guest memory balloon in bytes (json-number)
+
+Example:
+
+{ "event": "BALLOON_CHANGE",
+ "data": { "actual": 944766976 },
+ "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
+
BLOCK_IO_ERROR
--------------
@@ -26,6 +43,57 @@
Note: If action is "stop", a STOP event will eventually follow the
BLOCK_IO_ERROR event.
+BLOCK_JOB_CANCELLED
+-------------------
+
+Emitted when a block job has been cancelled.
+
+Data:
+
+- "type": Job type ("stream" for image streaming, json-string)
+- "device": Device name (json-string)
+- "len": Maximum progress value (json-int)
+- "offset": Current progress value (json-int)
+ On success this is equal to len.
+ On failure this is less than len.
+- "speed": Rate limit, bytes per second (json-int)
+
+Example:
+
+{ "event": "BLOCK_JOB_CANCELLED",
+ "data": { "type": "stream", "device": "virtio-disk0",
+ "len": 10737418240, "offset": 134217728,
+ "speed": 0 },
+ "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
+
+BLOCK_JOB_COMPLETED
+-------------------
+
+Emitted when a block job has completed.
+
+Data:
+
+- "type": Job type ("stream" for image streaming, json-string)
+- "device": Device name (json-string)
+- "len": Maximum progress value (json-int)
+- "offset": Current progress value (json-int)
+ On success this is equal to len.
+ On failure this is less than len.
+- "speed": Rate limit, bytes per second (json-int)
+- "error": Error message (json-string, optional)
+ Only present on failure. This field contains a human-readable
+ error message. There are no semantics other than that streaming
+ has failed and clients should not try to interpret the error
+ string.
+
+Example:
+
+{ "event": "BLOCK_JOB_COMPLETED",
+ "data": { "type": "stream", "device": "virtio-disk0",
+ "len": 10737418240, "offset": 10737418240,
+ "speed": 0 },
+ "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
+
DEVICE_TRAY_MOVED
-----------------
@@ -98,6 +166,68 @@
Note: If the command-line option "-no-shutdown" has been specified, a STOP
event will eventually follow the SHUTDOWN event.
+SPICE_CONNECTED, SPICE_DISCONNECTED
+-----------------------------------
+
+Emitted when a SPICE client connects or disconnects.
+
+Data:
+
+- "server": Server information (json-object)
+ - "host": IP address (json-string)
+ - "port": port number (json-string)
+ - "family": address family (json-string, "ipv4" or "ipv6")
+- "client": Client information (json-object)
+ - "host": IP address (json-string)
+ - "port": port number (json-string)
+ - "family": address family (json-string, "ipv4" or "ipv6")
+
+Example:
+
+{ "timestamp": {"seconds": 1290688046, "microseconds": 388707},
+ "event": "SPICE_CONNECTED",
+ "data": {
+ "server": { "port": "5920", "family": "ipv4", "host": "127.0.0.1"},
+ "client": {"port": "52873", "family": "ipv4", "host": "127.0.0.1"}
+}}
+
+SPICE_INITIALIZED
+-----------------
+
+Emitted after initial handshake and authentication takes place (if any)
+and the SPICE channel is up'n'running
+
+Data:
+
+- "server": Server information (json-object)
+ - "host": IP address (json-string)
+ - "port": port number (json-string)
+ - "family": address family (json-string, "ipv4" or "ipv6")
+ - "auth": authentication method (json-string, optional)
+- "client": Client information (json-object)
+ - "host": IP address (json-string)
+ - "port": port number (json-string)
+ - "family": address family (json-string, "ipv4" or "ipv6")
+ - "connection-id": spice connection id. All channels with the same id
+ belong to the same spice session (json-int)
+ - "channel-type": channel type. "1" is the main control channel, filter for
+ this one if you want track spice sessions only (json-int)
+ - "channel-id": channel id. Usually "0", might be different needed when
+ multiple channels of the same type exist, such as multiple
+ display channels in a multihead setup (json-int)
+ - "tls": whevener the channel is encrypted (json-bool)
+
+Example:
+
+{ "timestamp": {"seconds": 1290688046, "microseconds": 417172},
+ "event": "SPICE_INITIALIZED",
+ "data": {"server": {"auth": "spice", "port": "5921",
+ "family": "ipv4", "host": "127.0.0.1"},
+ "client": {"port": "49004", "family": "ipv4", "channel-type": 3,
+ "connection-id": 1804289383, "host": "127.0.0.1",
+ "channel-id": 0, "tls": true}
+}}
+
STOP
----
@@ -110,6 +240,32 @@
{ "event": "STOP",
"timestamp": { "seconds": 1267041730, "microseconds": 281295 } }
+SUSPEND
+-------
+
+Emitted when guest enters S3 state.
+
+Data: None.
+
+Example:
+
+{ "event": "SUSPEND",
+ "timestamp": { "seconds": 1344456160, "microseconds": 309119 } }
+
+SUSPEND_DISK
+------------
+
+Emitted when the guest makes a request to enter S4 state.
+
+Data: None.
+
+Example:
+
+{ "event": "SUSPEND_DISK",
+ "timestamp": { "seconds": 1344456160, "microseconds": 309119 } }
+
+Note: QEMU shuts down when entering S4 state.
+
VNC_CONNECTED
-------------
@@ -200,69 +356,17 @@
"host": "127.0.0.1", "sasl_username": "luiz" } },
"timestamp": { "seconds": 1263475302, "microseconds": 150772 } }
-SPICE_CONNECTED, SPICE_DISCONNECTED
------------------------------------
+WAKEUP
+------
-Emitted when a SPICE client connects or disconnects.
+Emitted when the guest has woken up from S3 and is running.
-Data:
-
-- "server": Server information (json-object)
- - "host": IP address (json-string)
- - "port": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
-- "client": Client information (json-object)
- - "host": IP address (json-string)
- - "port": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
+Data: None.
Example:
-{ "timestamp": {"seconds": 1290688046, "microseconds": 388707},
- "event": "SPICE_CONNECTED",
- "data": {
- "server": { "port": "5920", "family": "ipv4", "host": "127.0.0.1"},
- "client": {"port": "52873", "family": "ipv4", "host": "127.0.0.1"}
-}}
-
-
-SPICE_INITIALIZED
------------------
-
-Emitted after initial handshake and authentication takes place (if any)
-and the SPICE channel is up'n'running
-
-Data:
-
-- "server": Server information (json-object)
- - "host": IP address (json-string)
- - "port": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "auth": authentication method (json-string, optional)
-- "client": Client information (json-object)
- - "host": IP address (json-string)
- - "port": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "connection-id": spice connection id. All channels with the same id
- belong to the same spice session (json-int)
- - "channel-type": channel type. "1" is the main control channel, filter for
- this one if you want track spice sessions only (json-int)
- - "channel-id": channel id. Usually "0", might be different needed when
- multiple channels of the same type exist, such as multiple
- display channels in a multihead setup (json-int)
- - "tls": whevener the channel is encrypted (json-bool)
-
-Example:
-
-{ "timestamp": {"seconds": 1290688046, "microseconds": 417172},
- "event": "SPICE_INITIALIZED",
- "data": {"server": {"auth": "spice", "port": "5921",
- "family": "ipv4", "host": "127.0.0.1"},
- "client": {"port": "49004", "family": "ipv4", "channel-type": 3,
- "connection-id": 1804289383, "host": "127.0.0.1",
- "channel-id": 0, "tls": true}
-}}
-
+{ "event": "WATCHDOG",
+ "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
WATCHDOG
--------
@@ -282,74 +386,3 @@
Note: If action is "reset", "shutdown", or "pause" the WATCHDOG event is
followed respectively by the RESET, SHUTDOWN, or STOP events.
-
-
-BLOCK_JOB_COMPLETED
--------------------
-
-Emitted when a block job has completed.
-
-Data:
-
-- "type": Job type ("stream" for image streaming, json-string)
-- "device": Device name (json-string)
-- "len": Maximum progress value (json-int)
-- "offset": Current progress value (json-int)
- On success this is equal to len.
- On failure this is less than len.
-- "speed": Rate limit, bytes per second (json-int)
-- "error": Error message (json-string, optional)
- Only present on failure. This field contains a human-readable
- error message. There are no semantics other than that streaming
- has failed and clients should not try to interpret the error
- string.
-
-Example:
-
-{ "event": "BLOCK_JOB_COMPLETED",
- "data": { "type": "stream", "device": "virtio-disk0",
- "len": 10737418240, "offset": 10737418240,
- "speed": 0 },
- "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
-
-
-BLOCK_JOB_CANCELLED
--------------------
-
-Emitted when a block job has been cancelled.
-
-Data:
-
-- "type": Job type ("stream" for image streaming, json-string)
-- "device": Device name (json-string)
-- "len": Maximum progress value (json-int)
-- "offset": Current progress value (json-int)
- On success this is equal to len.
- On failure this is less than len.
-- "speed": Rate limit, bytes per second (json-int)
-
-Example:
-
-{ "event": "BLOCK_JOB_CANCELLED",
- "data": { "type": "stream", "device": "virtio-disk0",
- "len": 10737418240, "offset": 134217728,
- "speed": 0 },
- "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
-
-
-BALLOON_CHANGE
-----------
-
-Emitted when the guest changes the actual BALLOON level. This
-value is equivalent to the 'actual' field return by the
-'query-balloon' command
-
-Data:
-
-- "actual": actual level of the guest memory balloon in bytes (json-number)
-
-Example:
-
-{ "event": "BALLOON_CHANGE",
- "data": { "actual": 944766976 },
- "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
diff --git a/QMP/qmp-spec.txt b/QMP/qmp-spec.txt
index 1ba916c..a277896 100644
--- a/QMP/qmp-spec.txt
+++ b/QMP/qmp-spec.txt
@@ -106,14 +106,11 @@
The format is:
-{ "error": { "class": json-string, "data": json-object, "desc": json-string },
- "id": json-value }
+{ "error": { "class": json-string, "desc": json-string }, "id": json-value }
Where,
-- The "class" member contains the error class name (eg. "ServiceUnavailable")
-- The "data" member contains specific error data and is defined in a
- per-command basis, it will be an empty json-object if the error has no data
+- The "class" member contains the error class name (eg. "GenericError")
- The "desc" member is a human-readable error message. Clients should
not attempt to parse this message.
- The "id" member contains the transaction identification associated with
@@ -173,8 +170,7 @@
------------------
C: { "execute": }
-S: {"error": {"class": "JSONParsing", "desc": "Invalid JSON syntax", "data":
-{}}}
+S: {"error": {"class": "GenericError", "desc": "Invalid JSON syntax" } }
3.5 Powerdown event
-------------------
diff --git a/arch_init.c b/arch_init.c
index 7b65c48..9b46bfc 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -43,6 +43,7 @@
#include "hw/smbios.h"
#include "exec-memory.h"
#include "hw/pcspk.h"
+#include "qemu/page_cache.h"
#ifdef DEBUG_ARCH_INIT
#define DPRINTF(fmt, ...) \
@@ -106,6 +107,7 @@
#define RAM_SAVE_FLAG_PAGE 0x08
#define RAM_SAVE_FLAG_EOS 0x10
#define RAM_SAVE_FLAG_CONTINUE 0x20
+#define RAM_SAVE_FLAG_XBZRLE 0x40
#ifdef __ALTIVEC__
#include <altivec.h>
@@ -173,6 +175,92 @@
return 1;
}
+/* struct contains XBZRLE cache and a static page
+ used by the compression */
+static struct {
+ /* buffer used for XBZRLE encoding */
+ uint8_t *encoded_buf;
+ /* buffer for storing page content */
+ uint8_t *current_buf;
+ /* buffer used for XBZRLE decoding */
+ uint8_t *decoded_buf;
+ /* Cache for XBZRLE */
+ PageCache *cache;
+} XBZRLE = {
+ .encoded_buf = NULL,
+ .current_buf = NULL,
+ .decoded_buf = NULL,
+ .cache = NULL,
+};
+
+
+int64_t xbzrle_cache_resize(int64_t new_size)
+{
+ if (XBZRLE.cache != NULL) {
+ return cache_resize(XBZRLE.cache, new_size / TARGET_PAGE_SIZE) *
+ TARGET_PAGE_SIZE;
+ }
+ return pow2floor(new_size);
+}
+
+/* accounting for migration statistics */
+typedef struct AccountingInfo {
+ uint64_t dup_pages;
+ uint64_t norm_pages;
+ uint64_t iterations;
+ uint64_t xbzrle_bytes;
+ uint64_t xbzrle_pages;
+ uint64_t xbzrle_cache_miss;
+ uint64_t xbzrle_overflows;
+} AccountingInfo;
+
+static AccountingInfo acct_info;
+
+static void acct_clear(void)
+{
+ memset(&acct_info, 0, sizeof(acct_info));
+}
+
+uint64_t dup_mig_bytes_transferred(void)
+{
+ return acct_info.dup_pages * TARGET_PAGE_SIZE;
+}
+
+uint64_t dup_mig_pages_transferred(void)
+{
+ return acct_info.dup_pages;
+}
+
+uint64_t norm_mig_bytes_transferred(void)
+{
+ return acct_info.norm_pages * TARGET_PAGE_SIZE;
+}
+
+uint64_t norm_mig_pages_transferred(void)
+{
+ return acct_info.norm_pages;
+}
+
+uint64_t xbzrle_mig_bytes_transferred(void)
+{
+ return acct_info.xbzrle_bytes;
+}
+
+uint64_t xbzrle_mig_pages_transferred(void)
+{
+ return acct_info.xbzrle_pages;
+}
+
+uint64_t xbzrle_mig_pages_cache_miss(void)
+{
+ return acct_info.xbzrle_cache_miss;
+}
+
+uint64_t xbzrle_mig_pages_overflow(void)
+{
+ return acct_info.xbzrle_overflows;
+}
+
static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
int cont, int flag)
{
@@ -185,6 +273,61 @@
}
+#define ENCODING_FLAG_XBZRLE 0x1
+
+static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
+ ram_addr_t current_addr, RAMBlock *block,
+ ram_addr_t offset, int cont, bool last_stage)
+{
+ int encoded_len = 0, bytes_sent = -1;
+ uint8_t *prev_cached_page;
+
+ if (!cache_is_cached(XBZRLE.cache, current_addr)) {
+ if (!last_stage) {
+ cache_insert(XBZRLE.cache, current_addr,
+ g_memdup(current_data, TARGET_PAGE_SIZE));
+ }
+ acct_info.xbzrle_cache_miss++;
+ return -1;
+ }
+
+ prev_cached_page = get_cached_data(XBZRLE.cache, current_addr);
+
+ /* save current buffer into memory */
+ memcpy(XBZRLE.current_buf, current_data, TARGET_PAGE_SIZE);
+
+ /* XBZRLE encoding (if there is no overflow) */
+ encoded_len = xbzrle_encode_buffer(prev_cached_page, XBZRLE.current_buf,
+ TARGET_PAGE_SIZE, XBZRLE.encoded_buf,
+ TARGET_PAGE_SIZE);
+ if (encoded_len == 0) {
+ DPRINTF("Skipping unmodified page\n");
+ return 0;
+ } else if (encoded_len == -1) {
+ DPRINTF("Overflow\n");
+ acct_info.xbzrle_overflows++;
+ /* update data in the cache */
+ memcpy(prev_cached_page, current_data, TARGET_PAGE_SIZE);
+ return -1;
+ }
+
+ /* we need to update the data in the cache, in order to get the same data */
+ if (!last_stage) {
+ memcpy(prev_cached_page, XBZRLE.current_buf, TARGET_PAGE_SIZE);
+ }
+
+ /* Send XBZRLE based compressed page */
+ save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_XBZRLE);
+ qemu_put_byte(f, ENCODING_FLAG_XBZRLE);
+ qemu_put_be16(f, encoded_len);
+ qemu_put_buffer(f, XBZRLE.encoded_buf, encoded_len);
+ bytes_sent = encoded_len + 1 + 2;
+ acct_info.xbzrle_pages++;
+ acct_info.xbzrle_bytes += bytes_sent;
+
+ return bytes_sent;
+}
+
static RAMBlock *last_block;
static ram_addr_t last_offset;
@@ -196,12 +339,13 @@
* n: the amount of bytes written in other case
*/
-static int ram_save_block(QEMUFile *f)
+static int ram_save_block(QEMUFile *f, bool last_stage)
{
RAMBlock *block = last_block;
ram_addr_t offset = last_offset;
int bytes_sent = -1;
MemoryRegion *mr;
+ ram_addr_t current_addr;
if (!block)
block = QLIST_FIRST(&ram_list.blocks);
@@ -219,16 +363,31 @@
p = memory_region_get_ram_ptr(mr) + offset;
if (is_dup_page(p)) {
+ acct_info.dup_pages++;
save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_COMPRESS);
qemu_put_byte(f, *p);
bytes_sent = 1;
- } else {
+ } else if (migrate_use_xbzrle()) {
+ current_addr = block->offset + offset;
+ bytes_sent = save_xbzrle_page(f, p, current_addr, block,
+ offset, cont, last_stage);
+ if (!last_stage) {
+ p = get_cached_data(XBZRLE.cache, current_addr);
+ }
+ }
+
+ /* either we didn't send yet (we may have had XBZRLE overflow) */
+ if (bytes_sent == -1) {
save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE);
qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
bytes_sent = TARGET_PAGE_SIZE;
+ acct_info.norm_pages++;
}
- break;
+ /* if page is unmodified, continue to the next */
+ if (bytes_sent != 0) {
+ break;
+ }
}
offset += TARGET_PAGE_SIZE;
@@ -306,6 +465,15 @@
static void migration_end(void)
{
memory_global_dirty_log_stop();
+
+ if (migrate_use_xbzrle()) {
+ cache_fini(XBZRLE.cache);
+ g_free(XBZRLE.cache);
+ g_free(XBZRLE.encoded_buf);
+ g_free(XBZRLE.current_buf);
+ g_free(XBZRLE.decoded_buf);
+ XBZRLE.cache = NULL;
+ }
}
static void ram_migration_cancel(void *opaque)
@@ -325,6 +493,19 @@
last_offset = 0;
sort_ram_list();
+ if (migrate_use_xbzrle()) {
+ XBZRLE.cache = cache_init(migrate_xbzrle_cache_size() /
+ TARGET_PAGE_SIZE,
+ TARGET_PAGE_SIZE);
+ if (!XBZRLE.cache) {
+ DPRINTF("Error creating cache\n");
+ return -1;
+ }
+ XBZRLE.encoded_buf = g_malloc0(TARGET_PAGE_SIZE);
+ XBZRLE.current_buf = g_malloc(TARGET_PAGE_SIZE);
+ acct_clear();
+ }
+
/* Make sure all dirty bits are set */
QLIST_FOREACH(block, &ram_list.blocks, next) {
for (addr = 0; addr < block->length; addr += TARGET_PAGE_SIZE) {
@@ -365,12 +546,13 @@
while ((ret = qemu_file_rate_limit(f)) == 0) {
int bytes_sent;
- bytes_sent = ram_save_block(f);
+ bytes_sent = ram_save_block(f, false);
/* no more blocks to sent */
if (bytes_sent < 0) {
break;
}
bytes_transferred += bytes_sent;
+ acct_info.iterations++;
/* we want to check in the 1st loop, just in case it was the 1st time
and we had to sync the dirty bitmap.
qemu_get_clock_ns() is a bit expensive, so we only check each some
@@ -426,7 +608,7 @@
while (true) {
int bytes_sent;
- bytes_sent = ram_save_block(f);
+ bytes_sent = ram_save_block(f, true);
/* no more blocks to sent */
if (bytes_sent < 0) {
break;
@@ -440,6 +622,47 @@
return 0;
}
+static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host)
+{
+ int ret, rc = 0;
+ unsigned int xh_len;
+ int xh_flags;
+
+ if (!XBZRLE.decoded_buf) {
+ XBZRLE.decoded_buf = g_malloc(TARGET_PAGE_SIZE);
+ }
+
+ /* extract RLE header */
+ xh_flags = qemu_get_byte(f);
+ xh_len = qemu_get_be16(f);
+
+ if (xh_flags != ENCODING_FLAG_XBZRLE) {
+ fprintf(stderr, "Failed to load XBZRLE page - wrong compression!\n");
+ return -1;
+ }
+
+ if (xh_len > TARGET_PAGE_SIZE) {
+ fprintf(stderr, "Failed to load XBZRLE page - len overflow!\n");
+ return -1;
+ }
+ /* load data and decode */
+ qemu_get_buffer(f, XBZRLE.decoded_buf, xh_len);
+
+ /* decode RLE */
+ ret = xbzrle_decode_buffer(XBZRLE.decoded_buf, xh_len, host,
+ TARGET_PAGE_SIZE);
+ if (ret == -1) {
+ fprintf(stderr, "Failed to load XBZRLE page - decode error!\n");
+ rc = -1;
+ } else if (ret > TARGET_PAGE_SIZE) {
+ fprintf(stderr, "Failed to load XBZRLE page - size %d exceeds %d!\n",
+ ret, TARGET_PAGE_SIZE);
+ abort();
+ }
+
+ return rc;
+}
+
static inline void *host_from_stream_offset(QEMUFile *f,
ram_addr_t offset,
int flags)
@@ -553,6 +776,19 @@
}
qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
+ } else if (flags & RAM_SAVE_FLAG_XBZRLE) {
+ if (!migrate_use_xbzrle()) {
+ return -EINVAL;
+ }
+ void *host = host_from_stream_offset(f, addr, flags);
+ if (!host) {
+ return -EINVAL;
+ }
+
+ if (load_xbzrle(f, addr, host) < 0) {
+ ret = -EINVAL;
+ goto done;
+ }
}
error = qemu_file_get_error(f);
if (error) {
diff --git a/block.c b/block.c
index 24323c1..016858b 100644
--- a/block.c
+++ b/block.c
@@ -2445,6 +2445,7 @@
info->value->inserted->ro = bs->read_only;
info->value->inserted->drv = g_strdup(bs->drv->format_name);
info->value->inserted->encrypted = bs->encrypted;
+ info->value->inserted->encryption_key_missing = bdrv_key_required(bs);
if (bs->backing_file[0]) {
info->value->inserted->has_backing_file = true;
info->value->inserted->backing_file = g_strdup(bs->backing_file);
diff --git a/block_int.h b/block_int.h
index 6c1d9ca..4452f6f 100644
--- a/block_int.h
+++ b/block_int.h
@@ -30,6 +30,7 @@
#include "qemu-coroutine.h"
#include "qemu-timer.h"
#include "qapi-types.h"
+#include "qerror.h"
#define BLOCK_FLAG_ENCRYPT 1
#define BLOCK_FLAG_COMPAT6 4
diff --git a/compiler.h b/compiler.h
index 736e770..f76921e 100644
--- a/compiler.h
+++ b/compiler.h
@@ -45,6 +45,7 @@
# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2)))
# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
# endif
+#define GCC_WEAK __attribute__((weak))
#else
#define GCC_ATTR /**/
#define GCC_FMT_ATTR(n, m)
diff --git a/configure b/configure
index f0dbc03..edf9da4 100755
--- a/configure
+++ b/configure
@@ -171,7 +171,6 @@
kvm="no"
gprof="no"
debug_tcg="no"
-debug_mon="no"
debug="no"
strip_opt="yes"
tcg_interpreter="no"
@@ -657,14 +656,9 @@
;;
--disable-debug-tcg) debug_tcg="no"
;;
- --enable-debug-mon) debug_mon="yes"
- ;;
- --disable-debug-mon) debug_mon="no"
- ;;
--enable-debug)
# Enable debugging options that aren't excessively noisy
debug_tcg="yes"
- debug_mon="yes"
debug="yes"
strip_opt="no"
;;
@@ -3064,7 +3058,6 @@
echo "host big endian $bigendian"
echo "target list $target_list"
echo "tcg debug enabled $debug_tcg"
-echo "Mon debug enabled $debug_mon"
echo "gprof enabled $gprof"
echo "sparse enabled $sparse"
echo "strip binaries $strip_opt"
@@ -3157,9 +3150,6 @@
if test "$debug_tcg" = "yes" ; then
echo "CONFIG_DEBUG_TCG=y" >> $config_host_mak
fi
-if test "$debug_mon" = "yes" ; then
- echo "CONFIG_DEBUG_MONITOR=y" >> $config_host_mak
-fi
if test "$debug" = "yes" ; then
echo "CONFIG_DEBUG_EXEC=y" >> $config_host_mak
fi
@@ -3563,15 +3553,23 @@
mkdir -p linux-headers
case "$cpu" in
i386|x86_64)
- symlink "$source_path/linux-headers/asm-x86" linux-headers/asm
+ linux_arch=x86
;;
ppcemb|ppc|ppc64)
- symlink "$source_path/linux-headers/asm-powerpc" linux-headers/asm
+ linux_arch=powerpc
;;
s390x)
- symlink "$source_path/linux-headers/asm-s390" linux-headers/asm
+ linux_arch=s390
+ ;;
+ *)
+ # For most CPUs the kernel architecture name and QEMU CPU name match.
+ linux_arch="$cpu"
;;
esac
+ # For non-KVM architectures we will not have asm headers
+ if [ -e "$source_path/linux-headers/asm-$linux_arch" ]; then
+ symlink "$source_path/linux-headers/asm-$linux_arch" linux-headers/asm
+ fi
fi
for target in $target_list; do
@@ -3780,7 +3778,7 @@
case "$target_arch2" in
- alpha | or32 | sparc* | xtensa* | ppc*)
+ alpha | i386 | or32 | sparc* | x86_64 | xtensa* | ppc*)
echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
;;
esac
diff --git a/cpu-all.h b/cpu-all.h
index 82ba1d7..5e07d28 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -274,6 +274,28 @@
#define cpu_ldsw_code(env1, p) ldsw_raw(p)
#define cpu_ldl_code(env1, p) ldl_raw(p)
#define cpu_ldq_code(env1, p) ldq_raw(p)
+
+#define cpu_ldub_data(env, addr) ldub_raw(addr)
+#define cpu_lduw_data(env, addr) lduw_raw(addr)
+#define cpu_ldsw_data(env, addr) ldsw_raw(addr)
+#define cpu_ldl_data(env, addr) ldl_raw(addr)
+#define cpu_ldq_data(env, addr) ldq_raw(addr)
+
+#define cpu_stb_data(env, addr, data) stb_raw(addr, data)
+#define cpu_stw_data(env, addr, data) stw_raw(addr, data)
+#define cpu_stl_data(env, addr, data) stl_raw(addr, data)
+#define cpu_stq_data(env, addr, data) stq_raw(addr, data)
+
+#define cpu_ldub_kernel(env, addr) ldub_raw(addr)
+#define cpu_lduw_kernel(env, addr) lduw_raw(addr)
+#define cpu_ldsw_kernel(env, addr) ldsw_raw(addr)
+#define cpu_ldl_kernel(env, addr) ldl_raw(addr)
+#define cpu_ldq_kernel(env, addr) ldq_raw(addr)
+
+#define cpu_stb_kernel(env, addr, data) stb_raw(addr, data)
+#define cpu_stw_kernel(env, addr, data) stw_raw(addr, data)
+#define cpu_stl_kernel(env, addr, data) stl_raw(addr, data)
+#define cpu_stq_kernel(env, addr, data) stq_raw(addr, data)
#endif
#define ldub_kernel(p) ldub_raw(p)
diff --git a/cpus.c b/cpus.c
index 3de2e27..e476a3c 100644
--- a/cpus.c
+++ b/cpus.c
@@ -70,7 +70,8 @@
if (env->stopped || !runstate_is_running()) {
return true;
}
- if (!env->halted || qemu_cpu_has_work(env) || kvm_irqchip_in_kernel()) {
+ if (!env->halted || qemu_cpu_has_work(env) ||
+ kvm_async_interrupts_enabled()) {
return false;
}
return true;
diff --git a/cutils.c b/cutils.c
index 9d4c570..ee4614d 100644
--- a/cutils.c
+++ b/cutils.c
@@ -382,3 +382,45 @@
}
return fd;
}
+
+/* round down to the nearest power of 2*/
+int64_t pow2floor(int64_t value)
+{
+ if (!is_power_of_2(value)) {
+ value = 0x8000000000000000ULL >> clz64(value);
+ }
+ return value;
+}
+
+/*
+ * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128)
+ * Input is limited to 14-bit numbers
+ */
+int uleb128_encode_small(uint8_t *out, uint32_t n)
+{
+ g_assert(n <= 0x3fff);
+ if (n < 0x80) {
+ *out++ = n;
+ return 1;
+ } else {
+ *out++ = (n & 0x7f) | 0x80;
+ *out++ = n >> 7;
+ return 2;
+ }
+}
+
+int uleb128_decode_small(const uint8_t *in, uint32_t *n)
+{
+ if (!(*in & 0x80)) {
+ *n = *in++;
+ return 1;
+ } else {
+ *n = *in++ & 0x7f;
+ /* we exceed 14 bit number */
+ if (*in & 0x80) {
+ return -1;
+ }
+ *n |= *in++ << 7;
+ return 2;
+ }
+}
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index e542b4f..f335a72 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -27,3 +27,21 @@
CONFIG_DS1338=y
CONFIG_PFLASH_CFI01=y
CONFIG_PFLASH_CFI02=y
+
+CONFIG_ARM_TIMER=y
+CONFIG_PL011=y
+CONFIG_PL022=y
+CONFIG_PL031=y
+CONFIG_PL041=y
+CONFIG_PL050=y
+CONFIG_PL061=y
+CONFIG_PL080=y
+CONFIG_PL110=y
+CONFIG_PL181=y
+CONFIG_PL190=y
+CONFIG_PL310=y
+CONFIG_CADENCE=y
+CONFIG_XGMAC=y
+
+CONFIG_VERSATILE_PCI=y
+CONFIG_VERSATILE_I2C=y
diff --git a/docs/writing-qmp-commands.txt b/docs/writing-qmp-commands.txt
index 0ad51aa..8349dec 100644
--- a/docs/writing-qmp-commands.txt
+++ b/docs/writing-qmp-commands.txt
@@ -210,19 +210,17 @@
=== Errors ===
QMP commands should use the error interface exported by the error.h header
-file. The basic function used to set an error is the error_set() one.
+file. Basically, errors are set by calling the error_set() function.
Let's say we don't accept the string "message" to contain the word "love". If
-it does contain it, we want the "hello-world" command to the return the
-InvalidParameter error.
-
-Only one change is required, and it's in the C implementation:
+it does contain it, we want the "hello-world" command to return an error:
void qmp_hello_world(bool has_message, const char *message, Error **errp)
{
if (has_message) {
if (strstr(message, "love")) {
- error_set(errp, QERR_INVALID_PARAMETER, "message");
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+ "the word 'love' is not allowed");
return;
}
printf("%s\n", message);
@@ -231,30 +229,40 @@
}
}
-Let's test it. Build qemu, run it as defined in the "Testing" section, and
-then issue the following command:
+The first argument to the error_set() function is the Error pointer to pointer,
+which is passed to all QMP functions. The second argument is a ErrorClass
+value, which should be ERROR_CLASS_GENERIC_ERROR most of the time (more
+details about error classes are given below). The third argument is a human
+description of the error, this is a free-form printf-like string.
-{ "execute": "hello-world", "arguments": { "message": "we love qemu" } }
+Let's test the example above. Build qemu, run it as defined in the "Testing"
+section, and then issue the following command:
+
+{ "execute": "hello-world", "arguments": { "message": "all you need is love" } }
The QMP server's response should be:
{
"error": {
- "class": "InvalidParameter",
- "desc": "Invalid parameter 'message'",
- "data": {
- "name": "message"
- }
+ "class": "GenericError",
+ "desc": "the word 'love' is not allowed"
}
}
-Which is the InvalidParameter error.
+As a general rule, all QMP errors should use ERROR_CLASS_GENERIC_ERROR. There
+are two exceptions to this rule:
-When you have to return an error but you're unsure what error to return or
-which arguments an error takes, you should look at the qerror.h file. Note
-that you might be required to add new errors if needed.
+ 1. A non-generic ErrorClass value exists* for the failure you want to report
+ (eg. DeviceNotFound)
-FIXME: describe better the error API and how to add new errors.
+ 2. Management applications have to take special action on the failure you
+ want to report, hence you have to add a new ErrorClass value so that they
+ can check for it
+
+If the failure you want to report doesn't fall in one of the two cases above,
+just report ERROR_CLASS_GENERIC_ERROR.
+
+ * All existing ErrorClass values are defined in the qapi-schema.json file
=== Command Documentation ===
@@ -275,7 +283,6 @@
# @message: #optional string to be printed
#
# Returns: Nothing on success.
-# If @message contains "love", InvalidParameter
#
# Notes: if @message is not provided, the "Hello, world" string will
# be printed instead
diff --git a/docs/xbzrle.txt b/docs/xbzrle.txt
new file mode 100644
index 0000000..cc3a26a
--- /dev/null
+++ b/docs/xbzrle.txt
@@ -0,0 +1,128 @@
+XBZRLE (Xor Based Zero Run Length Encoding)
+===========================================
+
+Using XBZRLE (Xor Based Zero Run Length Encoding) allows for the reduction
+of VM downtime and the total live-migration time of Virtual machines.
+It is particularly useful for virtual machines running memory write intensive
+workloads that are typical of large enterprise applications such as SAP ERP
+Systems, and generally speaking for any application that uses a sparse memory
+update pattern.
+
+Instead of sending the changed guest memory page this solution will send a
+compressed version of the updates, thus reducing the amount of data sent during
+live migration.
+In order to be able to calculate the update, the previous memory pages need to
+be stored on the source. Those pages are stored in a dedicated cache
+(hash table) and are accessed by their address.
+The larger the cache size the better the chances are that the page has already
+been stored in the cache.
+A small cache size will result in high cache miss rate.
+Cache size can be changed before and during migration.
+
+Format
+=======
+
+The compression format performs a XOR between the previous and current content
+of the page, where zero represents an unchanged value.
+The page data delta is represented by zero and non zero runs.
+A zero run is represented by its length (in bytes).
+A non zero run is represented by its length (in bytes) and the new data.
+The run length is encoded using ULEB128 (http://en.wikipedia.org/wiki/LEB128)
+
+There can be more than one valid encoding, the sender may send a longer encoding
+for the benefit of reducing computation cost.
+
+page = zrun nzrun
+ | zrun nzrun page
+
+zrun = length
+
+nzrun = length byte...
+
+length = uleb128 encoded integer
+
+On the sender side XBZRLE is used as a compact delta encoding of page updates,
+retrieving the old page content from the cache (default size of 512 MB). The
+receiving side uses the existing page's content and XBZRLE to decode the new
+page's content.
+
+This work was originally based on research results published
+VEE 2011: Evaluation of Delta Compression Techniques for Efficient Live
+Migration of Large Virtual Machines by Benoit, Svard, Tordsson and Elmroth.
+Additionally the delta encoder XBRLE was improved further using the XBZRLE
+instead.
+
+XBZRLE has a sustained bandwidth of 2-2.5 GB/s for typical workloads making it
+ideal for in-line, real-time encoding such as is needed for live-migration.
+
+Example
+old buffer:
+1001 zeros
+05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 68 00 00 6b 00 6d
+3074 zeros
+
+new buffer:
+1001 zeros
+01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 68 00 00 67 00 69
+3074 zeros
+
+encoded buffer:
+
+encoded length 24
+e9 07 0f 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 03 01 67 01 01 69
+
+Usage
+======================
+1. Verify the destination QEMU version is able to decode the new format.
+ {qemu} info migrate_capabilities
+ {qemu} xbzrle: off , ...
+
+2. Activate xbzrle on both source and destination:
+ {qemu} migrate_set_capability xbzrle on
+
+3. Set the XBZRLE cache size - the cache size is in MBytes and should be a
+power of 2. The cache default value is 64MBytes. (on source only)
+ {qemu} migrate_set_cache_size 256m
+
+4. Start outgoing migration
+ {qemu} migrate -d tcp:destination.host:4444
+ {qemu} info migrate
+ capabilities: xbzrle: on
+ Migration status: active
+ transferred ram: A kbytes
+ remaining ram: B kbytes
+ total ram: C kbytes
+ total time: D milliseconds
+ duplicate: E pages
+ normal: F pages
+ normal bytes: G kbytes
+ cache size: H bytes
+ xbzrle transferred: I kbytes
+ xbzrle pages: J pages
+ xbzrle cache miss: K
+ xbzrle overflow : L
+
+xbzrle cache-miss: the number of cache misses to date - high cache-miss rate
+indicates that the cache size is set too low.
+xbzrle overflow: the number of overflows in the decoding which where the delta
+could not be compressed. This can happen if the changes in the pages are too
+large or there are many short changes; for example, changing every second byte
+(half a page).
+
+Testing: Testing indicated that live migration with XBZRLE was completed in 110
+seconds, whereas without it would not be able to complete.
+
+A simple synthetic memory r/w load generator:
+.. include <stdlib.h>
+.. include <stdio.h>
+.. int main()
+.. {
+.. char *buf = (char *) calloc(4096, 4096);
+.. while (1) {
+.. int i;
+.. for (i = 0; i < 4096 * 4; i++) {
+.. buf[i * 4096 / 4]++;
+.. }
+.. printf(".");
+.. }
+.. }
diff --git a/error.c b/error.c
index 58f55a0..1f05fc4 100644
--- a/error.c
+++ b/error.c
@@ -14,17 +14,16 @@
#include "error.h"
#include "qjson.h"
#include "qdict.h"
-#include "error_int.h"
+#include "qapi-types.h"
#include "qerror.h"
struct Error
{
- QDict *obj;
- const char *fmt;
char *msg;
+ ErrorClass err_class;
};
-void error_set(Error **errp, const char *fmt, ...)
+void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...)
{
Error *err;
va_list ap;
@@ -37,9 +36,9 @@
err = g_malloc0(sizeof(*err));
va_start(ap, fmt);
- err->obj = qobject_to_qdict(qobject_from_jsonv(fmt, &ap));
+ err->msg = g_strdup_vprintf(fmt, ap);
va_end(ap);
- err->fmt = fmt;
+ err->err_class = err_class;
*errp = err;
}
@@ -50,9 +49,7 @@
err_new = g_malloc0(sizeof(*err));
err_new->msg = g_strdup(err->msg);
- err_new->fmt = err->fmt;
- err_new->obj = err->obj;
- QINCREF(err_new->obj);
+ err_new->err_class = err->err_class;
return err_new;
}
@@ -62,75 +59,24 @@
return (errp && *errp);
}
+ErrorClass error_get_class(const Error *err)
+{
+ return err->err_class;
+}
+
const char *error_get_pretty(Error *err)
{
- if (err->msg == NULL) {
- QString *str;
- str = qerror_format(err->fmt, err->obj);
- err->msg = g_strdup(qstring_get_str(str));
- QDECREF(str);
- }
-
return err->msg;
}
-const char *error_get_field(Error *err, const char *field)
-{
- if (strcmp(field, "class") == 0) {
- return qdict_get_str(err->obj, field);
- } else {
- QDict *dict = qdict_get_qdict(err->obj, "data");
- return qdict_get_str(dict, field);
- }
-}
-
-QDict *error_get_data(Error *err)
-{
- QDict *data = qdict_get_qdict(err->obj, "data");
- QINCREF(data);
- return data;
-}
-
-void error_set_field(Error *err, const char *field, const char *value)
-{
- QDict *dict = qdict_get_qdict(err->obj, "data");
- qdict_put(dict, field, qstring_from_str(value));
-}
-
void error_free(Error *err)
{
if (err) {
- QDECREF(err->obj);
g_free(err->msg);
g_free(err);
}
}
-bool error_is_type(Error *err, const char *fmt)
-{
- const char *error_class;
- char *ptr;
- char *end;
-
- if (!err) {
- return false;
- }
-
- ptr = strstr(fmt, "'class': '");
- assert(ptr != NULL);
- ptr += strlen("'class': '");
-
- end = strchr(ptr, '\'');
- assert(end != NULL);
-
- error_class = error_get_field(err, "class");
- if (strlen(error_class) != end - ptr) {
- return false;
- }
-
- return strncmp(ptr, error_class, end - ptr) == 0;
-}
-
void error_propagate(Error **dst_err, Error *local_err)
{
if (dst_err && !*dst_err) {
@@ -139,22 +85,3 @@
error_free(local_err);
}
}
-
-QObject *error_get_qobject(Error *err)
-{
- QINCREF(err->obj);
- return QOBJECT(err->obj);
-}
-
-void error_set_qobject(Error **errp, QObject *obj)
-{
- Error *err;
- if (errp == NULL) {
- return;
- }
- err = g_malloc0(sizeof(*err));
- err->obj = qobject_to_qdict(obj);
- qobject_incref(obj);
-
- *errp = err;
-}
diff --git a/error.h b/error.h
index 3d9d96d..96fc203 100644
--- a/error.h
+++ b/error.h
@@ -13,20 +13,21 @@
#define ERROR_H
#include "compiler.h"
+#include "qapi-types.h"
#include <stdbool.h>
/**
- * A class representing internal errors within QEMU. An error has a string
- * typename and optionally a set of named string parameters.
+ * A class representing internal errors within QEMU. An error has a ErrorClass
+ * code and a human message.
*/
typedef struct Error Error;
/**
- * Set an indirect pointer to an error given a printf-style format parameter.
- * Currently, qerror.h defines these error formats. This function is not
- * meant to be used outside of QEMU.
+ * Set an indirect pointer to an error given a ErrorClass value and a
+ * printf-style human message. This function is not meant to be used outside
+ * of QEMU.
*/
-void error_set(Error **err, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
+void error_set(Error **err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(3, 4);
/**
* Returns true if an indirect pointer to an error is pointing to a valid
@@ -34,6 +35,11 @@
*/
bool error_is_set(Error **err);
+/*
+ * Get the error class of an error object.
+ */
+ErrorClass error_get_class(const Error *err);
+
/**
* Returns an exact copy of the error passed as an argument.
*/
@@ -45,16 +51,6 @@
const char *error_get_pretty(Error *err);
/**
- * Get an individual named error field.
- */
-const char *error_get_field(Error *err, const char *field);
-
-/**
- * Get an individual named error field.
- */
-void error_set_field(Error *err, const char *field, const char *value);
-
-/**
* Propagate an error to an indirect pointer to an error. This function will
* always transfer ownership of the error reference and handles the case where
* dst_err is NULL correctly. Errors after the first are discarded.
@@ -66,10 +62,4 @@
*/
void error_free(Error *err);
-/**
- * Determine if an error is of a speific type (based on the qerror format).
- * Non-QEMU users should get the `class' field to identify the error type.
- */
-bool error_is_type(Error *err, const char *fmt);
-
#endif
diff --git a/error_int.h b/error_int.h
deleted file mode 100644
index 5e39424..0000000
--- a/error_int.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * QEMU Error Objects
- *
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2. See
- * the COPYING.LIB file in the top-level directory.
- */
-#ifndef QEMU_ERROR_INT_H
-#define QEMU_ERROR_INT_H
-
-#include "qemu-common.h"
-#include "qobject.h"
-#include "qdict.h"
-#include "error.h"
-
-/**
- * Internal QEMU functions for working with Error.
- *
- * These are used to convert QErrors to Errors
- */
-QDict *error_get_data(Error *err);
-QObject *error_get_qobject(Error *err);
-void error_set_qobject(Error **errp, QObject *obj);
-
-#endif
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 9bbc7f7..f6104b0 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -829,6 +829,26 @@
@item migrate_cancel
@findex migrate_cancel
Cancel the current VM migration.
+
+ETEXI
+
+ {
+ .name = "migrate_set_cache_size",
+ .args_type = "value:o",
+ .params = "value",
+ .help = "set cache size (in bytes) for XBZRLE migrations,"
+ "the cache size will be rounded down to the nearest "
+ "power of 2.\n"
+ "The cache size affects the number of cache misses."
+ "In case of a high cache miss ratio you need to increase"
+ " the cache size",
+ .mhandler.cmd = hmp_migrate_set_cache_size,
+ },
+
+STEXI
+@item migrate_set_cache_size @var{value}
+@findex migrate_set_cache_size
+Set cache size to @var{value} (in bytes) for xbzrle migrations.
ETEXI
{
@@ -861,6 +881,20 @@
ETEXI
{
+ .name = "migrate_set_capability",
+ .args_type = "capability:s,state:b",
+ .params = "capability state",
+ .help = "Enable/Disable the usage of a capability for migration",
+ .mhandler.cmd = hmp_migrate_set_capability,
+ },
+
+STEXI
+@item migrate_set_capability @var{capability} @var{state}
+@findex migrate_set_capability
+Enable/Disable the usage of a capability @var{capability} for migration.
+ETEXI
+
+ {
.name = "client_migrate_info",
.args_type = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
.params = "protocol hostname port tls-port cert-subject",
@@ -1417,6 +1451,10 @@
show user network stack connection states
@item info migrate
show migration status
+@item info migrate_capabilities
+show current migration capabilities
+@item info migrate_cache_size
+show current migration XBZRLE cache size
@item info balloon
show balloon information
@item info qtree
diff --git a/hmp.c b/hmp.c
index 25688ab..a9d5675 100644
--- a/hmp.c
+++ b/hmp.c
@@ -131,8 +131,21 @@
void hmp_info_migrate(Monitor *mon)
{
MigrationInfo *info;
+ MigrationCapabilityStatusList *caps, *cap;
info = qmp_query_migrate(NULL);
+ caps = qmp_query_migrate_capabilities(NULL);
+
+ /* do not display parameters during setup */
+ if (info->has_status && caps) {
+ monitor_printf(mon, "capabilities: ");
+ for (cap = caps; cap; cap = cap->next) {
+ monitor_printf(mon, "%s: %s ",
+ MigrationCapability_lookup[cap->value->capability],
+ cap->value->state ? "on" : "off");
+ }
+ monitor_printf(mon, "\n");
+ }
if (info->has_status) {
monitor_printf(mon, "Migration status: %s\n", info->status);
@@ -147,6 +160,12 @@
info->ram->total >> 10);
monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
info->ram->total_time);
+ monitor_printf(mon, "duplicate: %" PRIu64 " pages\n",
+ info->ram->duplicate);
+ monitor_printf(mon, "normal: %" PRIu64 " pages\n",
+ info->ram->normal);
+ monitor_printf(mon, "normal bytes: %" PRIu64 " kbytes\n",
+ info->ram->normal_bytes >> 10);
}
if (info->has_disk) {
@@ -158,7 +177,46 @@
info->disk->total >> 10);
}
+ if (info->has_xbzrle_cache) {
+ monitor_printf(mon, "cache size: %" PRIu64 " bytes\n",
+ info->xbzrle_cache->cache_size);
+ monitor_printf(mon, "xbzrle transferred: %" PRIu64 " kbytes\n",
+ info->xbzrle_cache->bytes >> 10);
+ monitor_printf(mon, "xbzrle pages: %" PRIu64 " pages\n",
+ info->xbzrle_cache->pages);
+ monitor_printf(mon, "xbzrle cache miss: %" PRIu64 "\n",
+ info->xbzrle_cache->cache_miss);
+ monitor_printf(mon, "xbzrle overflow : %" PRIu64 "\n",
+ info->xbzrle_cache->overflow);
+ }
+
qapi_free_MigrationInfo(info);
+ qapi_free_MigrationCapabilityStatusList(caps);
+}
+
+void hmp_info_migrate_capabilities(Monitor *mon)
+{
+ MigrationCapabilityStatusList *caps, *cap;
+
+ caps = qmp_query_migrate_capabilities(NULL);
+
+ if (caps) {
+ monitor_printf(mon, "capabilities: ");
+ for (cap = caps; cap; cap = cap->next) {
+ monitor_printf(mon, "%s: %s ",
+ MigrationCapability_lookup[cap->value->capability],
+ cap->value->state ? "on" : "off");
+ }
+ monitor_printf(mon, "\n");
+ }
+
+ qapi_free_MigrationCapabilityStatusList(caps);
+}
+
+void hmp_info_migrate_cache_size(Monitor *mon)
+{
+ monitor_printf(mon, "xbzrel cache size: %" PRId64 " kbytes\n",
+ qmp_query_migrate_cache_size(NULL) >> 10);
}
void hmp_info_cpus(Monitor *mon)
@@ -612,34 +670,35 @@
static void hmp_cont_cb(void *opaque, int err)
{
- Monitor *mon = opaque;
-
if (!err) {
- hmp_cont(mon, NULL);
+ qmp_cont(NULL);
}
}
+static bool key_is_missing(const BlockInfo *bdev)
+{
+ return (bdev->inserted && bdev->inserted->encryption_key_missing);
+}
+
void hmp_cont(Monitor *mon, const QDict *qdict)
{
+ BlockInfoList *bdev_list, *bdev;
Error *errp = NULL;
- qmp_cont(&errp);
- if (error_is_set(&errp)) {
- if (error_is_type(errp, QERR_DEVICE_ENCRYPTED)) {
- const char *device;
-
- /* The device is encrypted. Ask the user for the password
- and retry */
-
- device = error_get_field(errp, "device");
- assert(device != NULL);
-
- monitor_read_block_device_key(mon, device, hmp_cont_cb, mon);
- error_free(errp);
- return;
+ bdev_list = qmp_query_block(NULL);
+ for (bdev = bdev_list; bdev; bdev = bdev->next) {
+ if (key_is_missing(bdev->value)) {
+ monitor_read_block_device_key(mon, bdev->value->device,
+ hmp_cont_cb, NULL);
+ goto out;
}
- hmp_handle_error(mon, &errp);
}
+
+ qmp_cont(&errp);
+ hmp_handle_error(mon, &errp);
+
+out:
+ qapi_free_BlockInfoList(bdev_list);
}
void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
@@ -731,12 +790,57 @@
qmp_migrate_set_downtime(value, NULL);
}
+void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict)
+{
+ int64_t value = qdict_get_int(qdict, "value");
+ Error *err = NULL;
+
+ qmp_migrate_set_cache_size(value, &err);
+ if (err) {
+ monitor_printf(mon, "%s\n", error_get_pretty(err));
+ error_free(err);
+ return;
+ }
+}
+
void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict)
{
int64_t value = qdict_get_int(qdict, "value");
qmp_migrate_set_speed(value, NULL);
}
+void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
+{
+ const char *cap = qdict_get_str(qdict, "capability");
+ bool state = qdict_get_bool(qdict, "state");
+ Error *err = NULL;
+ MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
+ int i;
+
+ for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+ if (strcmp(cap, MigrationCapability_lookup[i]) == 0) {
+ caps->value = g_malloc0(sizeof(*caps->value));
+ caps->value->capability = i;
+ caps->value->state = state;
+ caps->next = NULL;
+ qmp_migrate_set_capabilities(caps, &err);
+ break;
+ }
+ }
+
+ if (i == MIGRATION_CAPABILITY_MAX) {
+ error_set(&err, QERR_INVALID_PARAMETER, cap);
+ }
+
+ qapi_free_MigrationCapabilityStatusList(caps);
+
+ if (err) {
+ monitor_printf(mon, "migrate_set_parameter: %s\n",
+ error_get_pretty(err));
+ error_free(err);
+ }
+}
+
void hmp_set_password(Monitor *mon, const QDict *qdict)
{
const char *protocol = qdict_get_str(qdict, "protocol");
@@ -775,22 +879,6 @@
monitor_read_command(mon, 1);
}
-static void cb_hmp_change_bdrv_pwd(Monitor *mon, const char *password,
- void *opaque)
-{
- Error *encryption_err = opaque;
- Error *err = NULL;
- const char *device;
-
- device = error_get_field(encryption_err, "device");
-
- qmp_block_passwd(device, password, &err);
- hmp_handle_error(mon, &err);
- error_free(encryption_err);
-
- monitor_read_command(mon, 1);
-}
-
void hmp_change(Monitor *mon, const QDict *qdict)
{
const char *device = qdict_get_str(qdict, "device");
@@ -808,18 +896,10 @@
}
qmp_change(device, target, !!arg, arg, &err);
- if (error_is_type(err, QERR_DEVICE_ENCRYPTED)) {
- monitor_printf(mon, "%s (%s) is encrypted.\n",
- error_get_field(err, "device"),
- error_get_field(err, "filename"));
- if (!monitor_get_rs(mon)) {
- monitor_printf(mon,
- "terminal does not support password prompting\n");
- error_free(err);
- return;
- }
- readline_start(monitor_get_rs(mon), "Password: ", 1,
- cb_hmp_change_bdrv_pwd, err);
+ if (error_is_set(&err) &&
+ error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
+ error_free(err);
+ monitor_read_block_device_key(mon, device, NULL, NULL);
return;
}
hmp_handle_error(mon, &err);
diff --git a/hmp.h b/hmp.h
index 8d2b0d7..7dd93bf 100644
--- a/hmp.h
+++ b/hmp.h
@@ -16,6 +16,7 @@
#include "qemu-common.h"
#include "qapi-types.h"
+#include "qdict.h"
void hmp_info_name(Monitor *mon);
void hmp_info_version(Monitor *mon);
@@ -25,6 +26,8 @@
void hmp_info_chardev(Monitor *mon);
void hmp_info_mice(Monitor *mon);
void hmp_info_migrate(Monitor *mon);
+void hmp_info_migrate_capabilities(Monitor *mon);
+void hmp_info_migrate_cache_size(Monitor *mon);
void hmp_info_cpus(Monitor *mon);
void hmp_info_block(Monitor *mon);
void hmp_info_blockstats(Monitor *mon);
@@ -51,6 +54,8 @@
void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict);
void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict);
+void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict);
+void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict);
void hmp_set_password(Monitor *mon, const QDict *qdict);
void hmp_expire_password(Monitor *mon, const QDict *qdict);
void hmp_eject(Monitor *mon, const QDict *qdict);
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 6eee9a0..7f57ed5 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -74,6 +74,26 @@
hw-obj-$(CONFIG_PUV3) += puv3_pm.o
hw-obj-$(CONFIG_PUV3) += puv3_dma.o
+# ARM devices
+hw-obj-$(CONFIG_ARM_TIMER) += arm_timer.o
+hw-obj-$(CONFIG_PL011) += pl011.o
+hw-obj-$(CONFIG_PL022) += pl022.o
+hw-obj-$(CONFIG_PL031) += pl031.o
+hw-obj-$(CONFIG_PL041) += pl041.o lm4549.o
+hw-obj-$(CONFIG_PL050) += pl050.o
+hw-obj-$(CONFIG_PL061) += pl061.o
+hw-obj-$(CONFIG_PL080) += pl080.o
+hw-obj-$(CONFIG_PL110) += pl110.o
+hw-obj-$(CONFIG_PL181) += pl181.o
+hw-obj-$(CONFIG_PL190) += pl190.o
+hw-obj-$(CONFIG_PL310) += arm_l2x0.o
+hw-obj-$(CONFIG_VERSATILE_PCI) += versatile_pci.o
+hw-obj-$(CONFIG_VERSATILE_I2C) += versatile_i2c.o
+hw-obj-$(CONFIG_CADENCE) += cadence_uart.o
+hw-obj-$(CONFIG_CADENCE) += cadence_ttc.o
+hw-obj-$(CONFIG_CADENCE) += cadence_gem.o
+hw-obj-$(CONFIG_XGMAC) += xgmac.o
+
# PCI watchdog devices
hw-obj-$(CONFIG_PCI) += wdt_i6300esb.o
diff --git a/hw/acpi.c b/hw/acpi.c
index effc7ec..f7950be 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -22,6 +22,7 @@
#include "hw.h"
#include "pc.h"
#include "acpi.h"
+#include "monitor.h"
struct acpi_table_header {
uint16_t _length; /* our length, not actual part of the hdr */
@@ -386,6 +387,7 @@
break;
default:
if (sus_typ == s4) { /* S4 request */
+ monitor_protocol_event(QEVENT_SUSPEND_DISK, NULL);
qemu_system_shutdown_request();
}
break;
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index c413780..2b39fb3 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -1,10 +1,5 @@
-obj-y = integratorcp.o versatilepb.o arm_pic.o arm_timer.o
-obj-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
-obj-y += versatile_pci.o
-obj-y += versatile_i2c.o
-obj-y += cadence_uart.o
-obj-y += cadence_ttc.o
-obj-y += cadence_gem.o
+obj-y = integratorcp.o versatilepb.o arm_pic.o
+obj-y += arm_boot.o
obj-y += xilinx_zynq.o zynq_slcr.o
obj-y += arm_gic.o arm_gic_common.o
obj-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
@@ -12,12 +7,9 @@
obj-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o
obj-y += exynos4210_pmu.o exynos4210_mct.o exynos4210_fimd.o
obj-y += exynos4210_rtc.o exynos4210_i2c.o
-obj-y += arm_l2x0.o
obj-y += arm_mptimer.o a15mpcore.o
-obj-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
+obj-y += armv7m.o armv7m_nvic.o stellaris.o stellaris_enet.o
obj-y += highbank.o
-obj-y += pl061.o
-obj-y += xgmac.o
obj-y += pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
obj-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
obj-y += gumstix.o
@@ -37,7 +29,6 @@
obj-y += collie.o
obj-y += imx_serial.o imx_ccm.o imx_timer.o imx_avic.o
obj-y += kzm.o
-obj-y += pl041.o lm4549.o
obj-$(CONFIG_FDT) += ../device_tree.o
obj-y := $(addprefix ../,$(obj-y))
diff --git a/hw/armv7m.c b/hw/armv7m.c
index 8cec78d..9f66667 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -227,6 +227,11 @@
big_endian = 0;
#endif
+ if (!kernel_filename) {
+ fprintf(stderr, "Guest image must be specified (using -kernel)\n");
+ exit(1);
+ }
+
image_size = load_elf(kernel_filename, NULL, NULL, &entry, &lowaddr,
NULL, big_endian, ELF_MACHINE, 1);
if (image_size < 0) {
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 4867c1d..6a0832e 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -467,7 +467,7 @@
s->gic.num_cpu = 1;
/* Tell the common code we're an NVIC */
s->gic.revision = 0xffffffff;
- s->gic.num_irq = s->num_irq;
+ s->num_irq = s->gic.num_irq;
nc->parent_init(dev);
gic_init_irqs_and_distributor(&s->gic, s->num_irq);
/* The NVIC and system controller register area looks like this:
@@ -498,14 +498,21 @@
return 0;
}
-static Property armv7m_nvic_properties[] = {
+static void armv7m_nvic_instance_init(Object *obj)
+{
+ /* We have a different default value for the num-irq property
+ * than our superclass. This function runs after qdev init
+ * has set the defaults from the Property array and before
+ * any user-specified property setting, so just modify the
+ * value in the gic_state struct.
+ */
+ gic_state *s = ARM_GIC_COMMON(obj);
/* The ARM v7m may have anything from 0 to 496 external interrupt
* IRQ lines. We default to 64. Other boards may differ and should
- * set this property appropriately.
+ * set the num-irq property appropriately.
*/
- DEFINE_PROP_UINT32("num-irq", nvic_state, num_irq, 64),
- DEFINE_PROP_END_OF_LIST(),
-};
+ s->num_irq = 64;
+}
static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
{
@@ -518,12 +525,12 @@
sdc->init = armv7m_nvic_init;
dc->vmsd = &vmstate_nvic;
dc->reset = armv7m_nvic_reset;
- dc->props = armv7m_nvic_properties;
}
static TypeInfo armv7m_nvic_info = {
.name = TYPE_NVIC,
.parent = TYPE_ARM_GIC_COMMON,
+ .instance_init = armv7m_nvic_instance_init,
.instance_size = sizeof(nvic_state),
.class_init = armv7m_nvic_class_init,
.class_size = sizeof(NVICClass),
diff --git a/hw/kvm/i8259.c b/hw/kvm/i8259.c
index 94d1b9a..1e24cd4 100644
--- a/hw/kvm/i8259.c
+++ b/hw/kvm/i8259.c
@@ -94,7 +94,7 @@
{
int delivered;
- delivered = kvm_irqchip_set_irq(kvm_state, irq, level);
+ delivered = kvm_set_irq(kvm_state, irq, level);
apic_report_irq_delivered(delivered);
}
diff --git a/hw/kvm/ioapic.c b/hw/kvm/ioapic.c
index 3ae3175..6c3b8fe 100644
--- a/hw/kvm/ioapic.c
+++ b/hw/kvm/ioapic.c
@@ -82,7 +82,7 @@
KVMIOAPICState *s = opaque;
int delivered;
- delivered = kvm_irqchip_set_irq(kvm_state, s->kvm_gsi_base + irq, level);
+ delivered = kvm_set_irq(kvm_state, s->kvm_gsi_base + irq, level);
apic_report_irq_delivered(delivered);
}
diff --git a/hw/pc.c b/hw/pc.c
index 81c391c..e8bcfc0 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -42,6 +42,7 @@
#include "sysbus.h"
#include "sysemu.h"
#include "kvm.h"
+#include "kvm_i386.h"
#include "xen.h"
#include "blockdev.h"
#include "hw/block-common.h"
diff --git a/hw/sd.c b/hw/sd.c
index 07eb263..ec26407 100644
--- a/hw/sd.c
+++ b/hw/sd.c
@@ -32,6 +32,7 @@
#include "hw.h"
#include "block.h"
#include "sd.h"
+#include "bitmap.h"
//#define DEBUG_SD 1
@@ -80,8 +81,8 @@
uint32_t card_status;
uint8_t sd_status[64];
uint32_t vhs;
- int wp_switch;
- int *wp_groups;
+ bool wp_switch;
+ unsigned long *wp_groups;
uint64_t size;
int blk_len;
uint32_t erase_start;
@@ -90,12 +91,12 @@
int pwd_len;
int function_group[6];
- int spi;
+ bool spi;
int current_cmd;
/* True if we will handle the next command as an ACMD. Note that this does
* *not* track the APP_CMD status bit!
*/
- int expecting_acmd;
+ bool expecting_acmd;
int blk_written;
uint64_t data_start;
uint32_t data_offset;
@@ -105,7 +106,7 @@
BlockDriverState *bdrv;
uint8_t *buf;
- int enable;
+ bool enable;
};
static void sd_set_mode(SDState *sd)
@@ -387,6 +388,11 @@
response[3] = (sd->vhs >> 0) & 0xff;
}
+static inline uint64_t sd_addr_to_wpnum(uint64_t addr)
+{
+ return addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
+}
+
static void sd_reset(SDState *sd, BlockDriverState *bdrv)
{
uint64_t size;
@@ -399,7 +405,7 @@
}
size = sect << 9;
- sect = (size >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)) + 1;
+ sect = sd_addr_to_wpnum(size) + 1;
sd->state = sd_idle_state;
sd->rca = 0x0000;
@@ -414,15 +420,15 @@
if (sd->wp_groups)
g_free(sd->wp_groups);
- sd->wp_switch = bdrv ? bdrv_is_read_only(bdrv) : 0;
- sd->wp_groups = (int *) g_malloc0(sizeof(int) * sect);
+ sd->wp_switch = bdrv ? bdrv_is_read_only(bdrv) : false;
+ sd->wp_groups = bitmap_new(sect);
memset(sd->function_group, 0, sizeof(int) * 6);
sd->erase_start = 0;
sd->erase_end = 0;
sd->size = size;
sd->blk_len = 0x200;
sd->pwd_len = 0;
- sd->expecting_acmd = 0;
+ sd->expecting_acmd = false;
}
static void sd_cardchange(void *opaque, bool load)
@@ -444,14 +450,14 @@
whether card should be in SSI or MMC/SD mode. It is also up to the
board to ensure that ssi transfers only occur when the chip select
is asserted. */
-SDState *sd_init(BlockDriverState *bs, int is_spi)
+SDState *sd_init(BlockDriverState *bs, bool is_spi)
{
SDState *sd;
sd = (SDState *) g_malloc0(sizeof(SDState));
sd->buf = qemu_blockalign(bs, 512);
sd->spi = is_spi;
- sd->enable = 1;
+ sd->enable = true;
sd_reset(sd, bs);
if (sd->bdrv) {
bdrv_attach_dev_nofail(sd->bdrv, sd);
@@ -476,17 +482,17 @@
return;
}
- start = sd->erase_start >>
- (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
- end = sd->erase_end >>
- (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
+ start = sd_addr_to_wpnum(sd->erase_start);
+ end = sd_addr_to_wpnum(sd->erase_end);
sd->erase_start = 0;
sd->erase_end = 0;
sd->csd[14] |= 0x40;
- for (i = start; i <= end; i ++)
- if (sd->wp_groups[i])
+ for (i = start; i <= end; i++) {
+ if (test_bit(i, sd->wp_groups)) {
sd->card_status |= WP_ERASE_SKIP;
+ }
+ }
}
static uint32_t sd_wpbits(SDState *sd, uint64_t addr)
@@ -494,11 +500,13 @@
uint32_t i, wpnum;
uint32_t ret = 0;
- wpnum = addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
+ wpnum = sd_addr_to_wpnum(addr);
- for (i = 0; i < 32; i ++, wpnum ++, addr += WPGROUP_SIZE)
- if (addr < sd->size && sd->wp_groups[wpnum])
+ for (i = 0; i < 32; i++, wpnum++, addr += WPGROUP_SIZE) {
+ if (addr < sd->size && test_bit(wpnum, sd->wp_groups)) {
ret |= (1 << i);
+ }
+ }
return ret;
}
@@ -534,10 +542,9 @@
sd->data[66] = crc & 0xff;
}
-static inline int sd_wp_addr(SDState *sd, uint32_t addr)
+static inline bool sd_wp_addr(SDState *sd, uint64_t addr)
{
- return sd->wp_groups[addr >>
- (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)];
+ return test_bit(sd_addr_to_wpnum(addr), sd->wp_groups);
}
static void sd_lock_command(SDState *sd)
@@ -560,8 +567,7 @@
sd->card_status |= LOCK_UNLOCK_FAILED;
return;
}
- memset(sd->wp_groups, 0, sizeof(int) * (sd->size >>
- (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)));
+ bitmap_zero(sd->wp_groups, sd_addr_to_wpnum(sd->size) + 1);
sd->csd[14] &= ~0x10;
sd->card_status &= ~CARD_IS_LOCKED;
sd->pwd_len = 0;
@@ -1007,8 +1013,7 @@
}
sd->state = sd_programming_state;
- sd->wp_groups[addr >> (HWBLOCK_SHIFT +
- SECTOR_SHIFT + WPGROUP_SHIFT)] = 1;
+ set_bit(sd_addr_to_wpnum(addr), sd->wp_groups);
/* Bzzzzzzztt .... Operation complete. */
sd->state = sd_transfer_state;
return sd_r1b;
@@ -1027,8 +1032,7 @@
}
sd->state = sd_programming_state;
- sd->wp_groups[addr >> (HWBLOCK_SHIFT +
- SECTOR_SHIFT + WPGROUP_SHIFT)] = 0;
+ clear_bit(sd_addr_to_wpnum(addr), sd->wp_groups);
/* Bzzzzzzztt .... Operation complete. */
sd->state = sd_transfer_state;
return sd_r1b;
@@ -1125,7 +1129,7 @@
if (sd->rca != rca)
return sd_r0;
- sd->expecting_acmd = 1;
+ sd->expecting_acmd = true;
sd->card_status |= APP_CMD;
return sd_r1;
@@ -1307,7 +1311,7 @@
if (sd->card_status & CARD_IS_LOCKED) {
if (!cmd_valid_while_locked(sd, req)) {
sd->card_status |= ILLEGAL_COMMAND;
- sd->expecting_acmd = 0;
+ sd->expecting_acmd = false;
fprintf(stderr, "SD: Card is locked\n");
rtype = sd_illegal;
goto send_response;
@@ -1318,7 +1322,7 @@
sd_set_mode(sd);
if (sd->expecting_acmd) {
- sd->expecting_acmd = 0;
+ sd->expecting_acmd = false;
rtype = sd_app_command(sd, *req);
} else {
rtype = sd_normal_command(sd, *req);
@@ -1699,12 +1703,12 @@
return ret;
}
-int sd_data_ready(SDState *sd)
+bool sd_data_ready(SDState *sd)
{
return sd->state == sd_sendingdata_state;
}
-void sd_enable(SDState *sd, int enable)
+void sd_enable(SDState *sd, bool enable)
{
sd->enable = enable;
}
diff --git a/hw/sd.h b/hw/sd.h
index ac4b7c4..4eb9679 100644
--- a/hw/sd.h
+++ b/hw/sd.h
@@ -67,13 +67,13 @@
typedef struct SDState SDState;
-SDState *sd_init(BlockDriverState *bs, int is_spi);
+SDState *sd_init(BlockDriverState *bs, bool is_spi);
int sd_do_command(SDState *sd, SDRequest *req,
uint8_t *response);
void sd_write_data(SDState *sd, uint8_t value);
uint8_t sd_read_data(SDState *sd);
void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert);
-int sd_data_ready(SDState *sd);
-void sd_enable(SDState *sd, int enable);
+bool sd_data_ready(SDState *sd);
+void sd_enable(SDState *sd, bool enable);
#endif /* __hw_sd_h */
diff --git a/hw/ssd0323.c b/hw/ssd0323.c
index b0b2e94..b101c51 100644
--- a/hw/ssd0323.c
+++ b/hw/ssd0323.c
@@ -19,7 +19,9 @@
#define DPRINTF(fmt, ...) \
do { printf("ssd0323: " fmt , ## __VA_ARGS__); } while (0)
#define BADF(fmt, ...) \
-do { fprintf(stderr, "ssd0323: error: " fmt , ## __VA_ARGS__); exit(1);} while (0)
+do { \
+ fprintf(stderr, "ssd0323: error: " fmt , ## __VA_ARGS__); abort(); \
+} while (0)
#else
#define DPRINTF(fmt, ...) do {} while(0)
#define BADF(fmt, ...) \
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 125eded..5e6e09e 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -627,7 +627,7 @@
int r, n;
/* Must unset vector notifier while guest notifier is still assigned */
- if (kvm_irqchip_in_kernel() && !assign) {
+ if (kvm_msi_via_irqfd_enabled() && !assign) {
msix_unset_vector_notifiers(&proxy->pci_dev);
g_free(proxy->vector_irqfd);
proxy->vector_irqfd = NULL;
@@ -645,7 +645,7 @@
}
/* Must set vector notifier after guest notifier has been assigned */
- if (kvm_irqchip_in_kernel() && assign) {
+ if (kvm_msi_via_irqfd_enabled() && assign) {
proxy->vector_irqfd =
g_malloc0(sizeof(*proxy->vector_irqfd) *
msix_nr_vectors_allocated(&proxy->pci_dev));
diff --git a/include/qemu/page_cache.h b/include/qemu/page_cache.h
new file mode 100644
index 0000000..3839ac7
--- /dev/null
+++ b/include/qemu/page_cache.h
@@ -0,0 +1,79 @@
+/*
+ * Page cache for QEMU
+ * The cache is base on a hash of the page address
+ *
+ * Copyright 2012 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ * Orit Wasserman <owasserm@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef PAGE_CACHE_H
+#define PAGE_CACHE_H
+
+/* Page cache for storing guest pages */
+typedef struct PageCache PageCache;
+
+/**
+ * cache_init: Initialize the page cache
+ *
+ *
+ * Returns new allocated cache or NULL on error
+ *
+ * @cache pointer to the PageCache struct
+ * @num_pages: cache maximal number of cached pages
+ * @page_size: cache page size
+ */
+PageCache *cache_init(int64_t num_pages, unsigned int page_size);
+
+/**
+ * cache_fini: free all cache resources
+ * @cache pointer to the PageCache struct
+ */
+void cache_fini(PageCache *cache);
+
+/**
+ * cache_is_cached: Checks to see if the page is cached
+ *
+ * Returns %true if page is cached
+ *
+ * @cache pointer to the PageCache struct
+ * @addr: page addr
+ */
+bool cache_is_cached(const PageCache *cache, uint64_t addr);
+
+/**
+ * get_cached_data: Get the data cached for an addr
+ *
+ * Returns pointer to the data cached or NULL if not cached
+ *
+ * @cache pointer to the PageCache struct
+ * @addr: page addr
+ */
+uint8_t *get_cached_data(const PageCache *cache, uint64_t addr);
+
+/**
+ * cache_insert: insert the page into the cache. the previous value will be overwritten
+ *
+ * @cache pointer to the PageCache struct
+ * @addr: page address
+ * @pdata: pointer to the page
+ */
+void cache_insert(PageCache *cache, uint64_t addr, uint8_t *pdata);
+
+/**
+ * cache_resize: resize the page cache. In case of size reduction the extra
+ * pages will be freed
+ *
+ * Returns -1 on error new cache size on success
+ *
+ * @cache pointer to the PageCache struct
+ * @num_pages: new page cache size (in pages)
+ */
+int64_t cache_resize(PageCache *cache, int64_t num_pages);
+
+#endif
diff --git a/kvm-all.c b/kvm-all.c
index 2148b20..34b02c1 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -100,6 +100,10 @@
KVMState *kvm_state;
bool kvm_kernel_irqchip;
+bool kvm_async_interrupts_allowed;
+bool kvm_irqfds_allowed;
+bool kvm_msi_via_irqfd_allowed;
+bool kvm_gsi_routing_allowed;
static const KVMCapabilityInfo kvm_required_capabilites[] = {
KVM_CAP_INFO(USER_MEMORY),
@@ -852,18 +856,18 @@
}
}
-int kvm_irqchip_set_irq(KVMState *s, int irq, int level)
+int kvm_set_irq(KVMState *s, int irq, int level)
{
struct kvm_irq_level event;
int ret;
- assert(kvm_irqchip_in_kernel());
+ assert(kvm_async_interrupts_enabled());
event.level = level;
event.irq = irq;
ret = kvm_vm_ioctl(s, s->irqchip_inject_ioctl, &event);
if (ret < 0) {
- perror("kvm_set_irqchip_line");
+ perror("kvm_set_irq");
abort();
}
@@ -1088,7 +1092,7 @@
assert(route->kroute.type == KVM_IRQ_ROUTING_MSI);
- return kvm_irqchip_set_irq(s, route->kroute.gsi, 1);
+ return kvm_set_irq(s, route->kroute.gsi, 1);
}
int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
@@ -1096,7 +1100,7 @@
struct kvm_irq_routing_entry kroute;
int virq;
- if (!kvm_irqchip_in_kernel()) {
+ if (!kvm_gsi_routing_enabled()) {
return -ENOSYS;
}
@@ -1125,7 +1129,7 @@
.flags = assign ? 0 : KVM_IRQFD_FLAG_DEASSIGN,
};
- if (!kvm_irqchip_in_kernel()) {
+ if (!kvm_irqfds_enabled()) {
return -ENOSYS;
}
@@ -1201,12 +1205,36 @@
s->irqchip_inject_ioctl = KVM_IRQ_LINE_STATUS;
}
kvm_kernel_irqchip = true;
+ /* If we have an in-kernel IRQ chip then we must have asynchronous
+ * interrupt delivery (though the reverse is not necessarily true)
+ */
+ kvm_async_interrupts_allowed = true;
kvm_init_irq_routing(s);
return 0;
}
+static int kvm_max_vcpus(KVMState *s)
+{
+ int ret;
+
+ /* Find number of supported CPUs using the recommended
+ * procedure from the kernel API documentation to cope with
+ * older kernels that may be missing capabilities.
+ */
+ ret = kvm_check_extension(s, KVM_CAP_MAX_VCPUS);
+ if (ret) {
+ return ret;
+ }
+ ret = kvm_check_extension(s, KVM_CAP_NR_VCPUS);
+ if (ret) {
+ return ret;
+ }
+
+ return 4;
+}
+
int kvm_init(void)
{
static const char upgrade_note[] =
@@ -1216,6 +1244,7 @@
const KVMCapabilityInfo *missing_cap;
int ret;
int i;
+ int max_vcpus;
s = g_malloc0(sizeof(KVMState));
@@ -1256,6 +1285,14 @@
goto err;
}
+ max_vcpus = kvm_max_vcpus(s);
+ if (smp_cpus > max_vcpus) {
+ ret = -EINVAL;
+ fprintf(stderr, "Number of SMP cpus requested (%d) exceeds max cpus "
+ "supported by KVM (%d)\n", smp_cpus, max_vcpus);
+ goto err;
+ }
+
s->vmfd = kvm_ioctl(s, KVM_CREATE_VM, 0);
if (s->vmfd < 0) {
#ifdef TARGET_S390X
@@ -1667,11 +1704,6 @@
#endif
}
-int kvm_allows_irq0_override(void)
-{
- return !kvm_irqchip_in_kernel() || kvm_has_gsi_routing();
-}
-
void *kvm_vmalloc(ram_addr_t size)
{
#ifdef TARGET_S390X
diff --git a/kvm-stub.c b/kvm-stub.c
index d23b11c..94c9ea1 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -19,6 +19,10 @@
KVMState *kvm_state;
bool kvm_kernel_irqchip;
+bool kvm_async_interrupts_allowed;
+bool kvm_irqfds_allowed;
+bool kvm_msi_via_irqfd_allowed;
+bool kvm_gsi_routing_allowed;
int kvm_init_vcpu(CPUArchState *env)
{
@@ -71,11 +75,6 @@
return 0;
}
-int kvm_allows_irq0_override(void)
-{
- return 1;
-}
-
int kvm_has_pit_state2(void)
{
return 0;
diff --git a/kvm.h b/kvm.h
index 2617dd5..5b8f588 100644
--- a/kvm.h
+++ b/kvm.h
@@ -24,13 +24,69 @@
extern int kvm_allowed;
extern bool kvm_kernel_irqchip;
+extern bool kvm_async_interrupts_allowed;
+extern bool kvm_irqfds_allowed;
+extern bool kvm_msi_via_irqfd_allowed;
+extern bool kvm_gsi_routing_allowed;
#if defined CONFIG_KVM || !defined NEED_CPU_H
#define kvm_enabled() (kvm_allowed)
+/**
+ * kvm_irqchip_in_kernel:
+ *
+ * Returns: true if the user asked us to create an in-kernel
+ * irqchip via the "kernel_irqchip=on" machine option.
+ * What this actually means is architecture and machine model
+ * specific: on PC, for instance, it means that the LAPIC,
+ * IOAPIC and PIT are all in kernel. This function should never
+ * be used from generic target-independent code: use one of the
+ * following functions or some other specific check instead.
+ */
#define kvm_irqchip_in_kernel() (kvm_kernel_irqchip)
+
+/**
+ * kvm_async_interrupts_enabled:
+ *
+ * Returns: true if we can deliver interrupts to KVM
+ * asynchronously (ie by ioctl from any thread at any time)
+ * rather than having to do interrupt delivery synchronously
+ * (where the vcpu must be stopped at a suitable point first).
+ */
+#define kvm_async_interrupts_enabled() (kvm_async_interrupts_allowed)
+
+/**
+ * kvm_irqfds_enabled:
+ *
+ * Returns: true if we can use irqfds to inject interrupts into
+ * a KVM CPU (ie the kernel supports irqfds and we are running
+ * with a configuration where it is meaningful to use them).
+ */
+#define kvm_irqfds_enabled() (kvm_irqfds_allowed)
+
+/**
+ * kvm_msi_via_irqfd_enabled:
+ *
+ * Returns: true if we can route a PCI MSI (Message Signaled Interrupt)
+ * to a KVM CPU via an irqfd. This requires that the kernel supports
+ * this and that we're running in a configuration that permits it.
+ */
+#define kvm_msi_via_irqfd_enabled() (kvm_msi_via_irqfd_allowed)
+
+/**
+ * kvm_gsi_routing_enabled:
+ *
+ * Returns: true if GSI routing is enabled (ie the kernel supports
+ * it and we're running in a configuration that permits it).
+ */
+#define kvm_gsi_routing_enabled() (kvm_gsi_routing_allowed)
+
#else
#define kvm_enabled() (0)
#define kvm_irqchip_in_kernel() (false)
+#define kvm_async_interrupts_enabled() (false)
+#define kvm_irqfds_enabled() (false)
+#define kvm_msi_via_irqfd_enabled() (false)
+#define kvm_gsi_routing_allowed() (false)
#endif
struct kvm_run;
@@ -62,8 +118,6 @@
int kvm_has_many_ioeventfds(void);
int kvm_has_gsi_routing(void);
-int kvm_allows_irq0_override(void);
-
#ifdef NEED_CPU_H
int kvm_init_vcpu(CPUArchState *env);
@@ -133,7 +187,7 @@
void kvm_arch_init_irq_routing(KVMState *s);
-int kvm_irqchip_set_irq(KVMState *s, int irq, int level);
+int kvm_set_irq(KVMState *s, int irq, int level);
int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin);
diff --git a/migration-tcp.c b/migration-tcp.c
index 440804d..ac891c3 100644
--- a/migration-tcp.c
+++ b/migration-tcp.c
@@ -82,27 +82,23 @@
int tcp_start_outgoing_migration(MigrationState *s, const char *host_port,
Error **errp)
{
+ bool in_progress;
+
s->get_error = socket_errno;
s->write = socket_write;
s->close = tcp_close;
- s->fd = inet_connect(host_port, false, errp);
-
- if (!error_is_set(errp)) {
- migrate_fd_connect(s);
- } else if (error_is_type(*errp, QERR_SOCKET_CONNECT_IN_PROGRESS)) {
- DPRINTF("connect in progress\n");
- qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s);
- } else if (error_is_type(*errp, QERR_SOCKET_CREATE_FAILED)) {
- DPRINTF("connect failed\n");
- return -1;
- } else if (error_is_type(*errp, QERR_SOCKET_CONNECT_FAILED)) {
- DPRINTF("connect failed\n");
+ s->fd = inet_connect(host_port, false, &in_progress, errp);
+ if (error_is_set(errp)) {
migrate_fd_error(s);
return -1;
+ }
+
+ if (in_progress) {
+ DPRINTF("connect in progress\n");
+ qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s);
} else {
- DPRINTF("unknown error\n");
- return -1;
+ migrate_fd_connect(s);
}
return 0;
diff --git a/migration.c b/migration.c
index 8db1b43..653a3c1 100644
--- a/migration.c
+++ b/migration.c
@@ -43,6 +43,9 @@
#define MAX_THROTTLE (32 << 20) /* Migration speed throttling */
+/* Migration XBZRLE default cache size */
+#define DEFAULT_MIGRATE_CACHE_SIZE (64 * 1024 * 1024)
+
static NotifierList migration_state_notifiers =
NOTIFIER_LIST_INITIALIZER(migration_state_notifiers);
@@ -55,6 +58,7 @@
static MigrationState current_migration = {
.state = MIG_STATE_SETUP,
.bandwidth_limit = MAX_THROTTLE,
+ .xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE,
};
return ¤t_migration;
@@ -113,6 +117,43 @@
return max_downtime;
}
+MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
+{
+ MigrationCapabilityStatusList *head = NULL;
+ MigrationCapabilityStatusList *caps;
+ MigrationState *s = migrate_get_current();
+ int i;
+
+ for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+ if (head == NULL) {
+ head = g_malloc0(sizeof(*caps));
+ caps = head;
+ } else {
+ caps->next = g_malloc0(sizeof(*caps));
+ caps = caps->next;
+ }
+ caps->value =
+ g_malloc(sizeof(*caps->value));
+ caps->value->capability = i;
+ caps->value->state = s->enabled_capabilities[i];
+ }
+
+ return head;
+}
+
+static void get_xbzrle_cache_stats(MigrationInfo *info)
+{
+ if (migrate_use_xbzrle()) {
+ info->has_xbzrle_cache = true;
+ info->xbzrle_cache = g_malloc0(sizeof(*info->xbzrle_cache));
+ info->xbzrle_cache->cache_size = migrate_xbzrle_cache_size();
+ info->xbzrle_cache->bytes = xbzrle_mig_bytes_transferred();
+ info->xbzrle_cache->pages = xbzrle_mig_pages_transferred();
+ info->xbzrle_cache->cache_miss = xbzrle_mig_pages_cache_miss();
+ info->xbzrle_cache->overflow = xbzrle_mig_pages_overflow();
+ }
+}
+
MigrationInfo *qmp_query_migrate(Error **errp)
{
MigrationInfo *info = g_malloc0(sizeof(*info));
@@ -133,6 +174,9 @@
info->ram->total = ram_bytes_total();
info->ram->total_time = qemu_get_clock_ms(rt_clock)
- s->total_time;
+ info->ram->duplicate = dup_mig_pages_transferred();
+ info->ram->normal = norm_mig_pages_transferred();
+ info->ram->normal_bytes = norm_mig_bytes_transferred();
if (blk_mig_active()) {
info->has_disk = true;
@@ -141,8 +185,12 @@
info->disk->remaining = blk_mig_bytes_remaining();
info->disk->total = blk_mig_bytes_total();
}
+
+ get_xbzrle_cache_stats(info);
break;
case MIG_STATE_COMPLETED:
+ get_xbzrle_cache_stats(info);
+
info->has_status = true;
info->status = g_strdup("completed");
@@ -152,6 +200,9 @@
info->ram->remaining = 0;
info->ram->total = ram_bytes_total();
info->ram->total_time = s->total_time;
+ info->ram->duplicate = dup_mig_pages_transferred();
+ info->ram->normal = norm_mig_pages_transferred();
+ info->ram->normal_bytes = norm_mig_bytes_transferred();
break;
case MIG_STATE_ERROR:
info->has_status = true;
@@ -166,6 +217,22 @@
return info;
}
+void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
+ Error **errp)
+{
+ MigrationState *s = migrate_get_current();
+ MigrationCapabilityStatusList *cap;
+
+ if (s->state == MIG_STATE_ACTIVE) {
+ error_set(errp, QERR_MIGRATION_ACTIVE);
+ return;
+ }
+
+ for (cap = params; cap; cap = cap->next) {
+ s->enabled_capabilities[cap->value->capability] = cap->value->state;
+ }
+}
+
/* shared migration helpers */
static int migrate_fd_cleanup(MigrationState *s)
@@ -375,10 +442,18 @@
{
MigrationState *s = migrate_get_current();
int64_t bandwidth_limit = s->bandwidth_limit;
+ bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
+ int64_t xbzrle_cache_size = s->xbzrle_cache_size;
+
+ memcpy(enabled_capabilities, s->enabled_capabilities,
+ sizeof(enabled_capabilities));
memset(s, 0, sizeof(*s));
s->bandwidth_limit = bandwidth_limit;
s->params = *params;
+ memcpy(s->enabled_capabilities, enabled_capabilities,
+ sizeof(enabled_capabilities));
+ s->xbzrle_cache_size = xbzrle_cache_size;
s->bandwidth_limit = bandwidth_limit;
s->state = MIG_STATE_SETUP;
@@ -459,6 +534,25 @@
migrate_fd_cancel(migrate_get_current());
}
+void qmp_migrate_set_cache_size(int64_t value, Error **errp)
+{
+ MigrationState *s = migrate_get_current();
+
+ /* Check for truncation */
+ if (value != (size_t)value) {
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE, "cache size",
+ "exceeding address space");
+ return;
+ }
+
+ s->xbzrle_cache_size = xbzrle_cache_resize(value);
+}
+
+int64_t qmp_query_migrate_cache_size(Error **errp)
+{
+ return migrate_xbzrle_cache_size();
+}
+
void qmp_migrate_set_speed(int64_t value, Error **errp)
{
MigrationState *s;
@@ -478,3 +572,21 @@
value = MAX(0, MIN(UINT64_MAX, value));
max_downtime = (uint64_t)value;
}
+
+int migrate_use_xbzrle(void)
+{
+ MigrationState *s;
+
+ s = migrate_get_current();
+
+ return s->enabled_capabilities[MIGRATION_CAPABILITY_XBZRLE];
+}
+
+int64_t migrate_xbzrle_cache_size(void)
+{
+ MigrationState *s;
+
+ s = migrate_get_current();
+
+ return s->xbzrle_cache_size;
+}
diff --git a/migration.h b/migration.h
index 57572a6..a9852fc 100644
--- a/migration.h
+++ b/migration.h
@@ -19,6 +19,7 @@
#include "notify.h"
#include "error.h"
#include "vmstate.h"
+#include "qapi-types.h"
struct MigrationParams {
bool blk;
@@ -39,6 +40,8 @@
void *opaque;
MigrationParams params;
int64_t total_time;
+ bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
+ int64_t xbzrle_cache_size;
};
void process_incoming_migration(QEMUFile *f);
@@ -84,6 +87,15 @@
extern SaveVMHandlers savevm_ram_handlers;
+uint64_t dup_mig_bytes_transferred(void);
+uint64_t dup_mig_pages_transferred(void);
+uint64_t norm_mig_bytes_transferred(void);
+uint64_t norm_mig_pages_transferred(void);
+uint64_t xbzrle_mig_bytes_transferred(void);
+uint64_t xbzrle_mig_pages_transferred(void);
+uint64_t xbzrle_mig_pages_overflow(void);
+uint64_t xbzrle_mig_pages_cache_miss(void);
+
/**
* @migrate_add_blocker - prevent migration from proceeding
*
@@ -98,4 +110,13 @@
*/
void migrate_del_blocker(Error *reason);
+int xbzrle_encode_buffer(uint8_t *old_buf, uint8_t *new_buf, int slen,
+ uint8_t *dst, int dlen);
+int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen);
+
+int migrate_use_xbzrle(void);
+int64_t migrate_xbzrle_cache_size(void);
+
+int64_t xbzrle_cache_resize(int64_t new_size);
+
#endif
diff --git a/monitor.c b/monitor.c
index 49dccfe..dd63f1d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -172,41 +172,11 @@
CPUArchState *mon_cpu;
BlockDriverCompletionFunc *password_completion_cb;
void *password_opaque;
-#ifdef CONFIG_DEBUG_MONITOR
- int print_calls_nr;
-#endif
QError *error;
QLIST_HEAD(,mon_fd_t) fds;
QLIST_ENTRY(Monitor) entry;
};
-#ifdef CONFIG_DEBUG_MONITOR
-#define MON_DEBUG(fmt, ...) do { \
- fprintf(stderr, "Monitor: "); \
- fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
-
-static inline void mon_print_count_inc(Monitor *mon)
-{
- mon->print_calls_nr++;
-}
-
-static inline void mon_print_count_init(Monitor *mon)
-{
- mon->print_calls_nr = 0;
-}
-
-static inline int mon_print_count_get(const Monitor *mon)
-{
- return mon->print_calls_nr;
-}
-
-#else /* !CONFIG_DEBUG_MONITOR */
-#define MON_DEBUG(fmt, ...) do { } while (0)
-static inline void mon_print_count_inc(Monitor *mon) { }
-static inline void mon_print_count_init(Monitor *mon) { }
-static inline int mon_print_count_get(const Monitor *mon) { return 0; }
-#endif /* CONFIG_DEBUG_MONITOR */
-
/* QMP checker flags */
#define QMP_ACCEPT_UNKNOWNS 1
@@ -299,8 +269,6 @@
if (!mon)
return;
- mon_print_count_inc(mon);
-
if (monitor_ctrl_mode(mon)) {
return;
}
@@ -385,16 +353,26 @@
QDECREF(json);
}
+static QDict *build_qmp_error_dict(const QError *err)
+{
+ QObject *obj;
+
+ obj = qobject_from_jsonf("{ 'error': { 'class': %s, 'desc': %p } }",
+ ErrorClass_lookup[err->err_class],
+ qerror_human(err));
+
+ return qobject_to_qdict(obj);
+}
+
static void monitor_protocol_emitter(Monitor *mon, QObject *data)
{
QDict *qmp;
trace_monitor_protocol_emitter(mon);
- qmp = qdict_new();
-
if (!monitor_has_error(mon)) {
/* success response */
+ qmp = qdict_new();
if (data) {
qobject_incref(data);
qdict_put_obj(qmp, "return", data);
@@ -404,9 +382,7 @@
}
} else {
/* error response */
- qdict_put(mon->error->error, "desc", qerror_human(mon->error));
- qdict_put(qmp, "error", mon->error->error);
- QINCREF(mon->error->error);
+ qmp = build_qmp_error_dict(mon->error);
QDECREF(mon->error);
mon->error = NULL;
}
@@ -456,6 +432,7 @@
[QEVENT_BLOCK_JOB_CANCELLED] = "BLOCK_JOB_CANCELLED",
[QEVENT_DEVICE_TRAY_MOVED] = "DEVICE_TRAY_MOVED",
[QEVENT_SUSPEND] = "SUSPEND",
+ [QEVENT_SUSPEND_DISK] = "SUSPEND_DISK",
[QEVENT_WAKEUP] = "WAKEUP",
[QEVENT_BALLOON_CHANGE] = "BALLOON_CHANGE",
};
@@ -2655,6 +2632,20 @@
.mhandler.info = hmp_info_migrate,
},
{
+ .name = "migrate_capabilities",
+ .args_type = "",
+ .params = "",
+ .help = "show current migration capabilities",
+ .mhandler.info = hmp_info_migrate_capabilities,
+ },
+ {
+ .name = "migrate_cache_size",
+ .args_type = "",
+ .params = "",
+ .help = "show current migration xbzrle cache size",
+ .mhandler.info = hmp_info_migrate_cache_size,
+ },
+ {
.name = "balloon",
.args_type = "",
.params = "",
@@ -3860,8 +3851,6 @@
if (!mon->error) {
mon->error = qerror;
} else {
- MON_DEBUG("Additional error report at %s:%d\n",
- qerror->file, qerror->linenr);
QDECREF(qerror);
}
}
@@ -3875,36 +3864,7 @@
* Action: Report an internal error to the client if in QMP.
*/
qerror_report(QERR_UNDEFINED_ERROR);
- MON_DEBUG("command '%s' returned failure but did not pass an error\n",
- cmd->name);
}
-
-#ifdef CONFIG_DEBUG_MONITOR
- if (!ret && monitor_has_error(mon)) {
- /*
- * If it returns success, it must not have passed an error.
- *
- * Action: Report the passed error to the client.
- */
- MON_DEBUG("command '%s' returned success but passed an error\n",
- cmd->name);
- }
-
- if (mon_print_count_get(mon) > 0 && strcmp(cmd->name, "info") != 0) {
- /*
- * Handlers should not call Monitor print functions.
- *
- * Action: Ignore them in QMP.
- *
- * (XXX: we don't check any 'info' or 'query' command here
- * because the user print function _is_ called by do_info(), hence
- * we will trigger this check. This problem will go away when we
- * make 'query' commands real and kill do_info())
- */
- MON_DEBUG("command '%s' called print functions %d time(s)\n",
- cmd->name, mon_print_count_get(mon));
- }
-#endif
}
static void handle_user_command(Monitor *mon, const char *cmdline)
@@ -4433,8 +4393,6 @@
int ret;
QObject *data = NULL;
- mon_print_count_init(mon);
-
ret = cmd->mhandler.cmd_new(mon, params, &data);
handler_audit(mon, cmd, ret);
monitor_protocol_emitter(mon, data);
diff --git a/monitor.h b/monitor.h
index 5f4de1b..4ef9a04 100644
--- a/monitor.h
+++ b/monitor.h
@@ -40,6 +40,7 @@
QEVENT_BLOCK_JOB_CANCELLED,
QEVENT_DEVICE_TRAY_MOVED,
QEVENT_SUSPEND,
+ QEVENT_SUSPEND_DISK,
QEVENT_WAKEUP,
QEVENT_BALLOON_CHANGE,
diff --git a/nbd.c b/nbd.c
index dc0adf9..0dd60c5 100644
--- a/nbd.c
+++ b/nbd.c
@@ -162,7 +162,7 @@
int tcp_socket_outgoing_spec(const char *address_and_port)
{
- return inet_connect(address_and_port, true, NULL);
+ return inet_connect(address_and_port, true, NULL, NULL);
}
int tcp_socket_incoming(const char *address, uint16_t port)
diff --git a/page_cache.c b/page_cache.c
new file mode 100644
index 0000000..0294f7e
--- /dev/null
+++ b/page_cache.c
@@ -0,0 +1,218 @@
+/*
+ * Page cache for QEMU
+ * The cache is base on a hash of the page address
+ *
+ * Copyright 2012 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ * Orit Wasserman <owasserm@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <stdbool.h>
+#include <glib.h>
+#include <strings.h>
+
+#include "qemu-common.h"
+#include "qemu/page_cache.h"
+
+#ifdef DEBUG_CACHE
+#define DPRINTF(fmt, ...) \
+ do { fprintf(stdout, "cache: " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+ do { } while (0)
+#endif
+
+typedef struct CacheItem CacheItem;
+
+struct CacheItem {
+ uint64_t it_addr;
+ uint64_t it_age;
+ uint8_t *it_data;
+};
+
+struct PageCache {
+ CacheItem *page_cache;
+ unsigned int page_size;
+ int64_t max_num_items;
+ uint64_t max_item_age;
+ int64_t num_items;
+};
+
+PageCache *cache_init(int64_t num_pages, unsigned int page_size)
+{
+ int64_t i;
+
+ PageCache *cache;
+
+ if (num_pages <= 0) {
+ DPRINTF("invalid number of pages\n");
+ return NULL;
+ }
+
+ cache = g_malloc(sizeof(*cache));
+
+ /* round down to the nearest power of 2 */
+ if (!is_power_of_2(num_pages)) {
+ num_pages = pow2floor(num_pages);
+ DPRINTF("rounding down to %" PRId64 "\n", num_pages);
+ }
+ cache->page_size = page_size;
+ cache->num_items = 0;
+ cache->max_item_age = 0;
+ cache->max_num_items = num_pages;
+
+ DPRINTF("Setting cache buckets to %" PRId64 "\n", cache->max_num_items);
+
+ cache->page_cache = g_malloc((cache->max_num_items) *
+ sizeof(*cache->page_cache));
+
+ for (i = 0; i < cache->max_num_items; i++) {
+ cache->page_cache[i].it_data = NULL;
+ cache->page_cache[i].it_age = 0;
+ cache->page_cache[i].it_addr = -1;
+ }
+
+ return cache;
+}
+
+void cache_fini(PageCache *cache)
+{
+ int64_t i;
+
+ g_assert(cache);
+ g_assert(cache->page_cache);
+
+ for (i = 0; i < cache->max_num_items; i++) {
+ g_free(cache->page_cache[i].it_data);
+ }
+
+ g_free(cache->page_cache);
+ cache->page_cache = NULL;
+}
+
+static size_t cache_get_cache_pos(const PageCache *cache,
+ uint64_t address)
+{
+ size_t pos;
+
+ g_assert(cache->max_num_items);
+ pos = (address / cache->page_size) & (cache->max_num_items - 1);
+ return pos;
+}
+
+bool cache_is_cached(const PageCache *cache, uint64_t addr)
+{
+ size_t pos;
+
+ g_assert(cache);
+ g_assert(cache->page_cache);
+
+ pos = cache_get_cache_pos(cache, addr);
+
+ return (cache->page_cache[pos].it_addr == addr);
+}
+
+static CacheItem *cache_get_by_addr(const PageCache *cache, uint64_t addr)
+{
+ size_t pos;
+
+ g_assert(cache);
+ g_assert(cache->page_cache);
+
+ pos = cache_get_cache_pos(cache, addr);
+
+ return &cache->page_cache[pos];
+}
+
+uint8_t *get_cached_data(const PageCache *cache, uint64_t addr)
+{
+ return cache_get_by_addr(cache, addr)->it_data;
+}
+
+void cache_insert(PageCache *cache, uint64_t addr, uint8_t *pdata)
+{
+
+ CacheItem *it = NULL;
+
+ g_assert(cache);
+ g_assert(cache->page_cache);
+
+ /* actual update of entry */
+ it = cache_get_by_addr(cache, addr);
+
+ if (!it->it_data) {
+ cache->num_items++;
+ }
+
+ it->it_data = pdata;
+ it->it_age = ++cache->max_item_age;
+ it->it_addr = addr;
+}
+
+int64_t cache_resize(PageCache *cache, int64_t new_num_pages)
+{
+ PageCache *new_cache;
+ int64_t i;
+
+ CacheItem *old_it, *new_it;
+
+ g_assert(cache);
+
+ /* cache was not inited */
+ if (cache->page_cache == NULL) {
+ return -1;
+ }
+
+ /* same size */
+ if (pow2floor(new_num_pages) == cache->max_num_items) {
+ return cache->max_num_items;
+ }
+
+ new_cache = cache_init(new_num_pages, cache->page_size);
+ if (!(new_cache)) {
+ DPRINTF("Error creating new cache\n");
+ return -1;
+ }
+
+ /* move all data from old cache */
+ for (i = 0; i < cache->max_num_items; i++) {
+ old_it = &cache->page_cache[i];
+ if (old_it->it_addr != -1) {
+ /* check for collision, if there is, keep MRU page */
+ new_it = cache_get_by_addr(new_cache, old_it->it_addr);
+ if (new_it->it_data) {
+ /* keep the MRU page */
+ if (new_it->it_age >= old_it->it_age) {
+ g_free(old_it->it_data);
+ } else {
+ g_free(new_it->it_data);
+ new_it->it_data = old_it->it_data;
+ new_it->it_age = old_it->it_age;
+ new_it->it_addr = old_it->it_addr;
+ }
+ } else {
+ cache_insert(new_cache, old_it->it_addr, old_it->it_data);
+ }
+ }
+ }
+
+ cache->page_cache = new_cache->page_cache;
+ cache->max_num_items = new_cache->max_num_items;
+ cache->num_items = new_cache->num_items;
+
+ g_free(new_cache);
+
+ return cache->max_num_items;
+}
diff --git a/qapi-schema.json b/qapi-schema.json
index bd9c450..53bbe46 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3,6 +3,36 @@
# QAPI Schema
##
+# @ErrorClass
+#
+# QEMU error classes
+#
+# @GenericError: this is used for errors that don't require a specific error
+# class. This should be the default case for most errors
+#
+# @CommandNotFound: the requested command has not been found
+#
+# @DeviceEncrypted: the requested operation can't be fulfilled because the
+# selected device is encrypted
+#
+# @DeviceNotActive: a device has failed to be become active
+#
+# @DeviceNotFound: the requested device has not been found
+#
+# @KVMMissingCap: the requested operation can't be fulfilled because a
+# required KVM capability is missing
+#
+# @MigrationExpected: the requested operation can't be fulfilled because a
+# migration process is expected
+#
+# Since: 1.2
+##
+{ 'enum': 'ErrorClass',
+ 'data': [ 'GenericError', 'CommandNotFound', 'DeviceEncrypted',
+ 'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap',
+ 'MigrationExpected' ] }
+
+##
# @NameInfo:
#
# Guest name information.
@@ -260,15 +290,43 @@
#
# @total: total amount of bytes involved in the migration process
#
-# @total_time: tota0l amount of ms since migration started. If
+# @total-time: total amount of ms since migration started. If
# migration has ended, it returns the total migration
# time. (since 1.2)
#
-# Since: 0.14.0.
+# @duplicate: number of duplicate pages (since 1.2)
+#
+# @normal : number of normal pages (since 1.2)
+#
+# @normal-bytes : number of normal bytes sent (since 1.2)
+#
+# Since: 0.14.0
##
{ 'type': 'MigrationStats',
'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' ,
- 'total_time': 'int' } }
+ 'total-time': 'int', 'duplicate': 'int', 'normal': 'int',
+ 'normal-bytes': 'int' } }
+
+##
+# @XBZRLECacheStats
+#
+# Detailed XBZRLE migration cache statistics
+#
+# @cache-size: XBZRLE cache size
+#
+# @bytes: amount of bytes already transferred to the target VM
+#
+# @pages: amount of pages transferred to the target VM
+#
+# @cache-miss: number of cache miss
+#
+# @overflow: number of overflows
+#
+# Since: 1.2
+##
+{ 'type': 'XBZRLECacheStats',
+ 'data': {'cache-size': 'int', 'bytes': 'int', 'pages': 'int',
+ 'cache-miss': 'int', 'overflow': 'int' } }
##
# @MigrationInfo
@@ -288,11 +346,16 @@
# status, only returned if status is 'active' and it is a block
# migration
#
+# @xbzrle-cache: #optional @XBZRLECacheStats containing detailed XBZRLE
+# migration statistics, only returned if XBZRLE feature is on and
+# status is 'active' or 'completed' (since 1.2)
+#
# Since: 0.14.0
##
{ 'type': 'MigrationInfo',
'data': {'*status': 'str', '*ram': 'MigrationStats',
- '*disk': 'MigrationStats'} }
+ '*disk': 'MigrationStats',
+ '*xbzrle-cache': 'XBZRLECacheStats'} }
##
# @query-migrate
@@ -306,6 +369,57 @@
{ 'command': 'query-migrate', 'returns': 'MigrationInfo' }
##
+# @MigrationCapability
+#
+# Migration capabilities enumeration
+#
+# @xbzrle: Migration supports xbzrle (Xor Based Zero Run Length Encoding).
+# This feature allows us to minimize migration traffic for certain work
+# loads, by sending compressed difference of the pages
+#
+# Since: 1.2
+##
+{ 'enum': 'MigrationCapability',
+ 'data': ['xbzrle'] }
+
+##
+# @MigrationCapabilityStatus
+#
+# Migration capability information
+#
+# @capability: capability enum
+#
+# @state: capability state bool
+#
+# Since: 1.2
+##
+{ 'type': 'MigrationCapabilityStatus',
+ 'data': { 'capability' : 'MigrationCapability', 'state' : 'bool' } }
+
+##
+# @migrate-set-capabilities
+#
+# Enable/Disable the following migration capabilities (like xbzrle)
+#
+# @capabilities: json array of capability modifications to make
+#
+# Since: 1.2
+##
+{ 'command': 'migrate-set-capabilities',
+ 'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
+
+##
+# @query-migrate-capabilities
+#
+# Returns information about the current migration capabilities status
+#
+# Returns: @MigrationCapabilitiesStatus
+#
+# Since: 1.2
+##
+{ 'command': 'query-migrate-capabilities', 'returns': ['MigrationCapabilityStatus']}
+
+##
# @MouseInfo:
#
# Information about a mouse device.
@@ -402,6 +516,9 @@
#
# @encrypted: true if the backing device is encrypted
#
+# @encryption_key_missing: true if the backing device is encrypted but an
+# valid encryption key is missing
+#
# @bps: total throughput limit in bytes per second is specified
#
# @bps_rd: read throughput limit in bytes per second is specified
@@ -421,9 +538,9 @@
{ 'type': 'BlockDeviceInfo',
'data': { 'file': 'str', 'ro': 'bool', 'drv': 'str',
'*backing_file': 'str', 'backing_file_depth': 'int',
- 'encrypted': 'bool', 'bps': 'int', 'bps_rd': 'int',
- 'bps_wr': 'int', 'iops': 'int', 'iops_rd': 'int',
- 'iops_wr': 'int'} }
+ 'encrypted': 'bool', 'encryption_key_missing': 'bool',
+ 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
+ 'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int'} }
##
# @BlockDeviceIoStatus:
@@ -625,7 +742,6 @@
# Returns information about the current VNC server
#
# Returns: @VncInfo
-# If VNC support is not compiled in, FeatureDisabled
#
# Since: 0.14.0
##
@@ -1009,9 +1125,6 @@
# virtual address (defaults to CPU 0)
#
# Returns: Nothing on success
-# If @cpu is not a valid VCPU, InvalidParameterValue
-# If @filename cannot be opened, OpenFileFailed
-# If an I/O error occurs while writing the file, IOError
#
# Since: 0.14.0
#
@@ -1032,8 +1145,6 @@
# @filename: the file to save the memory to as binary data
#
# Returns: Nothing on success
-# If @filename cannot be opened, OpenFileFailed
-# If an I/O error occurs while writing the file, IOError
#
# Since: 0.14.0
#
@@ -1075,7 +1186,6 @@
# Injects an Non-Maskable Interrupt into all guest's VCPUs.
#
# Returns: If successful, nothing
-# If the Virtual Machine doesn't support NMI injection, Unsupported
#
# Since: 0.14.0
#
@@ -1126,7 +1236,6 @@
# Returns: nothing on success
# If @device is not a valid block device, DeviceNotFound
# If @device is not encrypted, DeviceNotEncrypted
-# If @password is not valid for this device, InvalidPassword
#
# Notes: Not all block formats support encryption and some that do are not
# able to validate that a password is correct. Disk corruption may
@@ -1167,11 +1276,6 @@
#
# Returns: nothing on success
# If @device is not a valid block device, DeviceNotFound
-# If @size is negative, InvalidParameterValue
-# If the block device has no medium inserted, DeviceHasNoMedium
-# If the block device does not support resize, Unsupported
-# If the block device is read-only, DeviceIsReadOnly
-# If a long-running operation is using the device, DeviceInUse
#
# Since: 0.14.0
##
@@ -1233,10 +1337,6 @@
#
# Returns: nothing on success
# If @device is not a valid block device, DeviceNotFound
-# If @device is busy, DeviceInUse will be returned
-# If @snapshot-file can't be created, OpenFileFailed
-# If @snapshot-file can't be opened, OpenFileFailed
-# If @format is invalid, InvalidBlockFormat
#
# Note: The transaction aborts on the first failure. Therefore, there will
# be only one device or snapshot file returned in an error condition, and
@@ -1265,8 +1365,6 @@
#
# Returns: nothing on success
# If @device is not a valid block device, DeviceNotFound
-# If @snapshot-file can't be opened, OpenFileFailed
-# If @format is invalid, InvalidBlockFormat
#
# Since 0.14.0
##
@@ -1344,6 +1442,33 @@
{ 'command': 'migrate_set_speed', 'data': {'value': 'int'} }
##
+# @migrate-set-cache-size
+#
+# Set XBZRLE cache size
+#
+# @value: cache size in bytes
+#
+# The size will be rounded down to the nearest power of 2.
+# The cache size can be modified before and during ongoing migration
+#
+# Returns: nothing on success
+#
+# Since: 1.2
+##
+{ 'command': 'migrate-set-cache-size', 'data': {'value': 'int'} }
+
+##
+# @query-migrate-cache-size
+#
+# query XBZRLE cache size
+#
+# Returns: XBZRLE cache size in bytes
+#
+# Since: 1.2
+##
+{ 'command': 'query-migrate-cache-size', 'returns': 'int' }
+
+##
# @ObjectPropertyInfo:
#
# @name: the name of the property
@@ -1363,9 +1488,7 @@
# 4) A link type in the form 'link<subtype>' where subtype is a qdev
# device type name. Link properties form the device model graph.
#
-# Since: 1.1
-#
-# Notes: This type is experimental. Its syntax may change in future releases.
+# Since: 1.2
##
{ 'type': 'ObjectPropertyInfo',
'data': { 'name': 'str', 'type': 'str' } }
@@ -1382,10 +1505,7 @@
# Returns: a list of @ObjectPropertyInfo that describe the properties of the
# object.
#
-# Since: 1.1
-#
-# Notes: This command is experimental. It's syntax may change in future
-# releases.
+# Since: 1.2
##
{ 'command': 'qom-list',
'data': { 'path': 'str' },
@@ -1421,9 +1541,7 @@
# returns as #str pathnames. All integer property types (u8, u16, etc)
# are returned as #int.
#
-# Since: 1.1
-#
-# Notes: This command is experimental and may change syntax in future releases.
+# Since: 1.2
##
{ 'command': 'qom-get',
'data': { 'path': 'str', 'property': 'str' },
@@ -1442,9 +1560,7 @@
# @value: a value who's type is appropriate for the property type. See @qom-get
# for a description of type mapping.
#
-# Since: 1.1
-#
-# Notes: This command is experimental and may change syntax in future releases.
+# Since: 1.2
##
{ 'command': 'qom-set',
'data': { 'path': 'str', 'property': 'str', 'value': 'visitor' },
@@ -1468,11 +1584,6 @@
#
# Returns: Nothing on success
# If Spice is not enabled, DeviceNotFound
-# If @protocol does not support connected, InvalidParameter
-# If @protocol is invalid, InvalidParameter
-# If any other error occurs, SetPasswdFailed
-#
-# Notes: If VNC is not enabled, SetPasswdFailed is returned.
#
# Since: 0.14.0
##
@@ -1494,8 +1605,6 @@
#
# Returns: Nothing on success
# If @protocol is `spice' and Spice is not active, DeviceNotFound
-# If an error occurs setting password expiration, SetPasswdFailed
-# If @protocol is not `spice' or 'vnc', InvalidParameter
#
# Since: 0.14.0
#
@@ -1518,8 +1627,6 @@
#
# Returns: Nothing on success
# If @device is not a valid block device, DeviceNotFound
-# If @device is not removable and @force is false, DeviceNotRemovable
-# If @force is false and @device is locked, DeviceLocked
#
# Notes: Ejecting a device will no media results in success
#
@@ -1562,7 +1669,6 @@
#
# Returns: Nothing on success.
# If @device is not a valid block device, DeviceNotFound
-# If @format is not a valid block format, InvalidBlockFormat
# If the new block device is encrypted, DeviceEncrypted. Note that
# if this error is returned, the device has been opened successfully
# and an additional call to @block_passwd is required to set the
@@ -1598,7 +1704,6 @@
#
# Returns: Nothing on success
# If @device is not a valid block device, DeviceNotFound
-# If the argument combination is invalid, InvalidParameterCombination
#
# Since: 1.1
##
@@ -1632,11 +1737,7 @@
# @speed: #optional the maximum speed, in bytes per second
#
# Returns: Nothing on success
-# If streaming is already active on this device, DeviceInUse
# If @device does not exist, DeviceNotFound
-# If image streaming is not supported by this device, NotSupported
-# If @base does not exist, BaseNotFound
-# If @speed is invalid, InvalidParameter
#
# Since: 1.1
##
@@ -1658,8 +1759,6 @@
# Defaults to 0.
#
# Returns: Nothing on success
-# If the job type does not support throttling, NotSupported
-# If the speed value is invalid, InvalidParameter
# If no background operation is active on this device, DeviceNotActive
#
# Since: 1.1
@@ -1689,7 +1788,6 @@
#
# Returns: Nothing on success
# If no background operation is active on this device, DeviceNotActive
-# If cancellation already in progress, DeviceInUse
#
# Since: 1.1
##
@@ -1721,14 +1819,40 @@
# Returns: a list of @ObjectTypeInfo or an empty list if no results are found
#
# Since: 1.1
-#
-# Notes: This command is experimental and may change syntax in future releases.
##
{ 'command': 'qom-list-types',
'data': { '*implements': 'str', '*abstract': 'bool' },
'returns': [ 'ObjectTypeInfo' ] }
##
+# @DevicePropertyInfo:
+#
+# Information about device properties.
+#
+# @name: the name of the property
+# @type: the typename of the property
+#
+# Since: 1.2
+##
+{ 'type': 'DevicePropertyInfo',
+ 'data': { 'name': 'str', 'type': 'str' } }
+
+##
+# @device-list-properties:
+#
+# List properties associated with a device.
+#
+# @typename: the type name of a device
+#
+# Returns: a list of DevicePropertyInfo describing a devices properties
+#
+# Since: 1.2
+##
+{ 'command': 'device-list-properties',
+ 'data': { 'typename': 'str'},
+ 'returns': [ 'DevicePropertyInfo' ] }
+
+##
# @migrate
#
# Migrates the current running guest to another Virtual Machine.
@@ -1759,8 +1883,6 @@
# format.
#
# Returns: Nothing on success
-# If @filename cannot be opened, OpenFileFailed
-# If an I/O error occurs while writing the file, IOError
#
# Since: 1.1
##
@@ -1775,7 +1897,6 @@
#
# Returns: Nothing on success
# If @id is not a valid device, DeviceNotFound
-# If the device does not support unplug, BusNoHotplug
#
# Notes: When this command completes, the device may not be removed from the
# guest. Hot removal is an operation that requires guest cooperation.
@@ -1816,14 +1937,6 @@
# want to dump all guest's memory, please specify the start @begin and @length
#
# Returns: nothing on success
-# If @begin contains an invalid address, InvalidParameter
-# If only one of @begin and @length is specified, MissingParameter
-# If @protocol stats with "fd:", and the fd cannot be found, FdNotFound
-# If @protocol starts with "file:", and the file cannot be
-# opened, OpenFileFailed
-# If @protocol does not start with "fd:" or "file:", InvalidParameter
-# If an I/O error occurs while writing the file, IOError
-# If the target does not support this command, Unsupported
#
# Since: 1.2
##
@@ -1850,10 +1963,6 @@
#
# Returns: Nothing on success
# If @type is not a valid network backend, DeviceNotFound
-# If @id is not a valid identifier, InvalidParameterValue
-# if @id already exists, DuplicateId
-# If @props contains an invalid parameter for this backend,
-# InvalidParameter
##
{ 'command': 'netdev_add',
'data': {'type': 'str', 'id': 'str', '*props': '**'},
@@ -2173,8 +2282,6 @@
# @fdname: file descriptor name
#
# Returns: Nothing on success
-# If file descriptor was not received, FdNotSupplied
-# If @fdname is not valid, InvalidParameterType
#
# Since: 0.14.0
#
@@ -2194,8 +2301,58 @@
# @fdname: file descriptor name
#
# Returns: Nothing on success
-# If @fdname is not found, FdNotFound
#
# Since: 0.14.0
##
{ 'command': 'closefd', 'data': {'fdname': 'str'} }
+
+##
+# @MachineInfo:
+#
+# Information describing a machine.
+#
+# @name: the name of the machine
+#
+# @alias: #optional an alias for the machine name
+#
+# @default: #optional whether the machine is default
+#
+# Since: 1.2.0
+##
+{ 'type': 'MachineInfo',
+ 'data': { 'name': 'str', '*alias': 'str',
+ '*is-default': 'bool' } }
+
+##
+# @query-machines:
+#
+# Return a list of supported machines
+#
+# Returns: a list of MachineInfo
+#
+# Since: 1.2.0
+##
+{ 'command': 'query-machines', 'returns': ['MachineInfo'] }
+
+##
+# @CpuDefinitionInfo:
+#
+# Virtual CPU definition.
+#
+# @name: the name of the CPU definition
+#
+# Since: 1.2.0
+##
+{ 'type': 'CpuDefinitionInfo',
+ 'data': { 'name': 'str' } }
+
+##
+# @query-cpu-definitions:
+#
+# Return a list of supported virtual CPU definitions
+#
+# Returns: a list of CpuDefInfo
+#
+# Since: 1.2.0
+##
+{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] }
diff --git a/qapi/qmp-core.h b/qapi/qmp-core.h
index b0f64ba..00446cf 100644
--- a/qapi/qmp-core.h
+++ b/qapi/qmp-core.h
@@ -49,6 +49,7 @@
void qmp_enable_command(const char *name);
bool qmp_command_is_enabled(const char *name);
char **qmp_get_command_list(void);
+QObject *qmp_build_error_object(Error *errp);
#endif
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 122c1a2..4085994 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -14,8 +14,8 @@
#include "qemu-objects.h"
#include "qapi/qmp-core.h"
#include "json-parser.h"
+#include "qapi-types.h"
#include "error.h"
-#include "error_int.h"
#include "qerror.h"
static QDict *qmp_dispatch_check_obj(const QObject *request, Error **errp)
@@ -109,6 +109,13 @@
return ret;
}
+QObject *qmp_build_error_object(Error *errp)
+{
+ return qobject_from_jsonf("{ 'class': %s, 'desc': %s }",
+ ErrorClass_lookup[error_get_class(errp)],
+ error_get_pretty(errp));
+}
+
QObject *qmp_dispatch(QObject *request)
{
Error *err = NULL;
@@ -119,7 +126,7 @@
rsp = qdict_new();
if (err) {
- qdict_put_obj(rsp, "error", error_get_qobject(err));
+ qdict_put_obj(rsp, "error", qmp_build_error_object(err));
error_free(err);
} else if (ret) {
qdict_put_obj(rsp, "return", ret);
diff --git a/qemu-char.c b/qemu-char.c
index c2aaaee..382c71e 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2446,7 +2446,7 @@
if (is_listen) {
fd = inet_listen_opts(opts, 0, NULL);
} else {
- fd = inet_connect_opts(opts, NULL);
+ fd = inet_connect_opts(opts, NULL, NULL);
}
}
if (fd < 0) {
diff --git a/qemu-common.h b/qemu-common.h
index f9deca6..095e28d 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -1,3 +1,4 @@
+
/* Common header file that is included by all of qemu. */
#ifndef QEMU_COMMON_H
#define QEMU_COMMON_H
@@ -429,6 +430,26 @@
/* Round number up to multiple */
#define QEMU_ALIGN_UP(n, m) QEMU_ALIGN_DOWN((n) + (m) - 1, (m))
+static inline bool is_power_of_2(uint64_t value)
+{
+ if (!value) {
+ return 0;
+ }
+
+ return !(value & (value - 1));
+}
+
+/* round down to the nearest power of 2*/
+int64_t pow2floor(int64_t value);
+
#include "module.h"
+/*
+ * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128)
+ * Input is limited to 14-bit numbers
+ */
+
+int uleb128_encode_small(uint8_t *out, uint32_t n);
+int uleb128_decode_small(const uint8_t *in, uint32_t *n);
+
#endif
diff --git a/qemu-ga.c b/qemu-ga.c
index f1a39ec..8f87621 100644
--- a/qemu-ga.c
+++ b/qemu-ga.c
@@ -28,7 +28,6 @@
#include "module.h"
#include "signal.h"
#include "qerror.h"
-#include "error_int.h"
#include "qapi/qmp-core.h"
#include "qga/channel.h"
#ifdef _WIN32
@@ -515,7 +514,7 @@
} else {
g_warning("failed to parse event: %s", error_get_pretty(err));
}
- qdict_put_obj(qdict, "error", error_get_qobject(err));
+ qdict_put_obj(qdict, "error", qmp_build_error_object(err));
error_free(err);
} else {
qdict = qobject_to_qdict(obj);
@@ -532,7 +531,7 @@
qdict = qdict_new();
g_warning("unrecognized payload format");
error_set(&err, QERR_UNSUPPORTED);
- qdict_put_obj(qdict, "error", error_get_qobject(err));
+ qdict_put_obj(qdict, "error", qmp_build_error_object(err));
error_free(err);
}
ret = send_response(s, QOBJECT(qdict));
diff --git a/qemu-sockets.c b/qemu-sockets.c
index beb2bb6..361d890 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -209,7 +209,7 @@
return slisten;
}
-int inet_connect_opts(QemuOpts *opts, Error **errp)
+int inet_connect_opts(QemuOpts *opts, bool *in_progress, Error **errp)
{
struct addrinfo ai,*res,*e;
const char *addr;
@@ -224,6 +224,10 @@
ai.ai_family = PF_UNSPEC;
ai.ai_socktype = SOCK_STREAM;
+ if (in_progress) {
+ *in_progress = false;
+ }
+
addr = qemu_opt_get(opts, "host");
port = qemu_opt_get(opts, "port");
block = qemu_opt_get_bool(opts, "block", 0);
@@ -277,7 +281,9 @@
#else
if (!block && (rc == -EINPROGRESS)) {
#endif
- error_set(errp, QERR_SOCKET_CONNECT_IN_PROGRESS);
+ if (in_progress) {
+ *in_progress = true;
+ }
} else if (rc < 0) {
if (NULL == e->ai_next)
fprintf(stderr, "%s: connect(%s,%s,%s,%s): %s\n", __FUNCTION__,
@@ -487,7 +493,7 @@
return sock;
}
-int inet_connect(const char *str, bool block, Error **errp)
+int inet_connect(const char *str, bool block, bool *in_progress, Error **errp)
{
QemuOpts *opts;
int sock = -1;
@@ -497,7 +503,7 @@
if (block) {
qemu_opt_set(opts, "block", "on");
}
- sock = inet_connect_opts(opts, errp);
+ sock = inet_connect_opts(opts, in_progress, errp);
} else {
error_set(errp, QERR_SOCKET_CREATE_FAILED);
}
diff --git a/qemu_socket.h b/qemu_socket.h
index 4689ff3..30ae6af 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -42,8 +42,8 @@
int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp);
int inet_listen(const char *str, char *ostr, int olen,
int socktype, int port_offset, Error **errp);
-int inet_connect_opts(QemuOpts *opts, Error **errp);
-int inet_connect(const char *str, bool block, Error **errp);
+int inet_connect_opts(QemuOpts *opts, bool *in_progress, Error **errp);
+int inet_connect(const char *str, bool block, bool *in_progress, Error **errp);
int inet_dgram_opts(QemuOpts *opts);
const char *inet_strfamily(int family);
diff --git a/qerror.c b/qerror.c
index 92c4eff..0818504 100644
--- a/qerror.c
+++ b/qerror.c
@@ -23,320 +23,11 @@
};
/**
- * The 'desc' parameter is a printf-like string, the format of the format
- * string is:
- *
- * %(KEY)
- *
- * Where KEY is a QDict key, which has to be passed to qerror_from_info().
- *
- * Example:
- *
- * "foo error on device: %(device) slot: %(slot_nr)"
- *
- * A single percent sign can be printed if followed by a second one,
- * for example:
- *
- * "running out of foo: %(foo)%%"
- *
- * Please keep the entries in alphabetical order.
- * Use scripts/check-qerror.sh to check.
- */
-static const QErrorStringTable qerror_table[] = {
- {
- .error_fmt = QERR_ADD_CLIENT_FAILED,
- .desc = "Could not add client",
- },
- {
- .error_fmt = QERR_AMBIGUOUS_PATH,
- .desc = "Path '%(path)' does not uniquely identify a %(object)"
- },
- {
- .error_fmt = QERR_BAD_BUS_FOR_DEVICE,
- .desc = "Device '%(device)' can't go on a %(bad_bus_type) bus",
- },
- {
- .error_fmt = QERR_BASE_NOT_FOUND,
- .desc = "Base '%(base)' not found",
- },
- {
- .error_fmt = QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
- .desc = "Block format '%(format)' used by device '%(name)' does not support feature '%(feature)'",
- },
- {
- .error_fmt = QERR_BUS_NO_HOTPLUG,
- .desc = "Bus '%(bus)' does not support hotplugging",
- },
- {
- .error_fmt = QERR_BUS_NOT_FOUND,
- .desc = "Bus '%(bus)' not found",
- },
- {
- .error_fmt = QERR_COMMAND_DISABLED,
- .desc = "The command %(name) has been disabled for this instance",
- },
- {
- .error_fmt = QERR_COMMAND_NOT_FOUND,
- .desc = "The command %(name) has not been found",
- },
- {
- .error_fmt = QERR_DEVICE_ENCRYPTED,
- .desc = "Device '%(device)' is encrypted",
- },
- {
- .error_fmt = QERR_DEVICE_FEATURE_BLOCKS_MIGRATION,
- .desc = "Migration is disabled when using feature '%(feature)' in device '%(device)'",
- },
- {
- .error_fmt = QERR_DEVICE_HAS_NO_MEDIUM,
- .desc = "Device '%(device)' has no medium",
- },
- {
- .error_fmt = QERR_DEVICE_INIT_FAILED,
- .desc = "Device '%(device)' could not be initialized",
- },
- {
- .error_fmt = QERR_DEVICE_IN_USE,
- .desc = "Device '%(device)' is in use",
- },
- {
- .error_fmt = QERR_DEVICE_IS_READ_ONLY,
- .desc = "Device '%(device)' is read only",
- },
- {
- .error_fmt = QERR_DEVICE_LOCKED,
- .desc = "Device '%(device)' is locked",
- },
- {
- .error_fmt = QERR_DEVICE_MULTIPLE_BUSSES,
- .desc = "Device '%(device)' has multiple child busses",
- },
- {
- .error_fmt = QERR_DEVICE_NO_BUS,
- .desc = "Device '%(device)' has no child bus",
- },
- {
- .error_fmt = QERR_DEVICE_NO_HOTPLUG,
- .desc = "Device '%(device)' does not support hotplugging",
- },
- {
- .error_fmt = QERR_DEVICE_NOT_ACTIVE,
- .desc = "Device '%(device)' has not been activated",
- },
- {
- .error_fmt = QERR_DEVICE_NOT_ENCRYPTED,
- .desc = "Device '%(device)' is not encrypted",
- },
- {
- .error_fmt = QERR_DEVICE_NOT_FOUND,
- .desc = "Device '%(device)' not found",
- },
- {
- .error_fmt = QERR_DEVICE_NOT_REMOVABLE,
- .desc = "Device '%(device)' is not removable",
- },
- {
- .error_fmt = QERR_DUPLICATE_ID,
- .desc = "Duplicate ID '%(id)' for %(object)",
- },
- {
- .error_fmt = QERR_FD_NOT_FOUND,
- .desc = "File descriptor named '%(name)' not found",
- },
- {
- .error_fmt = QERR_FD_NOT_SUPPLIED,
- .desc = "No file descriptor supplied via SCM_RIGHTS",
- },
- {
- .error_fmt = QERR_FEATURE_DISABLED,
- .desc = "The feature '%(name)' is not enabled",
- },
- {
- .error_fmt = QERR_INVALID_BLOCK_FORMAT,
- .desc = "Invalid block format '%(name)'",
- },
- {
- .error_fmt = QERR_INVALID_OPTION_GROUP,
- .desc = "There is no option group '%(group)'",
- },
- {
- .error_fmt = QERR_INVALID_PARAMETER,
- .desc = "Invalid parameter '%(name)'",
- },
- {
- .error_fmt = QERR_INVALID_PARAMETER_COMBINATION,
- .desc = "Invalid parameter combination",
- },
- {
- .error_fmt = QERR_INVALID_PARAMETER_TYPE,
- .desc = "Invalid parameter type for '%(name)', expected: %(expected)",
- },
- {
- .error_fmt = QERR_INVALID_PARAMETER_VALUE,
- .desc = "Parameter '%(name)' expects %(expected)",
- },
- {
- .error_fmt = QERR_INVALID_PASSWORD,
- .desc = "Password incorrect",
- },
- {
- .error_fmt = QERR_IO_ERROR,
- .desc = "An IO error has occurred",
- },
- {
- .error_fmt = QERR_JSON_PARSE_ERROR,
- .desc = "JSON parse error, %(message)",
-
- },
- {
- .error_fmt = QERR_JSON_PARSING,
- .desc = "Invalid JSON syntax",
- },
- {
- .error_fmt = QERR_KVM_MISSING_CAP,
- .desc = "Using KVM without %(capability), %(feature) unavailable",
- },
- {
- .error_fmt = QERR_MIGRATION_ACTIVE,
- .desc = "There's a migration process in progress",
- },
- {
- .error_fmt = QERR_MIGRATION_NOT_SUPPORTED,
- .desc = "State blocked by non-migratable device '%(device)'",
- },
- {
- .error_fmt = QERR_MIGRATION_EXPECTED,
- .desc = "An incoming migration is expected before this command can be executed",
- },
- {
- .error_fmt = QERR_MISSING_PARAMETER,
- .desc = "Parameter '%(name)' is missing",
- },
- {
- .error_fmt = QERR_NO_BUS_FOR_DEVICE,
- .desc = "No '%(bus)' bus found for device '%(device)'",
- },
- {
- .error_fmt = QERR_NOT_SUPPORTED,
- .desc = "Not supported",
- },
- {
- .error_fmt = QERR_OPEN_FILE_FAILED,
- .desc = "Could not open '%(filename)'",
- },
- {
- .error_fmt = QERR_PERMISSION_DENIED,
- .desc = "Insufficient permission to perform this operation",
- },
- {
- .error_fmt = QERR_PROPERTY_NOT_FOUND,
- .desc = "Property '%(device).%(property)' not found",
- },
- {
- .error_fmt = QERR_PROPERTY_VALUE_BAD,
- .desc = "Property '%(device).%(property)' doesn't take value '%(value)'",
- },
- {
- .error_fmt = QERR_PROPERTY_VALUE_IN_USE,
- .desc = "Property '%(device).%(property)' can't take value '%(value)', it's in use",
- },
- {
- .error_fmt = QERR_PROPERTY_VALUE_NOT_FOUND,
- .desc = "Property '%(device).%(property)' can't find value '%(value)'",
- },
- {
- .error_fmt = QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
- .desc = "Property '%(device).%(property)' doesn't take "
- "value '%(value)', it's not a power of 2",
- },
- {
- .error_fmt = QERR_PROPERTY_VALUE_OUT_OF_RANGE,
- .desc = "Property '%(device).%(property)' doesn't take "
- "value %(value) (minimum: %(min), maximum: %(max))",
- },
- {
- .error_fmt = QERR_QGA_COMMAND_FAILED,
- .desc = "Guest agent command failed, error was '%(message)'",
- },
- {
- .error_fmt = QERR_QGA_LOGGING_FAILED,
- .desc = "Guest agent failed to log non-optional log statement",
- },
- {
- .error_fmt = QERR_QMP_BAD_INPUT_OBJECT,
- .desc = "Expected '%(expected)' in QMP input",
- },
- {
- .error_fmt = QERR_QMP_BAD_INPUT_OBJECT_MEMBER,
- .desc = "QMP input object member '%(member)' expects '%(expected)'",
- },
- {
- .error_fmt = QERR_QMP_EXTRA_MEMBER,
- .desc = "QMP input object member '%(member)' is unexpected",
- },
- {
- .error_fmt = QERR_RESET_REQUIRED,
- .desc = "Resetting the Virtual Machine is required",
- },
- {
- .error_fmt = QERR_SET_PASSWD_FAILED,
- .desc = "Could not set password",
- },
- {
- .error_fmt = QERR_TOO_MANY_FILES,
- .desc = "Too many open files",
- },
- {
- .error_fmt = QERR_UNDEFINED_ERROR,
- .desc = "An undefined error has occurred",
- },
- {
- .error_fmt = QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
- .desc = "'%(device)' uses a %(format) feature which is not "
- "supported by this qemu version: %(feature)",
- },
- {
- .error_fmt = QERR_UNSUPPORTED,
- .desc = "this feature or command is not currently supported",
- },
- {
- .error_fmt = QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION,
- .desc = "Migration is disabled when VirtFS export path '%(path)' "
- "is mounted in the guest using mount_tag '%(tag)'",
- },
- {
- .error_fmt = QERR_VNC_SERVER_FAILED,
- .desc = "Could not start VNC server on %(target)",
- },
- {
- .error_fmt = QERR_SOCKET_CONNECT_IN_PROGRESS,
- .desc = "Connection can not be completed immediately",
- },
- {
- .error_fmt = QERR_SOCKET_CONNECT_FAILED,
- .desc = "Failed to connect to socket",
- },
- {
- .error_fmt = QERR_SOCKET_LISTEN_FAILED,
- .desc = "Failed to set socket to listening mode",
- },
- {
- .error_fmt = QERR_SOCKET_BIND_FAILED,
- .desc = "Failed to bind socket",
- },
- {
- .error_fmt = QERR_SOCKET_CREATE_FAILED,
- .desc = "Failed to create socket",
- },
- {}
-};
-
-/**
* qerror_new(): Create a new QError
*
* Return strong reference.
*/
-QError *qerror_new(void)
+static QError *qerror_new(void)
{
QError *qerr;
@@ -346,200 +37,31 @@
return qerr;
}
-static void GCC_FMT_ATTR(2, 3) qerror_abort(const QError *qerr,
- const char *fmt, ...)
-{
- va_list ap;
-
- fprintf(stderr, "qerror: bad call in function '%s':\n", qerr->func);
- fprintf(stderr, "qerror: -> ");
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-
- fprintf(stderr, "\nqerror: call at %s:%d\n", qerr->file, qerr->linenr);
- abort();
-}
-
-static void GCC_FMT_ATTR(2, 0) qerror_set_data(QError *qerr,
- const char *fmt, va_list *va)
-{
- QObject *obj;
-
- obj = qobject_from_jsonv(fmt, va);
- if (!obj) {
- qerror_abort(qerr, "invalid format '%s'", fmt);
- }
- if (qobject_type(obj) != QTYPE_QDICT) {
- qerror_abort(qerr, "error format is not a QDict '%s'", fmt);
- }
-
- qerr->error = qobject_to_qdict(obj);
-
- obj = qdict_get(qerr->error, "class");
- if (!obj) {
- qerror_abort(qerr, "missing 'class' key in '%s'", fmt);
- }
- if (qobject_type(obj) != QTYPE_QSTRING) {
- qerror_abort(qerr, "'class' key value should be a QString");
- }
-
- obj = qdict_get(qerr->error, "data");
- if (!obj) {
- qerror_abort(qerr, "missing 'data' key in '%s'", fmt);
- }
- if (qobject_type(obj) != QTYPE_QDICT) {
- qerror_abort(qerr, "'data' key value should be a QDICT");
- }
-}
-
-static void qerror_set_desc(QError *qerr, const char *fmt)
-{
- int i;
-
- // FIXME: inefficient loop
-
- for (i = 0; qerror_table[i].error_fmt; i++) {
- if (strcmp(qerror_table[i].error_fmt, fmt) == 0) {
- qerr->entry = &qerror_table[i];
- return;
- }
- }
-
- qerror_abort(qerr, "error format '%s' not found", fmt);
-}
-
/**
* qerror_from_info(): Create a new QError from error information
*
- * The information consists of:
- *
- * - file the file name of where the error occurred
- * - linenr the line number of where the error occurred
- * - func the function name of where the error occurred
- * - fmt JSON printf-like dictionary, there must exist keys 'class' and
- * 'data'
- * - va va_list of all arguments specified by fmt
- *
* Return strong reference.
*/
-QError *qerror_from_info(const char *file, int linenr, const char *func,
- const char *fmt, va_list *va)
+static QError *qerror_from_info(ErrorClass err_class, const char *fmt,
+ va_list *va)
{
QError *qerr;
qerr = qerror_new();
loc_save(&qerr->loc);
- qerr->linenr = linenr;
- qerr->file = file;
- qerr->func = func;
- if (!fmt) {
- qerror_abort(qerr, "QDict not specified");
- }
-
- qerror_set_data(qerr, fmt, va);
- qerror_set_desc(qerr, fmt);
+ qerr->err_msg = g_strdup_vprintf(fmt, *va);
+ qerr->err_class = err_class;
return qerr;
}
-static void parse_error(const QErrorStringTable *entry, int c)
-{
- fprintf(stderr, "expected '%c' in '%s'", c, entry->desc);
- abort();
-}
-
-static const char *append_field(QDict *error, QString *outstr,
- const QErrorStringTable *entry,
- const char *start)
-{
- QObject *obj;
- QDict *qdict;
- QString *key_qs;
- const char *end, *key;
-
- if (*start != '%')
- parse_error(entry, '%');
- start++;
- if (*start != '(')
- parse_error(entry, '(');
- start++;
-
- end = strchr(start, ')');
- if (!end)
- parse_error(entry, ')');
-
- key_qs = qstring_from_substr(start, 0, end - start - 1);
- key = qstring_get_str(key_qs);
-
- qdict = qobject_to_qdict(qdict_get(error, "data"));
- obj = qdict_get(qdict, key);
- if (!obj) {
- abort();
- }
-
- switch (qobject_type(obj)) {
- case QTYPE_QSTRING:
- qstring_append(outstr, qdict_get_str(qdict, key));
- break;
- case QTYPE_QINT:
- qstring_append_int(outstr, qdict_get_int(qdict, key));
- break;
- default:
- abort();
- }
-
- QDECREF(key_qs);
- return ++end;
-}
-
-static QString *qerror_format_desc(QDict *error,
- const QErrorStringTable *entry)
-{
- QString *qstring;
- const char *p;
-
- assert(entry != NULL);
-
- qstring = qstring_new();
-
- for (p = entry->desc; *p != '\0';) {
- if (*p != '%') {
- qstring_append_chr(qstring, *p++);
- } else if (*(p + 1) == '%') {
- qstring_append_chr(qstring, '%');
- p += 2;
- } else {
- p = append_field(error, qstring, entry, p);
- }
- }
-
- return qstring;
-}
-
-QString *qerror_format(const char *fmt, QDict *error)
-{
- const QErrorStringTable *entry = NULL;
- int i;
-
- for (i = 0; qerror_table[i].error_fmt; i++) {
- if (strcmp(qerror_table[i].error_fmt, fmt) == 0) {
- entry = &qerror_table[i];
- break;
- }
- }
-
- return qerror_format_desc(error, entry);
-}
-
/**
* qerror_human(): Format QError data into human-readable string.
*/
QString *qerror_human(const QError *qerror)
{
- return qerror_format_desc(qerror->error, qerror->entry);
+ return qstring_from_str(qerror->err_msg);
}
/**
@@ -549,7 +71,7 @@
* it uses error_report() for this, so that the output is routed to the right
* place (ie. stderr or Monitor's device).
*/
-void qerror_print(QError *qerror)
+static void qerror_print(QError *qerror)
{
QString *qstring = qerror_human(qerror);
loc_push_restore(&qerror->loc);
@@ -558,14 +80,13 @@
QDECREF(qstring);
}
-void qerror_report_internal(const char *file, int linenr, const char *func,
- const char *fmt, ...)
+void qerror_report(ErrorClass eclass, const char *fmt, ...)
{
va_list va;
QError *qerror;
va_start(va, fmt);
- qerror = qerror_from_info(file, linenr, func, fmt, &va);
+ qerror = qerror_from_info(eclass, fmt, &va);
va_end(va);
if (monitor_cur_is_qmp()) {
@@ -579,27 +100,18 @@
/* Evil... */
struct Error
{
- QDict *obj;
- const char *fmt;
char *msg;
+ ErrorClass err_class;
};
void qerror_report_err(Error *err)
{
QError *qerr;
- int i;
qerr = qerror_new();
loc_save(&qerr->loc);
- QINCREF(err->obj);
- qerr->error = err->obj;
-
- for (i = 0; qerror_table[i].error_fmt; i++) {
- if (strcmp(qerror_table[i].error_fmt, err->fmt) == 0) {
- qerr->entry = &qerror_table[i];
- break;
- }
- }
+ qerr->err_msg = g_strdup(err->msg);
+ qerr->err_class = err->err_class;
if (monitor_cur_is_qmp()) {
monitor_set_error(cur_mon, qerr);
@@ -620,7 +132,7 @@
/**
* qobject_to_qerror(): Convert a QObject into a QError
*/
-QError *qobject_to_qerror(const QObject *obj)
+static QError *qobject_to_qerror(const QObject *obj)
{
if (qobject_type(obj) != QTYPE_QERROR) {
return NULL;
@@ -639,6 +151,6 @@
assert(obj != NULL);
qerr = qobject_to_qerror(obj);
- QDECREF(qerr->error);
+ g_free(qerr->err_msg);
g_free(qerr);
}
diff --git a/qerror.h b/qerror.h
index b4c8758..d0a76a4 100644
--- a/qerror.h
+++ b/qerror.h
@@ -16,36 +16,20 @@
#include "qstring.h"
#include "qemu-error.h"
#include "error.h"
+#include "qapi-types.h"
#include <stdarg.h>
-typedef struct QErrorStringTable {
- const char *desc;
- const char *error_fmt;
-} QErrorStringTable;
-
typedef struct QError {
QObject_HEAD;
- QDict *error;
Location loc;
- int linenr;
- const char *file;
- const char *func;
- const QErrorStringTable *entry;
+ char *err_msg;
+ ErrorClass err_class;
} QError;
-QError *qerror_new(void);
-QError *qerror_from_info(const char *file, int linenr, const char *func,
- const char *fmt, va_list *va) GCC_FMT_ATTR(4, 0);
QString *qerror_human(const QError *qerror);
-void qerror_print(QError *qerror);
-void qerror_report_internal(const char *file, int linenr, const char *func,
- const char *fmt, ...) GCC_FMT_ATTR(4, 5);
+void qerror_report(ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
void qerror_report_err(Error *err);
void assert_no_error(Error *err);
-QString *qerror_format(const char *fmt, QDict *error);
-#define qerror_report(fmt, ...) \
- qerror_report_internal(__FILE__, __LINE__, __func__, fmt, ## __VA_ARGS__)
-QError *qobject_to_qerror(const QObject *obj);
/*
* QError class list
@@ -53,217 +37,213 @@
* Use scripts/check-qerror.sh to check.
*/
#define QERR_ADD_CLIENT_FAILED \
- "{ 'class': 'AddClientFailed', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Could not add client"
#define QERR_AMBIGUOUS_PATH \
- "{ 'class': 'AmbiguousPath', 'data': { 'path': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Path '%s' does not uniquely identify an object"
#define QERR_BAD_BUS_FOR_DEVICE \
- "{ 'class': 'BadBusForDevice', 'data': { 'device': %s, 'bad_bus_type': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Device '%s' can't go on a %s bus"
#define QERR_BASE_NOT_FOUND \
- "{ 'class': 'BaseNotFound', 'data': { 'base': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Base '%s' not found"
#define QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED \
- "{ 'class': 'BlockFormatFeatureNotSupported', 'data': { 'format': %s, 'name': %s, 'feature': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Block format '%s' used by device '%s' does not support feature '%s'"
#define QERR_BUFFER_OVERRUN \
- "{ 'class': 'BufferOverrun', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "An internal buffer overran"
#define QERR_BUS_NO_HOTPLUG \
- "{ 'class': 'BusNoHotplug', 'data': { 'bus': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Bus '%s' does not support hotplugging"
#define QERR_BUS_NOT_FOUND \
- "{ 'class': 'BusNotFound', 'data': { 'bus': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Bus '%s' not found"
#define QERR_COMMAND_DISABLED \
- "{ 'class': 'CommandDisabled', 'data': { 'name': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "The command %s has been disabled for this instance"
#define QERR_COMMAND_NOT_FOUND \
- "{ 'class': 'CommandNotFound', 'data': { 'name': %s } }"
+ ERROR_CLASS_COMMAND_NOT_FOUND, "The command %s has not been found"
#define QERR_DEVICE_ENCRYPTED \
- "{ 'class': 'DeviceEncrypted', 'data': { 'device': %s, 'filename': %s } }"
+ ERROR_CLASS_DEVICE_ENCRYPTED, "'%s' (%s) is encrypted"
#define QERR_DEVICE_FEATURE_BLOCKS_MIGRATION \
- "{ 'class': 'DeviceFeatureBlocksMigration', 'data': { 'device': %s, 'feature': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Migration is disabled when using feature '%s' in device '%s'"
#define QERR_DEVICE_HAS_NO_MEDIUM \
- "{ 'class': 'DeviceHasNoMedium', 'data': { 'device': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Device '%s' has no medium"
#define QERR_DEVICE_INIT_FAILED \
- "{ 'class': 'DeviceInitFailed', 'data': { 'device': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Device '%s' could not be initialized"
#define QERR_DEVICE_IN_USE \
- "{ 'class': 'DeviceInUse', 'data': { 'device': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Device '%s' is in use"
#define QERR_DEVICE_IS_READ_ONLY \
- "{ 'class': 'DeviceIsReadOnly', 'data': { 'device': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Device '%s' is read only"
#define QERR_DEVICE_LOCKED \
- "{ 'class': 'DeviceLocked', 'data': { 'device': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Device '%s' is locked"
#define QERR_DEVICE_MULTIPLE_BUSSES \
- "{ 'class': 'DeviceMultipleBusses', 'data': { 'device': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Device '%s' has multiple child busses"
#define QERR_DEVICE_NO_BUS \
- "{ 'class': 'DeviceNoBus', 'data': { 'device': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Device '%s' has no child bus"
#define QERR_DEVICE_NO_HOTPLUG \
- "{ 'class': 'DeviceNoHotplug', 'data': { 'device': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Device '%s' does not support hotplugging"
#define QERR_DEVICE_NOT_ACTIVE \
- "{ 'class': 'DeviceNotActive', 'data': { 'device': %s } }"
+ ERROR_CLASS_DEVICE_NOT_ACTIVE, "Device '%s' has not been activated"
#define QERR_DEVICE_NOT_ENCRYPTED \
- "{ 'class': 'DeviceNotEncrypted', 'data': { 'device': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Device '%s' is not encrypted"
#define QERR_DEVICE_NOT_FOUND \
- "{ 'class': 'DeviceNotFound', 'data': { 'device': %s } }"
+ ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found"
#define QERR_DEVICE_NOT_REMOVABLE \
- "{ 'class': 'DeviceNotRemovable', 'data': { 'device': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Device '%s' is not removable"
#define QERR_DUPLICATE_ID \
- "{ 'class': 'DuplicateId', 'data': { 'id': %s, 'object': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Duplicate ID '%s' for %s"
#define QERR_FD_NOT_FOUND \
- "{ 'class': 'FdNotFound', 'data': { 'name': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "File descriptor named '%s' not found"
#define QERR_FD_NOT_SUPPLIED \
- "{ 'class': 'FdNotSupplied', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "No file descriptor supplied via SCM_RIGHTS"
#define QERR_FEATURE_DISABLED \
- "{ 'class': 'FeatureDisabled', 'data': { 'name': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "The feature '%s' is not enabled"
#define QERR_INVALID_BLOCK_FORMAT \
- "{ 'class': 'InvalidBlockFormat', 'data': { 'name': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Invalid block format '%s'"
#define QERR_INVALID_OPTION_GROUP \
- "{ 'class': 'InvalidOptionGroup', 'data': { 'group': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "There is no option group '%s'"
#define QERR_INVALID_PARAMETER \
- "{ 'class': 'InvalidParameter', 'data': { 'name': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Invalid parameter '%s'"
#define QERR_INVALID_PARAMETER_COMBINATION \
- "{ 'class': 'InvalidParameterCombination', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Invalid parameter combination"
#define QERR_INVALID_PARAMETER_TYPE \
- "{ 'class': 'InvalidParameterType', 'data': { 'name': %s,'expected': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Invalid parameter type for '%s', expected: %s"
#define QERR_INVALID_PARAMETER_VALUE \
- "{ 'class': 'InvalidParameterValue', 'data': { 'name': %s, 'expected': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Parameter '%s' expects %s"
#define QERR_INVALID_PASSWORD \
- "{ 'class': 'InvalidPassword', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Password incorrect"
#define QERR_IO_ERROR \
- "{ 'class': 'IOError', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "An IO error has occurred"
#define QERR_JSON_PARSE_ERROR \
- "{ 'class': 'JSONParseError', 'data': { 'message': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "JSON parse error, %s"
#define QERR_JSON_PARSING \
- "{ 'class': 'JSONParsing', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Invalid JSON syntax"
#define QERR_KVM_MISSING_CAP \
- "{ 'class': 'KVMMissingCap', 'data': { 'capability': %s, 'feature': %s } }"
+ ERROR_CLASS_K_V_M_MISSING_CAP, "Using KVM without %s, %s unavailable"
#define QERR_MIGRATION_ACTIVE \
- "{ 'class': 'MigrationActive', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "There's a migration process in progress"
#define QERR_MIGRATION_NOT_SUPPORTED \
- "{ 'class': 'MigrationNotSupported', 'data': {'device': %s} }"
+ ERROR_CLASS_GENERIC_ERROR, "State blocked by non-migratable device '%s'"
#define QERR_MIGRATION_EXPECTED \
- "{ 'class': 'MigrationExpected', 'data': {} }"
+ ERROR_CLASS_MIGRATION_EXPECTED, "An incoming migration is expected before this command can be executed"
#define QERR_MISSING_PARAMETER \
- "{ 'class': 'MissingParameter', 'data': { 'name': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Parameter '%s' is missing"
#define QERR_NO_BUS_FOR_DEVICE \
- "{ 'class': 'NoBusForDevice', 'data': { 'device': %s, 'bus': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "No '%s' bus found for device '%s'"
#define QERR_NOT_SUPPORTED \
- "{ 'class': 'NotSupported', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Not supported"
#define QERR_OPEN_FILE_FAILED \
- "{ 'class': 'OpenFileFailed', 'data': { 'filename': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Could not open '%s'"
#define QERR_PERMISSION_DENIED \
- "{ 'class': 'PermissionDenied', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Insufficient permission to perform this operation"
#define QERR_PROPERTY_NOT_FOUND \
- "{ 'class': 'PropertyNotFound', 'data': { 'device': %s, 'property': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' not found"
#define QERR_PROPERTY_VALUE_BAD \
- "{ 'class': 'PropertyValueBad', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' doesn't take value '%s'"
#define QERR_PROPERTY_VALUE_IN_USE \
- "{ 'class': 'PropertyValueInUse', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' can't take value '%s', it's in use"
#define QERR_PROPERTY_VALUE_NOT_FOUND \
- "{ 'class': 'PropertyValueNotFound', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' can't find value '%s'"
#define QERR_PROPERTY_VALUE_NOT_POWER_OF_2 \
- "{ 'class': 'PropertyValueNotPowerOf2', 'data': { " \
- "'device': %s, 'property': %s, 'value': %"PRId64" } }"
+ ERROR_CLASS_GENERIC_ERROR, "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2"
#define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
- "{ 'class': 'PropertyValueOutOfRange', 'data': { 'device': %s, 'property': %s, 'value': %"PRId64", 'min': %"PRId64", 'max': %"PRId64" } }"
+ ERROR_CLASS_GENERIC_ERROR, "Property %s.%s doesn't take value %" PRId64 " (minimum: %" PRId64 ", maximum: %" PRId64 ")"
#define QERR_QGA_COMMAND_FAILED \
- "{ 'class': 'QgaCommandFailed', 'data': { 'message': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Guest agent command failed, error was '%s'"
#define QERR_QGA_LOGGING_FAILED \
- "{ 'class': 'QgaLoggingFailed', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Guest agent failed to log non-optional log statement"
#define QERR_QMP_BAD_INPUT_OBJECT \
- "{ 'class': 'QMPBadInputObject', 'data': { 'expected': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Expected '%s' in QMP input"
#define QERR_QMP_BAD_INPUT_OBJECT_MEMBER \
- "{ 'class': 'QMPBadInputObjectMember', 'data': { 'member': %s, 'expected': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "QMP input object member '%s' expects '%s'"
#define QERR_QMP_EXTRA_MEMBER \
- "{ 'class': 'QMPExtraInputObjectMember', 'data': { 'member': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "QMP input object member '%s' is unexpected"
#define QERR_RESET_REQUIRED \
- "{ 'class': 'ResetRequired', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Resetting the Virtual Machine is required"
#define QERR_SET_PASSWD_FAILED \
- "{ 'class': 'SetPasswdFailed', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Could not set password"
#define QERR_TOO_MANY_FILES \
- "{ 'class': 'TooManyFiles', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Too many open files"
#define QERR_UNDEFINED_ERROR \
- "{ 'class': 'UndefinedError', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "An undefined error has occurred"
#define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \
- "{ 'class': 'UnknownBlockFormatFeature', 'data': { 'device': %s, 'format': %s, 'feature': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "'%s' uses a %s feature which is not supported by this qemu version: %s"
#define QERR_UNSUPPORTED \
- "{ 'class': 'Unsupported', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "this feature or command is not currently supported"
#define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \
- "{ 'class': 'VirtFSFeatureBlocksMigration', 'data': { 'path': %s, 'tag': %s } }"
+ ERROR_CLASS_GENERIC_ERROR, "Migration is disabled when VirtFS export path '%s' is mounted in the guest using mount_tag '%s'"
#define QERR_VNC_SERVER_FAILED \
- "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }"
-
-#define QERR_SOCKET_CONNECT_IN_PROGRESS \
- "{ 'class': 'SockConnectInprogress', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Could not start VNC server on %s"
#define QERR_SOCKET_CONNECT_FAILED \
- "{ 'class': 'SockConnectFailed', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Failed to connect to socket"
#define QERR_SOCKET_LISTEN_FAILED \
- "{ 'class': 'SockListenFailed', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Failed to set socket to listening mode"
#define QERR_SOCKET_BIND_FAILED \
- "{ 'class': 'SockBindFailed', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Failed to bind socket"
#define QERR_SOCKET_CREATE_FAILED \
- "{ 'class': 'SockCreateFailed', 'data': {} }"
+ ERROR_CLASS_GENERIC_ERROR, "Failed to create socket"
#endif /* QERROR_H */
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ac46638..527b9f7 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -435,8 +435,8 @@
-> { "execute": "inject-nmi" }
<- { "return": {} }
-Note: inject-nmi is only supported for x86 guest currently, it will
- returns "Unsupported" error for non-x86 guest.
+Note: inject-nmi fails when the guest doesn't support injecting.
+ Currently, only x86 guests do.
EQMP
@@ -520,6 +520,50 @@
<- { "return": {} }
EQMP
+{
+ .name = "migrate-set-cache-size",
+ .args_type = "value:o",
+ .mhandler.cmd_new = qmp_marshal_input_migrate_set_cache_size,
+ },
+
+SQMP
+migrate-set-cache-size
+---------------------
+
+Set cache size to be used by XBZRLE migration, the cache size will be rounded
+down to the nearest power of 2
+
+Arguments:
+
+- "value": cache size in bytes (json-int)
+
+Example:
+
+-> { "execute": "migrate-set-cache-size", "arguments": { "value": 536870912 } }
+<- { "return": {} }
+
+EQMP
+ {
+ .name = "query-migrate-cache-size",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_migrate_cache_size,
+ },
+
+SQMP
+query-migrate-cache-size
+---------------------
+
+Show cache size to be used by XBZRLE migration
+
+returns a json-object with the following information:
+- "size" : json-int
+
+Example:
+
+-> { "execute": "query-migrate-cache-size" }
+<- { "return": 67108864 }
+
+EQMP
{
.name = "migrate_set_speed",
@@ -2078,12 +2122,24 @@
- "transferred": amount transferred (json-int)
- "remaining": amount remaining (json-int)
- "total": total (json-int)
+ - "total-time": total amount of ms since migration started. If
+ migration has ended, it returns the total migration time
+ (json-int)
+ - "duplicate": number of duplicated pages (json-int)
+ - "normal" : number of normal pages transferred (json-int)
+ - "normal-bytes" : number of normal bytes transferred (json-int)
- "disk": only present if "status" is "active" and it is a block migration,
it is a json-object with the following disk information (in bytes):
- "transferred": amount transferred (json-int)
- "remaining": amount remaining (json-int)
- "total": total (json-int)
-
+- "xbzrle-cache": only present if XBZRLE is active.
+ It is a json-object with the following XBZRLE information:
+ - "cache-size": XBZRLE cache size
+ - "bytes": total XBZRLE bytes transferred
+ - "pages": number of XBZRLE compressed pages
+ - "cache-miss": number of cache misses
+ - "overflow": number of XBZRLE overflows
Examples:
1. Before the first migration
@@ -2094,7 +2150,19 @@
2. Migration is done and has succeeded
-> { "execute": "query-migrate" }
-<- { "return": { "status": "completed" } }
+<- { "return": {
+ "status": "completed",
+ "ram":{
+ "transferred":123,
+ "remaining":123,
+ "total":246,
+ "total-time":12345,
+ "duplicate":123,
+ "normal":123,
+ "normal-bytes":123456
+ }
+ }
+ }
3. Migration is done and has failed
@@ -2110,7 +2178,11 @@
"ram":{
"transferred":123,
"remaining":123,
- "total":246
+ "total":246,
+ "total-time":12345,
+ "duplicate":123,
+ "normal":123,
+ "normal-bytes":123456
}
}
}
@@ -2124,7 +2196,11 @@
"ram":{
"total":1057024,
"remaining":1053304,
- "transferred":3720
+ "transferred":3720,
+ "total-time":12345,
+ "duplicate":123,
+ "normal":123,
+ "normal-bytes":123456
},
"disk":{
"total":20971520,
@@ -2134,6 +2210,32 @@
}
}
+6. Migration is being performed and XBZRLE is active:
+
+-> { "execute": "query-migrate" }
+<- {
+ "return":{
+ "status":"active",
+ "capabilities" : [ { "capability": "xbzrle", "state" : true } ],
+ "ram":{
+ "total":1057024,
+ "remaining":1053304,
+ "transferred":3720,
+ "total-time":12345,
+ "duplicate":10,
+ "normal":3333,
+ "normal-bytes":3412992
+ },
+ "xbzrle-cache":{
+ "cache-size":67108864,
+ "bytes":20971520,
+ "pages":2444343,
+ "cache-miss":2244,
+ "overflow":34434
+ }
+ }
+ }
+
EQMP
{
@@ -2143,6 +2245,55 @@
},
SQMP
+migrate-set-capabilities
+-------
+
+Enable/Disable migration capabilities
+
+- "xbzrle": xbzrle support
+
+Arguments:
+
+Example:
+
+-> { "execute": "migrate-set-capabilities" , "arguments":
+ { "capabilities": [ { "capability": "xbzrle", "state": true } ] } }
+
+EQMP
+
+ {
+ .name = "migrate-set-capabilities",
+ .args_type = "capabilities:O",
+ .params = "capability:s,state:b",
+ .mhandler.cmd_new = qmp_marshal_input_migrate_set_capabilities,
+ },
+SQMP
+query-migrate-capabilities
+-------
+
+Query current migration capabilities
+
+- "capabilities": migration capabilities state
+ - "xbzrle" : XBZRLE state (json-bool)
+
+Arguments:
+
+Example:
+
+-> { "execute": "query-migrate-capabilities" }
+<- { "return": {
+ "capabilities" : [ { "capability" : "xbzrle", "state" : false } ]
+ }
+ }
+EQMP
+
+ {
+ .name = "query-migrate-capabilities",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_migrate_capabilities,
+ },
+
+SQMP
query-balloon
-------------
@@ -2217,3 +2368,22 @@
.args_type = "implements:s?,abstract:b?",
.mhandler.cmd_new = qmp_marshal_input_qom_list_types,
},
+
+ {
+ .name = "device-list-properties",
+ .args_type = "typename:s",
+ .mhandler.cmd_new = qmp_marshal_input_device_list_properties,
+ },
+
+ {
+ .name = "query-machines",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_machines,
+ },
+
+ {
+ .name = "query-cpu-definitions",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_cpu_definitions,
+ },
+
diff --git a/qmp.c b/qmp.c
index fee9fb2..6c1e4e8 100644
--- a/qmp.c
+++ b/qmp.c
@@ -417,3 +417,59 @@
return ret;
}
+
+DevicePropertyInfoList *qmp_device_list_properties(const char *typename,
+ Error **errp)
+{
+ ObjectClass *klass;
+ Property *prop;
+ DevicePropertyInfoList *prop_list = NULL;
+
+ klass = object_class_by_name(typename);
+ if (klass == NULL) {
+ error_set(errp, QERR_DEVICE_NOT_FOUND, typename);
+ return NULL;
+ }
+
+ klass = object_class_dynamic_cast(klass, TYPE_DEVICE);
+ if (klass == NULL) {
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+ "name", TYPE_DEVICE);
+ return NULL;
+ }
+
+ do {
+ for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) {
+ DevicePropertyInfoList *entry;
+ DevicePropertyInfo *info;
+
+ /*
+ * TODO Properties without a parser are just for dirty hacks.
+ * qdev_prop_ptr is the only such PropertyInfo. It's marked
+ * for removal. This conditional should be removed along with
+ * it.
+ */
+ if (!prop->info->set) {
+ continue; /* no way to set it, don't show */
+ }
+
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strdup(prop->name);
+ info->type = g_strdup(prop->info->legacy_name ?: prop->info->name);
+
+ entry = g_malloc0(sizeof(*entry));
+ entry->value = info;
+ entry->next = prop_list;
+ prop_list = entry;
+ }
+ klass = object_class_get_parent(klass);
+ } while (klass != object_class_by_name(TYPE_DEVICE));
+
+ return prop_list;
+}
+
+CpuDefinitionInfoList GCC_WEAK *qmp_query_cpu_definitions(Error **errp)
+{
+ error_set(errp, QERR_NOT_SUPPORTED);
+ return NULL;
+}
diff --git a/savevm.c b/savevm.c
index 6e82b2d..0ea10c9 100644
--- a/savevm.c
+++ b/savevm.c
@@ -2392,3 +2392,162 @@
{
vmstate_register_ram(mr, NULL);
}
+
+/*
+ page = zrun nzrun
+ | zrun nzrun page
+
+ zrun = length
+
+ nzrun = length byte...
+
+ length = uleb128 encoded integer
+ */
+int xbzrle_encode_buffer(uint8_t *old_buf, uint8_t *new_buf, int slen,
+ uint8_t *dst, int dlen)
+{
+ uint32_t zrun_len = 0, nzrun_len = 0;
+ int d = 0, i = 0;
+ long res, xor;
+ uint8_t *nzrun_start = NULL;
+
+ g_assert(!(((uintptr_t)old_buf | (uintptr_t)new_buf | slen) %
+ sizeof(long)));
+
+ while (i < slen) {
+ /* overflow */
+ if (d + 2 > dlen) {
+ return -1;
+ }
+
+ /* not aligned to sizeof(long) */
+ res = (slen - i) % sizeof(long);
+ while (res && old_buf[i] == new_buf[i]) {
+ zrun_len++;
+ i++;
+ res--;
+ }
+
+ /* word at a time for speed */
+ if (!res) {
+ while (i < slen &&
+ (*(long *)(old_buf + i)) == (*(long *)(new_buf + i))) {
+ i += sizeof(long);
+ zrun_len += sizeof(long);
+ }
+
+ /* go over the rest */
+ while (i < slen && old_buf[i] == new_buf[i]) {
+ zrun_len++;
+ i++;
+ }
+ }
+
+ /* buffer unchanged */
+ if (zrun_len == slen) {
+ return 0;
+ }
+
+ /* skip last zero run */
+ if (i == slen) {
+ return d;
+ }
+
+ d += uleb128_encode_small(dst + d, zrun_len);
+
+ zrun_len = 0;
+ nzrun_start = new_buf + i;
+
+ /* overflow */
+ if (d + 2 > dlen) {
+ return -1;
+ }
+ /* not aligned to sizeof(long) */
+ res = (slen - i) % sizeof(long);
+ while (res && old_buf[i] != new_buf[i]) {
+ i++;
+ nzrun_len++;
+ res--;
+ }
+
+ /* word at a time for speed, use of 32-bit long okay */
+ if (!res) {
+ /* truncation to 32-bit long okay */
+ long mask = 0x0101010101010101ULL;
+ while (i < slen) {
+ xor = *(long *)(old_buf + i) ^ *(long *)(new_buf + i);
+ if ((xor - mask) & ~xor & (mask << 7)) {
+ /* found the end of an nzrun within the current long */
+ while (old_buf[i] != new_buf[i]) {
+ nzrun_len++;
+ i++;
+ }
+ break;
+ } else {
+ i += sizeof(long);
+ nzrun_len += sizeof(long);
+ }
+ }
+ }
+
+ d += uleb128_encode_small(dst + d, nzrun_len);
+ /* overflow */
+ if (d + nzrun_len > dlen) {
+ return -1;
+ }
+ memcpy(dst + d, nzrun_start, nzrun_len);
+ d += nzrun_len;
+ nzrun_len = 0;
+ }
+
+ return d;
+}
+
+int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen)
+{
+ int i = 0, d = 0;
+ int ret;
+ uint32_t count = 0;
+
+ while (i < slen) {
+
+ /* zrun */
+ if ((slen - i) < 2) {
+ return -1;
+ }
+
+ ret = uleb128_decode_small(src + i, &count);
+ if (ret < 0 || (i && !count)) {
+ return -1;
+ }
+ i += ret;
+ d += count;
+
+ /* overflow */
+ if (d > dlen) {
+ return -1;
+ }
+
+ /* nzrun */
+ if ((slen - i) < 2) {
+ return -1;
+ }
+
+ ret = uleb128_decode_small(src + i, &count);
+ if (ret < 0 || !count) {
+ return -1;
+ }
+ i += ret;
+
+ /* overflow */
+ if (d + count > dlen || i + count > slen) {
+ return -1;
+ }
+
+ memcpy(dst + d, src + i, count);
+ d += count;
+ i += count;
+ }
+
+ return d;
+}
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 9eed40e..3c4678d 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -342,6 +342,7 @@
#define %(guard)s
#include "%(prefix)sqapi-types.h"
+#include "qdict.h"
#include "error.h"
''',
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 4a734f5..cf601ae 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -70,7 +70,7 @@
ret += mcgen('''
"%(value)s",
''',
- value=value.lower())
+ value=value)
ret += mcgen('''
NULL,
@@ -79,6 +79,16 @@
''')
return ret
+def generate_enum_name(name):
+ if name.isupper():
+ return c_fun(name)
+ new_name = ''
+ for c in c_fun(name):
+ if c.isupper():
+ new_name += '_'
+ new_name += c
+ return new_name.lstrip('_').upper()
+
def generate_enum(name, values):
lookup_decl = mcgen('''
extern const char *%(name)s_lookup[];
@@ -100,7 +110,7 @@
%(abbrev)s_%(value)s = %(i)d,
''',
abbrev=de_camel_case(name).upper(),
- value=c_fun(value).upper(),
+ value=generate_enum_name(value),
i=i)
i += 1
@@ -253,7 +263,8 @@
#ifndef %(guard)s
#define %(guard)s
-#include "qapi/qapi-types-core.h"
+#include "qemu-common.h"
+
''',
guard=guardname(h_file)))
diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs
index 683fd59..c1d4f05 100644
--- a/target-i386/Makefile.objs
+++ b/target-i386/Makefile.objs
@@ -3,14 +3,6 @@
obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o
obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
obj-$(CONFIG_KVM) += kvm.o hyperv.o
+obj-$(CONFIG_NO_KVM) += kvm-stub.o
obj-$(CONFIG_LINUX_USER) += ioport-user.o
obj-$(CONFIG_BSD_USER) += ioport-user.o
-
-$(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
-$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
-$(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
-$(obj)/svm_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
-$(obj)/smm_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
-$(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
-$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
-$(obj)/seg_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target-i386/cc_helper.c b/target-i386/cc_helper.c
index ff654bc..07892f9 100644
--- a/target-i386/cc_helper.c
+++ b/target-i386/cc_helper.c
@@ -18,7 +18,6 @@
*/
#include "cpu.h"
-#include "dyngen-exec.h"
#include "helper.h"
const uint8_t parity_table[256] = {
@@ -76,184 +75,177 @@
#endif
-static int compute_all_eflags(void)
+static int compute_all_eflags(CPUX86State *env)
{
return CC_SRC;
}
-static int compute_c_eflags(void)
+static int compute_c_eflags(CPUX86State *env)
{
return CC_SRC & CC_C;
}
-uint32_t helper_cc_compute_all(int op)
+uint32_t helper_cc_compute_all(CPUX86State *env, int op)
{
switch (op) {
default: /* should never happen */
return 0;
case CC_OP_EFLAGS:
- return compute_all_eflags();
+ return compute_all_eflags(env);
case CC_OP_MULB:
- return compute_all_mulb();
+ return compute_all_mulb(env);
case CC_OP_MULW:
- return compute_all_mulw();
+ return compute_all_mulw(env);
case CC_OP_MULL:
- return compute_all_mull();
+ return compute_all_mull(env);
case CC_OP_ADDB:
- return compute_all_addb();
+ return compute_all_addb(env);
case CC_OP_ADDW:
- return compute_all_addw();
+ return compute_all_addw(env);
case CC_OP_ADDL:
- return compute_all_addl();
+ return compute_all_addl(env);
case CC_OP_ADCB:
- return compute_all_adcb();
+ return compute_all_adcb(env);
case CC_OP_ADCW:
- return compute_all_adcw();
+ return compute_all_adcw(env);
case CC_OP_ADCL:
- return compute_all_adcl();
+ return compute_all_adcl(env);
case CC_OP_SUBB:
- return compute_all_subb();
+ return compute_all_subb(env);
case CC_OP_SUBW:
- return compute_all_subw();
+ return compute_all_subw(env);
case CC_OP_SUBL:
- return compute_all_subl();
+ return compute_all_subl(env);
case CC_OP_SBBB:
- return compute_all_sbbb();
+ return compute_all_sbbb(env);
case CC_OP_SBBW:
- return compute_all_sbbw();
+ return compute_all_sbbw(env);
case CC_OP_SBBL:
- return compute_all_sbbl();
+ return compute_all_sbbl(env);
case CC_OP_LOGICB:
- return compute_all_logicb();
+ return compute_all_logicb(env);
case CC_OP_LOGICW:
- return compute_all_logicw();
+ return compute_all_logicw(env);
case CC_OP_LOGICL:
- return compute_all_logicl();
+ return compute_all_logicl(env);
case CC_OP_INCB:
- return compute_all_incb();
+ return compute_all_incb(env);
case CC_OP_INCW:
- return compute_all_incw();
+ return compute_all_incw(env);
case CC_OP_INCL:
- return compute_all_incl();
+ return compute_all_incl(env);
case CC_OP_DECB:
- return compute_all_decb();
+ return compute_all_decb(env);
case CC_OP_DECW:
- return compute_all_decw();
+ return compute_all_decw(env);
case CC_OP_DECL:
- return compute_all_decl();
+ return compute_all_decl(env);
case CC_OP_SHLB:
- return compute_all_shlb();
+ return compute_all_shlb(env);
case CC_OP_SHLW:
- return compute_all_shlw();
+ return compute_all_shlw(env);
case CC_OP_SHLL:
- return compute_all_shll();
+ return compute_all_shll(env);
case CC_OP_SARB:
- return compute_all_sarb();
+ return compute_all_sarb(env);
case CC_OP_SARW:
- return compute_all_sarw();
+ return compute_all_sarw(env);
case CC_OP_SARL:
- return compute_all_sarl();
+ return compute_all_sarl(env);
#ifdef TARGET_X86_64
case CC_OP_MULQ:
- return compute_all_mulq();
+ return compute_all_mulq(env);
case CC_OP_ADDQ:
- return compute_all_addq();
+ return compute_all_addq(env);
case CC_OP_ADCQ:
- return compute_all_adcq();
+ return compute_all_adcq(env);
case CC_OP_SUBQ:
- return compute_all_subq();
+ return compute_all_subq(env);
case CC_OP_SBBQ:
- return compute_all_sbbq();
+ return compute_all_sbbq(env);
case CC_OP_LOGICQ:
- return compute_all_logicq();
+ return compute_all_logicq(env);
case CC_OP_INCQ:
- return compute_all_incq();
+ return compute_all_incq(env);
case CC_OP_DECQ:
- return compute_all_decq();
+ return compute_all_decq(env);
case CC_OP_SHLQ:
- return compute_all_shlq();
+ return compute_all_shlq(env);
case CC_OP_SARQ:
- return compute_all_sarq();
+ return compute_all_sarq(env);
#endif
}
}
-uint32_t cpu_cc_compute_all(CPUX86State *env1, int op)
+uint32_t cpu_cc_compute_all(CPUX86State *env, int op)
{
- CPUX86State *saved_env;
- uint32_t ret;
-
- saved_env = env;
- env = env1;
- ret = helper_cc_compute_all(op);
- env = saved_env;
- return ret;
+ return helper_cc_compute_all(env, op);
}
-uint32_t helper_cc_compute_c(int op)
+uint32_t helper_cc_compute_c(CPUX86State *env, int op)
{
switch (op) {
default: /* should never happen */
return 0;
case CC_OP_EFLAGS:
- return compute_c_eflags();
+ return compute_c_eflags(env);
case CC_OP_MULB:
- return compute_c_mull();
+ return compute_c_mull(env);
case CC_OP_MULW:
- return compute_c_mull();
+ return compute_c_mull(env);
case CC_OP_MULL:
- return compute_c_mull();
+ return compute_c_mull(env);
case CC_OP_ADDB:
- return compute_c_addb();
+ return compute_c_addb(env);
case CC_OP_ADDW:
- return compute_c_addw();
+ return compute_c_addw(env);
case CC_OP_ADDL:
- return compute_c_addl();
+ return compute_c_addl(env);
case CC_OP_ADCB:
- return compute_c_adcb();
+ return compute_c_adcb(env);
case CC_OP_ADCW:
- return compute_c_adcw();
+ return compute_c_adcw(env);
case CC_OP_ADCL:
- return compute_c_adcl();
+ return compute_c_adcl(env);
case CC_OP_SUBB:
- return compute_c_subb();
+ return compute_c_subb(env);
case CC_OP_SUBW:
- return compute_c_subw();
+ return compute_c_subw(env);
case CC_OP_SUBL:
- return compute_c_subl();
+ return compute_c_subl(env);
case CC_OP_SBBB:
- return compute_c_sbbb();
+ return compute_c_sbbb(env);
case CC_OP_SBBW:
- return compute_c_sbbw();
+ return compute_c_sbbw(env);
case CC_OP_SBBL:
- return compute_c_sbbl();
+ return compute_c_sbbl(env);
case CC_OP_LOGICB:
return compute_c_logicb();
@@ -263,111 +255,112 @@
return compute_c_logicl();
case CC_OP_INCB:
- return compute_c_incl();
+ return compute_c_incl(env);
case CC_OP_INCW:
- return compute_c_incl();
+ return compute_c_incl(env);
case CC_OP_INCL:
- return compute_c_incl();
+ return compute_c_incl(env);
case CC_OP_DECB:
- return compute_c_incl();
+ return compute_c_incl(env);
case CC_OP_DECW:
- return compute_c_incl();
+ return compute_c_incl(env);
case CC_OP_DECL:
- return compute_c_incl();
+ return compute_c_incl(env);
case CC_OP_SHLB:
- return compute_c_shlb();
+ return compute_c_shlb(env);
case CC_OP_SHLW:
- return compute_c_shlw();
+ return compute_c_shlw(env);
case CC_OP_SHLL:
- return compute_c_shll();
+ return compute_c_shll(env);
case CC_OP_SARB:
- return compute_c_sarl();
+ return compute_c_sarl(env);
case CC_OP_SARW:
- return compute_c_sarl();
+ return compute_c_sarl(env);
case CC_OP_SARL:
- return compute_c_sarl();
+ return compute_c_sarl(env);
#ifdef TARGET_X86_64
case CC_OP_MULQ:
- return compute_c_mull();
+ return compute_c_mull(env);
case CC_OP_ADDQ:
- return compute_c_addq();
+ return compute_c_addq(env);
case CC_OP_ADCQ:
- return compute_c_adcq();
+ return compute_c_adcq(env);
case CC_OP_SUBQ:
- return compute_c_subq();
+ return compute_c_subq(env);
case CC_OP_SBBQ:
- return compute_c_sbbq();
+ return compute_c_sbbq(env);
case CC_OP_LOGICQ:
return compute_c_logicq();
case CC_OP_INCQ:
- return compute_c_incl();
+ return compute_c_incl(env);
case CC_OP_DECQ:
- return compute_c_incl();
+ return compute_c_incl(env);
case CC_OP_SHLQ:
- return compute_c_shlq();
+ return compute_c_shlq(env);
case CC_OP_SARQ:
- return compute_c_sarl();
+ return compute_c_sarl(env);
#endif
}
}
-void helper_write_eflags(target_ulong t0, uint32_t update_mask)
+void helper_write_eflags(CPUX86State *env, target_ulong t0,
+ uint32_t update_mask)
{
cpu_load_eflags(env, t0, update_mask);
}
-target_ulong helper_read_eflags(void)
+target_ulong helper_read_eflags(CPUX86State *env)
{
uint32_t eflags;
- eflags = helper_cc_compute_all(CC_OP);
+ eflags = helper_cc_compute_all(env, CC_OP);
eflags |= (DF & DF_MASK);
eflags |= env->eflags & ~(VM_MASK | RF_MASK);
return eflags;
}
-void helper_clts(void)
+void helper_clts(CPUX86State *env)
{
env->cr[0] &= ~CR0_TS_MASK;
env->hflags &= ~HF_TS_MASK;
}
-void helper_reset_rf(void)
+void helper_reset_rf(CPUX86State *env)
{
env->eflags &= ~RF_MASK;
}
-void helper_cli(void)
+void helper_cli(CPUX86State *env)
{
env->eflags &= ~IF_MASK;
}
-void helper_sti(void)
+void helper_sti(CPUX86State *env)
{
env->eflags |= IF_MASK;
}
#if 0
/* vm86plus instructions */
-void helper_cli_vm(void)
+void helper_cli_vm(CPUX86State *env)
{
env->eflags &= ~VIF_MASK;
}
-void helper_sti_vm(void)
+void helper_sti_vm(CPUX86State *env)
{
env->eflags |= VIF_MASK;
if (env->eflags & VIP_MASK) {
@@ -376,12 +369,12 @@
}
#endif
-void helper_set_inhibit_irq(void)
+void helper_set_inhibit_irq(CPUX86State *env)
{
env->hflags |= HF_INHIBIT_IRQ_MASK;
}
-void helper_reset_inhibit_irq(void)
+void helper_reset_inhibit_irq(CPUX86State *env)
{
env->hflags &= ~HF_INHIBIT_IRQ_MASK;
}
diff --git a/target-i386/cc_helper_template.h b/target-i386/cc_helper_template.h
index ff22830..1f94e11 100644
--- a/target-i386/cc_helper_template.h
+++ b/target-i386/cc_helper_template.h
@@ -42,7 +42,7 @@
/* dynamic flags computation */
-static int glue(compute_all_add, SUFFIX)(void)
+static int glue(compute_all_add, SUFFIX)(CPUX86State *env)
{
int cf, pf, af, zf, sf, of;
target_long src1, src2;
@@ -58,7 +58,7 @@
return cf | pf | af | zf | sf | of;
}
-static int glue(compute_c_add, SUFFIX)(void)
+static int glue(compute_c_add, SUFFIX)(CPUX86State *env)
{
int cf;
target_long src1;
@@ -68,7 +68,7 @@
return cf;
}
-static int glue(compute_all_adc, SUFFIX)(void)
+static int glue(compute_all_adc, SUFFIX)(CPUX86State *env)
{
int cf, pf, af, zf, sf, of;
target_long src1, src2;
@@ -84,7 +84,7 @@
return cf | pf | af | zf | sf | of;
}
-static int glue(compute_c_adc, SUFFIX)(void)
+static int glue(compute_c_adc, SUFFIX)(CPUX86State *env)
{
int cf;
target_long src1;
@@ -94,7 +94,7 @@
return cf;
}
-static int glue(compute_all_sub, SUFFIX)(void)
+static int glue(compute_all_sub, SUFFIX)(CPUX86State *env)
{
int cf, pf, af, zf, sf, of;
target_long src1, src2;
@@ -110,7 +110,7 @@
return cf | pf | af | zf | sf | of;
}
-static int glue(compute_c_sub, SUFFIX)(void)
+static int glue(compute_c_sub, SUFFIX)(CPUX86State *env)
{
int cf;
target_long src1, src2;
@@ -121,7 +121,7 @@
return cf;
}
-static int glue(compute_all_sbb, SUFFIX)(void)
+static int glue(compute_all_sbb, SUFFIX)(CPUX86State *env)
{
int cf, pf, af, zf, sf, of;
target_long src1, src2;
@@ -137,7 +137,7 @@
return cf | pf | af | zf | sf | of;
}
-static int glue(compute_c_sbb, SUFFIX)(void)
+static int glue(compute_c_sbb, SUFFIX)(CPUX86State *env)
{
int cf;
target_long src1, src2;
@@ -148,7 +148,7 @@
return cf;
}
-static int glue(compute_all_logic, SUFFIX)(void)
+static int glue(compute_all_logic, SUFFIX)(CPUX86State *env)
{
int cf, pf, af, zf, sf, of;
@@ -166,7 +166,7 @@
return 0;
}
-static int glue(compute_all_inc, SUFFIX)(void)
+static int glue(compute_all_inc, SUFFIX)(CPUX86State *env)
{
int cf, pf, af, zf, sf, of;
target_long src1, src2;
@@ -183,13 +183,13 @@
}
#if DATA_BITS == 32
-static int glue(compute_c_inc, SUFFIX)(void)
+static int glue(compute_c_inc, SUFFIX)(CPUX86State *env)
{
return CC_SRC;
}
#endif
-static int glue(compute_all_dec, SUFFIX)(void)
+static int glue(compute_all_dec, SUFFIX)(CPUX86State *env)
{
int cf, pf, af, zf, sf, of;
target_long src1, src2;
@@ -205,7 +205,7 @@
return cf | pf | af | zf | sf | of;
}
-static int glue(compute_all_shl, SUFFIX)(void)
+static int glue(compute_all_shl, SUFFIX)(CPUX86State *env)
{
int cf, pf, af, zf, sf, of;
@@ -219,19 +219,19 @@
return cf | pf | af | zf | sf | of;
}
-static int glue(compute_c_shl, SUFFIX)(void)
+static int glue(compute_c_shl, SUFFIX)(CPUX86State *env)
{
return (CC_SRC >> (DATA_BITS - 1)) & CC_C;
}
#if DATA_BITS == 32
-static int glue(compute_c_sar, SUFFIX)(void)
+static int glue(compute_c_sar, SUFFIX)(CPUX86State *env)
{
return CC_SRC & 1;
}
#endif
-static int glue(compute_all_sar, SUFFIX)(void)
+static int glue(compute_all_sar, SUFFIX)(CPUX86State *env)
{
int cf, pf, af, zf, sf, of;
@@ -246,7 +246,7 @@
}
#if DATA_BITS == 32
-static int glue(compute_c_mul, SUFFIX)(void)
+static int glue(compute_c_mul, SUFFIX)(CPUX86State *env)
{
int cf;
@@ -257,7 +257,7 @@
/* NOTE: we compute the flags like the P4. On olders CPUs, only OF and
CF are modified and it is slower to do that. */
-static int glue(compute_all_mul, SUFFIX)(void)
+static int glue(compute_all_mul, SUFFIX)(CPUX86State *env)
{
int cf, pf, af, zf, sf, of;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 880cfea..6d5d0d6 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -28,6 +28,7 @@
#include "qemu-config.h"
#include "qapi/qapi-visit-core.h"
+#include "qmp-commands.h"
#include "hyperv.h"
@@ -1125,6 +1126,27 @@
}
}
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+ CpuDefinitionInfoList *cpu_list = NULL;
+ x86_def_t *def;
+
+ for (def = x86_defs; def; def = def->next) {
+ CpuDefinitionInfoList *entry;
+ CpuDefinitionInfo *info;
+
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strdup(def->name);
+
+ entry = g_malloc0(sizeof(*entry));
+ entry->value = info;
+ entry->next = cpu_list;
+ cpu_list = entry;
+ }
+
+ return cpu_list;
+}
+
int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
{
CPUX86State *env = &cpu->env;
diff --git a/target-i386/fpu_helper.c b/target-i386/fpu_helper.c
index 6065c2e..dfc34a6 100644
--- a/target-i386/fpu_helper.c
+++ b/target-i386/fpu_helper.c
@@ -19,7 +19,6 @@
#include <math.h>
#include "cpu.h"
-#include "dyngen-exec.h"
#include "helper.h"
#if !defined(CONFIG_USER_ONLY)
@@ -58,39 +57,39 @@
#define floatx80_l2e make_floatx80(0x3fff, 0xb8aa3b295c17f0bcLL)
#define floatx80_l2t make_floatx80(0x4000, 0xd49a784bcd1b8afeLL)
-static inline void fpush(void)
+static inline void fpush(CPUX86State *env)
{
env->fpstt = (env->fpstt - 1) & 7;
env->fptags[env->fpstt] = 0; /* validate stack entry */
}
-static inline void fpop(void)
+static inline void fpop(CPUX86State *env)
{
env->fptags[env->fpstt] = 1; /* invalidate stack entry */
env->fpstt = (env->fpstt + 1) & 7;
}
-static inline floatx80 helper_fldt(target_ulong ptr)
+static inline floatx80 helper_fldt(CPUX86State *env, target_ulong ptr)
{
CPU_LDoubleU temp;
- temp.l.lower = ldq(ptr);
- temp.l.upper = lduw(ptr + 8);
+ temp.l.lower = cpu_ldq_data(env, ptr);
+ temp.l.upper = cpu_lduw_data(env, ptr + 8);
return temp.d;
}
-static inline void helper_fstt(floatx80 f, target_ulong ptr)
+static inline void helper_fstt(CPUX86State *env, floatx80 f, target_ulong ptr)
{
CPU_LDoubleU temp;
temp.d = f;
- stq(ptr, temp.l.lower);
- stw(ptr + 8, temp.l.upper);
+ cpu_stq_data(env, ptr, temp.l.lower);
+ cpu_stw_data(env, ptr + 8, temp.l.upper);
}
/* x87 FPU helpers */
-static inline double floatx80_to_double(floatx80 a)
+static inline double floatx80_to_double(CPUX86State *env, floatx80 a)
{
union {
float64 f64;
@@ -101,7 +100,7 @@
return u.d;
}
-static inline floatx80 double_to_floatx80(double a)
+static inline floatx80 double_to_floatx80(CPUX86State *env, double a)
{
union {
float64 f64;
@@ -112,7 +111,7 @@
return float64_to_floatx80(u.f64, &env->fp_status);
}
-static void fpu_set_exception(int mask)
+static void fpu_set_exception(CPUX86State *env, int mask)
{
env->fpus |= mask;
if (env->fpus & (~env->fpuc & FPUC_EM)) {
@@ -120,15 +119,15 @@
}
}
-static inline floatx80 helper_fdiv(floatx80 a, floatx80 b)
+static inline floatx80 helper_fdiv(CPUX86State *env, floatx80 a, floatx80 b)
{
if (floatx80_is_zero(b)) {
- fpu_set_exception(FPUS_ZE);
+ fpu_set_exception(env, FPUS_ZE);
}
return floatx80_div(a, b, &env->fp_status);
}
-static void fpu_raise_exception(void)
+static void fpu_raise_exception(CPUX86State *env)
{
if (env->cr[0] & CR0_NE_MASK) {
raise_exception(env, EXCP10_COPR);
@@ -140,7 +139,7 @@
#endif
}
-void helper_flds_FT0(uint32_t val)
+void helper_flds_FT0(CPUX86State *env, uint32_t val)
{
union {
float32 f;
@@ -151,7 +150,7 @@
FT0 = float32_to_floatx80(u.f, &env->fp_status);
}
-void helper_fldl_FT0(uint64_t val)
+void helper_fldl_FT0(CPUX86State *env, uint64_t val)
{
union {
float64 f;
@@ -162,12 +161,12 @@
FT0 = float64_to_floatx80(u.f, &env->fp_status);
}
-void helper_fildl_FT0(int32_t val)
+void helper_fildl_FT0(CPUX86State *env, int32_t val)
{
FT0 = int32_to_floatx80(val, &env->fp_status);
}
-void helper_flds_ST0(uint32_t val)
+void helper_flds_ST0(CPUX86State *env, uint32_t val)
{
int new_fpstt;
union {
@@ -182,7 +181,7 @@
env->fptags[new_fpstt] = 0; /* validate stack entry */
}
-void helper_fldl_ST0(uint64_t val)
+void helper_fldl_ST0(CPUX86State *env, uint64_t val)
{
int new_fpstt;
union {
@@ -197,7 +196,7 @@
env->fptags[new_fpstt] = 0; /* validate stack entry */
}
-void helper_fildl_ST0(int32_t val)
+void helper_fildl_ST0(CPUX86State *env, int32_t val)
{
int new_fpstt;
@@ -207,7 +206,7 @@
env->fptags[new_fpstt] = 0; /* validate stack entry */
}
-void helper_fildll_ST0(int64_t val)
+void helper_fildll_ST0(CPUX86State *env, int64_t val)
{
int new_fpstt;
@@ -217,7 +216,7 @@
env->fptags[new_fpstt] = 0; /* validate stack entry */
}
-uint32_t helper_fsts_ST0(void)
+uint32_t helper_fsts_ST0(CPUX86State *env)
{
union {
float32 f;
@@ -228,7 +227,7 @@
return u.i;
}
-uint64_t helper_fstl_ST0(void)
+uint64_t helper_fstl_ST0(CPUX86State *env)
{
union {
float64 f;
@@ -239,7 +238,7 @@
return u.i;
}
-int32_t helper_fist_ST0(void)
+int32_t helper_fist_ST0(CPUX86State *env)
{
int32_t val;
@@ -250,7 +249,7 @@
return val;
}
-int32_t helper_fistl_ST0(void)
+int32_t helper_fistl_ST0(CPUX86State *env)
{
int32_t val;
@@ -258,7 +257,7 @@
return val;
}
-int64_t helper_fistll_ST0(void)
+int64_t helper_fistll_ST0(CPUX86State *env)
{
int64_t val;
@@ -266,7 +265,7 @@
return val;
}
-int32_t helper_fistt_ST0(void)
+int32_t helper_fistt_ST0(CPUX86State *env)
{
int32_t val;
@@ -277,7 +276,7 @@
return val;
}
-int32_t helper_fisttl_ST0(void)
+int32_t helper_fisttl_ST0(CPUX86State *env)
{
int32_t val;
@@ -285,7 +284,7 @@
return val;
}
-int64_t helper_fisttll_ST0(void)
+int64_t helper_fisttll_ST0(CPUX86State *env)
{
int64_t val;
@@ -293,38 +292,38 @@
return val;
}
-void helper_fldt_ST0(target_ulong ptr)
+void helper_fldt_ST0(CPUX86State *env, target_ulong ptr)
{
int new_fpstt;
new_fpstt = (env->fpstt - 1) & 7;
- env->fpregs[new_fpstt].d = helper_fldt(ptr);
+ env->fpregs[new_fpstt].d = helper_fldt(env, ptr);
env->fpstt = new_fpstt;
env->fptags[new_fpstt] = 0; /* validate stack entry */
}
-void helper_fstt_ST0(target_ulong ptr)
+void helper_fstt_ST0(CPUX86State *env, target_ulong ptr)
{
- helper_fstt(ST0, ptr);
+ helper_fstt(env, ST0, ptr);
}
-void helper_fpush(void)
+void helper_fpush(CPUX86State *env)
{
- fpush();
+ fpush(env);
}
-void helper_fpop(void)
+void helper_fpop(CPUX86State *env)
{
- fpop();
+ fpop(env);
}
-void helper_fdecstp(void)
+void helper_fdecstp(CPUX86State *env)
{
env->fpstt = (env->fpstt - 1) & 7;
env->fpus &= ~0x4700;
}
-void helper_fincstp(void)
+void helper_fincstp(CPUX86State *env)
{
env->fpstt = (env->fpstt + 1) & 7;
env->fpus &= ~0x4700;
@@ -332,32 +331,32 @@
/* FPU move */
-void helper_ffree_STN(int st_index)
+void helper_ffree_STN(CPUX86State *env, int st_index)
{
env->fptags[(env->fpstt + st_index) & 7] = 1;
}
-void helper_fmov_ST0_FT0(void)
+void helper_fmov_ST0_FT0(CPUX86State *env)
{
ST0 = FT0;
}
-void helper_fmov_FT0_STN(int st_index)
+void helper_fmov_FT0_STN(CPUX86State *env, int st_index)
{
FT0 = ST(st_index);
}
-void helper_fmov_ST0_STN(int st_index)
+void helper_fmov_ST0_STN(CPUX86State *env, int st_index)
{
ST0 = ST(st_index);
}
-void helper_fmov_STN_ST0(int st_index)
+void helper_fmov_STN_ST0(CPUX86State *env, int st_index)
{
ST(st_index) = ST0;
}
-void helper_fxchg_ST0_STN(int st_index)
+void helper_fxchg_ST0_STN(CPUX86State *env, int st_index)
{
floatx80 tmp;
@@ -370,7 +369,7 @@
static const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500};
-void helper_fcom_ST0_FT0(void)
+void helper_fcom_ST0_FT0(CPUX86State *env)
{
int ret;
@@ -378,7 +377,7 @@
env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1];
}
-void helper_fucom_ST0_FT0(void)
+void helper_fucom_ST0_FT0(CPUX86State *env)
{
int ret;
@@ -388,158 +387,158 @@
static const int fcomi_ccval[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C};
-void helper_fcomi_ST0_FT0(void)
+void helper_fcomi_ST0_FT0(CPUX86State *env)
{
int eflags;
int ret;
ret = floatx80_compare(ST0, FT0, &env->fp_status);
- eflags = helper_cc_compute_all(CC_OP);
+ eflags = cpu_cc_compute_all(env, CC_OP);
eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
CC_SRC = eflags;
}
-void helper_fucomi_ST0_FT0(void)
+void helper_fucomi_ST0_FT0(CPUX86State *env)
{
int eflags;
int ret;
ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status);
- eflags = helper_cc_compute_all(CC_OP);
+ eflags = cpu_cc_compute_all(env, CC_OP);
eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
CC_SRC = eflags;
}
-void helper_fadd_ST0_FT0(void)
+void helper_fadd_ST0_FT0(CPUX86State *env)
{
ST0 = floatx80_add(ST0, FT0, &env->fp_status);
}
-void helper_fmul_ST0_FT0(void)
+void helper_fmul_ST0_FT0(CPUX86State *env)
{
ST0 = floatx80_mul(ST0, FT0, &env->fp_status);
}
-void helper_fsub_ST0_FT0(void)
+void helper_fsub_ST0_FT0(CPUX86State *env)
{
ST0 = floatx80_sub(ST0, FT0, &env->fp_status);
}
-void helper_fsubr_ST0_FT0(void)
+void helper_fsubr_ST0_FT0(CPUX86State *env)
{
ST0 = floatx80_sub(FT0, ST0, &env->fp_status);
}
-void helper_fdiv_ST0_FT0(void)
+void helper_fdiv_ST0_FT0(CPUX86State *env)
{
- ST0 = helper_fdiv(ST0, FT0);
+ ST0 = helper_fdiv(env, ST0, FT0);
}
-void helper_fdivr_ST0_FT0(void)
+void helper_fdivr_ST0_FT0(CPUX86State *env)
{
- ST0 = helper_fdiv(FT0, ST0);
+ ST0 = helper_fdiv(env, FT0, ST0);
}
/* fp operations between STN and ST0 */
-void helper_fadd_STN_ST0(int st_index)
+void helper_fadd_STN_ST0(CPUX86State *env, int st_index)
{
ST(st_index) = floatx80_add(ST(st_index), ST0, &env->fp_status);
}
-void helper_fmul_STN_ST0(int st_index)
+void helper_fmul_STN_ST0(CPUX86State *env, int st_index)
{
ST(st_index) = floatx80_mul(ST(st_index), ST0, &env->fp_status);
}
-void helper_fsub_STN_ST0(int st_index)
+void helper_fsub_STN_ST0(CPUX86State *env, int st_index)
{
ST(st_index) = floatx80_sub(ST(st_index), ST0, &env->fp_status);
}
-void helper_fsubr_STN_ST0(int st_index)
+void helper_fsubr_STN_ST0(CPUX86State *env, int st_index)
{
ST(st_index) = floatx80_sub(ST0, ST(st_index), &env->fp_status);
}
-void helper_fdiv_STN_ST0(int st_index)
+void helper_fdiv_STN_ST0(CPUX86State *env, int st_index)
{
floatx80 *p;
p = &ST(st_index);
- *p = helper_fdiv(*p, ST0);
+ *p = helper_fdiv(env, *p, ST0);
}
-void helper_fdivr_STN_ST0(int st_index)
+void helper_fdivr_STN_ST0(CPUX86State *env, int st_index)
{
floatx80 *p;
p = &ST(st_index);
- *p = helper_fdiv(ST0, *p);
+ *p = helper_fdiv(env, ST0, *p);
}
/* misc FPU operations */
-void helper_fchs_ST0(void)
+void helper_fchs_ST0(CPUX86State *env)
{
ST0 = floatx80_chs(ST0);
}
-void helper_fabs_ST0(void)
+void helper_fabs_ST0(CPUX86State *env)
{
ST0 = floatx80_abs(ST0);
}
-void helper_fld1_ST0(void)
+void helper_fld1_ST0(CPUX86State *env)
{
ST0 = floatx80_one;
}
-void helper_fldl2t_ST0(void)
+void helper_fldl2t_ST0(CPUX86State *env)
{
ST0 = floatx80_l2t;
}
-void helper_fldl2e_ST0(void)
+void helper_fldl2e_ST0(CPUX86State *env)
{
ST0 = floatx80_l2e;
}
-void helper_fldpi_ST0(void)
+void helper_fldpi_ST0(CPUX86State *env)
{
ST0 = floatx80_pi;
}
-void helper_fldlg2_ST0(void)
+void helper_fldlg2_ST0(CPUX86State *env)
{
ST0 = floatx80_lg2;
}
-void helper_fldln2_ST0(void)
+void helper_fldln2_ST0(CPUX86State *env)
{
ST0 = floatx80_ln2;
}
-void helper_fldz_ST0(void)
+void helper_fldz_ST0(CPUX86State *env)
{
ST0 = floatx80_zero;
}
-void helper_fldz_FT0(void)
+void helper_fldz_FT0(CPUX86State *env)
{
FT0 = floatx80_zero;
}
-uint32_t helper_fnstsw(void)
+uint32_t helper_fnstsw(CPUX86State *env)
{
return (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
}
-uint32_t helper_fnstcw(void)
+uint32_t helper_fnstcw(CPUX86State *env)
{
return env->fpuc;
}
-static void update_fp_status(void)
+static void update_fp_status(CPUX86State *env)
{
int rnd_type;
@@ -575,25 +574,25 @@
set_floatx80_rounding_precision(rnd_type, &env->fp_status);
}
-void helper_fldcw(uint32_t val)
+void helper_fldcw(CPUX86State *env, uint32_t val)
{
env->fpuc = val;
- update_fp_status();
+ update_fp_status(env);
}
-void helper_fclex(void)
+void helper_fclex(CPUX86State *env)
{
env->fpus &= 0x7f00;
}
-void helper_fwait(void)
+void helper_fwait(CPUX86State *env)
{
if (env->fpus & FPUS_SE) {
- fpu_raise_exception();
+ fpu_raise_exception(env);
}
}
-void helper_fninit(void)
+void helper_fninit(CPUX86State *env)
{
env->fpus = 0;
env->fpstt = 0;
@@ -610,7 +609,7 @@
/* BCD ops */
-void helper_fbld_ST0(target_ulong ptr)
+void helper_fbld_ST0(CPUX86State *env, target_ulong ptr)
{
floatx80 tmp;
uint64_t val;
@@ -619,18 +618,18 @@
val = 0;
for (i = 8; i >= 0; i--) {
- v = ldub(ptr + i);
+ v = cpu_ldub_data(env, ptr + i);
val = (val * 100) + ((v >> 4) * 10) + (v & 0xf);
}
tmp = int64_to_floatx80(val, &env->fp_status);
- if (ldub(ptr + 9) & 0x80) {
+ if (cpu_ldub_data(env, ptr + 9) & 0x80) {
floatx80_chs(tmp);
}
- fpush();
+ fpush(env);
ST0 = tmp;
}
-void helper_fbst_ST0(target_ulong ptr)
+void helper_fbst_ST0(CPUX86State *env, target_ulong ptr)
{
int v;
target_ulong mem_ref, mem_end;
@@ -640,10 +639,10 @@
mem_ref = ptr;
mem_end = mem_ref + 9;
if (val < 0) {
- stb(mem_end, 0x80);
+ cpu_stb_data(env, mem_end, 0x80);
val = -val;
} else {
- stb(mem_end, 0x00);
+ cpu_stb_data(env, mem_end, 0x00);
}
while (mem_ref < mem_end) {
if (val == 0) {
@@ -652,63 +651,63 @@
v = val % 100;
val = val / 100;
v = ((v / 10) << 4) | (v % 10);
- stb(mem_ref++, v);
+ cpu_stb_data(env, mem_ref++, v);
}
while (mem_ref < mem_end) {
- stb(mem_ref++, 0);
+ cpu_stb_data(env, mem_ref++, 0);
}
}
-void helper_f2xm1(void)
+void helper_f2xm1(CPUX86State *env)
{
- double val = floatx80_to_double(ST0);
+ double val = floatx80_to_double(env, ST0);
val = pow(2.0, val) - 1.0;
- ST0 = double_to_floatx80(val);
+ ST0 = double_to_floatx80(env, val);
}
-void helper_fyl2x(void)
+void helper_fyl2x(CPUX86State *env)
{
- double fptemp = floatx80_to_double(ST0);
+ double fptemp = floatx80_to_double(env, ST0);
if (fptemp > 0.0) {
fptemp = log(fptemp) / log(2.0); /* log2(ST) */
- fptemp *= floatx80_to_double(ST1);
- ST1 = double_to_floatx80(fptemp);
- fpop();
+ fptemp *= floatx80_to_double(env, ST1);
+ ST1 = double_to_floatx80(env, fptemp);
+ fpop(env);
} else {
env->fpus &= ~0x4700;
env->fpus |= 0x400;
}
}
-void helper_fptan(void)
+void helper_fptan(CPUX86State *env)
{
- double fptemp = floatx80_to_double(ST0);
+ double fptemp = floatx80_to_double(env, ST0);
if ((fptemp > MAXTAN) || (fptemp < -MAXTAN)) {
env->fpus |= 0x400;
} else {
fptemp = tan(fptemp);
- ST0 = double_to_floatx80(fptemp);
- fpush();
+ ST0 = double_to_floatx80(env, fptemp);
+ fpush(env);
ST0 = floatx80_one;
env->fpus &= ~0x400; /* C2 <-- 0 */
/* the above code is for |arg| < 2**52 only */
}
}
-void helper_fpatan(void)
+void helper_fpatan(CPUX86State *env)
{
double fptemp, fpsrcop;
- fpsrcop = floatx80_to_double(ST1);
- fptemp = floatx80_to_double(ST0);
- ST1 = double_to_floatx80(atan2(fpsrcop, fptemp));
- fpop();
+ fpsrcop = floatx80_to_double(env, ST1);
+ fptemp = floatx80_to_double(env, ST0);
+ ST1 = double_to_floatx80(env, atan2(fpsrcop, fptemp));
+ fpop(env);
}
-void helper_fxtract(void)
+void helper_fxtract(CPUX86State *env)
{
CPU_LDoubleU temp;
@@ -718,7 +717,7 @@
/* Easy way to generate -inf and raising division by 0 exception */
ST0 = floatx80_div(floatx80_chs(floatx80_one), floatx80_zero,
&env->fp_status);
- fpush();
+ fpush(env);
ST0 = temp.d;
} else {
int expdif;
@@ -726,24 +725,24 @@
expdif = EXPD(temp) - EXPBIAS;
/* DP exponent bias */
ST0 = int32_to_floatx80(expdif, &env->fp_status);
- fpush();
+ fpush(env);
BIASEXPONENT(temp);
ST0 = temp.d;
}
}
-void helper_fprem1(void)
+void helper_fprem1(CPUX86State *env)
{
double st0, st1, dblq, fpsrcop, fptemp;
CPU_LDoubleU fpsrcop1, fptemp1;
int expdif;
signed long long int q;
- st0 = floatx80_to_double(ST0);
- st1 = floatx80_to_double(ST1);
+ st0 = floatx80_to_double(env, ST0);
+ st1 = floatx80_to_double(env, ST1);
if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) {
- ST0 = double_to_floatx80(0.0 / 0.0); /* NaN */
+ ST0 = double_to_floatx80(env, 0.0 / 0.0); /* NaN */
env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */
return;
}
@@ -788,21 +787,21 @@
-(floor(fabs(fpsrcop))) : floor(fpsrcop);
st0 -= (st1 * fpsrcop * fptemp);
}
- ST0 = double_to_floatx80(st0);
+ ST0 = double_to_floatx80(env, st0);
}
-void helper_fprem(void)
+void helper_fprem(CPUX86State *env)
{
double st0, st1, dblq, fpsrcop, fptemp;
CPU_LDoubleU fpsrcop1, fptemp1;
int expdif;
signed long long int q;
- st0 = floatx80_to_double(ST0);
- st1 = floatx80_to_double(ST1);
+ st0 = floatx80_to_double(env, ST0);
+ st1 = floatx80_to_double(env, ST1);
if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) {
- ST0 = double_to_floatx80(0.0 / 0.0); /* NaN */
+ ST0 = double_to_floatx80(env, 0.0 / 0.0); /* NaN */
env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */
return;
}
@@ -849,25 +848,25 @@
-(floor(fabs(fpsrcop))) : floor(fpsrcop);
st0 -= (st1 * fpsrcop * fptemp);
}
- ST0 = double_to_floatx80(st0);
+ ST0 = double_to_floatx80(env, st0);
}
-void helper_fyl2xp1(void)
+void helper_fyl2xp1(CPUX86State *env)
{
- double fptemp = floatx80_to_double(ST0);
+ double fptemp = floatx80_to_double(env, ST0);
if ((fptemp + 1.0) > 0.0) {
fptemp = log(fptemp + 1.0) / log(2.0); /* log2(ST + 1.0) */
- fptemp *= floatx80_to_double(ST1);
- ST1 = double_to_floatx80(fptemp);
- fpop();
+ fptemp *= floatx80_to_double(env, ST1);
+ ST1 = double_to_floatx80(env, fptemp);
+ fpop(env);
} else {
env->fpus &= ~0x4700;
env->fpus |= 0x400;
}
}
-void helper_fsqrt(void)
+void helper_fsqrt(CPUX86State *env)
{
if (floatx80_is_neg(ST0)) {
env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */
@@ -876,27 +875,27 @@
ST0 = floatx80_sqrt(ST0, &env->fp_status);
}
-void helper_fsincos(void)
+void helper_fsincos(CPUX86State *env)
{
- double fptemp = floatx80_to_double(ST0);
+ double fptemp = floatx80_to_double(env, ST0);
if ((fptemp > MAXTAN) || (fptemp < -MAXTAN)) {
env->fpus |= 0x400;
} else {
- ST0 = double_to_floatx80(sin(fptemp));
- fpush();
- ST0 = double_to_floatx80(cos(fptemp));
+ ST0 = double_to_floatx80(env, sin(fptemp));
+ fpush(env);
+ ST0 = double_to_floatx80(env, cos(fptemp));
env->fpus &= ~0x400; /* C2 <-- 0 */
/* the above code is for |arg| < 2**63 only */
}
}
-void helper_frndint(void)
+void helper_frndint(CPUX86State *env)
{
ST0 = floatx80_round_to_int(ST0, &env->fp_status);
}
-void helper_fscale(void)
+void helper_fscale(CPUX86State *env)
{
if (floatx80_is_any_nan(ST1)) {
ST0 = ST1;
@@ -906,33 +905,33 @@
}
}
-void helper_fsin(void)
+void helper_fsin(CPUX86State *env)
{
- double fptemp = floatx80_to_double(ST0);
+ double fptemp = floatx80_to_double(env, ST0);
if ((fptemp > MAXTAN) || (fptemp < -MAXTAN)) {
env->fpus |= 0x400;
} else {
- ST0 = double_to_floatx80(sin(fptemp));
+ ST0 = double_to_floatx80(env, sin(fptemp));
env->fpus &= ~0x400; /* C2 <-- 0 */
/* the above code is for |arg| < 2**53 only */
}
}
-void helper_fcos(void)
+void helper_fcos(CPUX86State *env)
{
- double fptemp = floatx80_to_double(ST0);
+ double fptemp = floatx80_to_double(env, ST0);
if ((fptemp > MAXTAN) || (fptemp < -MAXTAN)) {
env->fpus |= 0x400;
} else {
- ST0 = double_to_floatx80(cos(fptemp));
+ ST0 = double_to_floatx80(env, cos(fptemp));
env->fpus &= ~0x400; /* C2 <-- 0 */
/* the above code is for |arg| < 2**63 only */
}
}
-void helper_fxam_ST0(void)
+void helper_fxam_ST0(CPUX86State *env)
{
CPU_LDoubleU temp;
int expdif;
@@ -963,7 +962,7 @@
}
}
-void helper_fstenv(target_ulong ptr, int data32)
+void helper_fstenv(CPUX86State *env, target_ulong ptr, int data32)
{
int fpus, fptag, exp, i;
uint64_t mant;
@@ -991,37 +990,37 @@
}
if (data32) {
/* 32 bit */
- stl(ptr, env->fpuc);
- stl(ptr + 4, fpus);
- stl(ptr + 8, fptag);
- stl(ptr + 12, 0); /* fpip */
- stl(ptr + 16, 0); /* fpcs */
- stl(ptr + 20, 0); /* fpoo */
- stl(ptr + 24, 0); /* fpos */
+ cpu_stl_data(env, ptr, env->fpuc);
+ cpu_stl_data(env, ptr + 4, fpus);
+ cpu_stl_data(env, ptr + 8, fptag);
+ cpu_stl_data(env, ptr + 12, 0); /* fpip */
+ cpu_stl_data(env, ptr + 16, 0); /* fpcs */
+ cpu_stl_data(env, ptr + 20, 0); /* fpoo */
+ cpu_stl_data(env, ptr + 24, 0); /* fpos */
} else {
/* 16 bit */
- stw(ptr, env->fpuc);
- stw(ptr + 2, fpus);
- stw(ptr + 4, fptag);
- stw(ptr + 6, 0);
- stw(ptr + 8, 0);
- stw(ptr + 10, 0);
- stw(ptr + 12, 0);
+ cpu_stw_data(env, ptr, env->fpuc);
+ cpu_stw_data(env, ptr + 2, fpus);
+ cpu_stw_data(env, ptr + 4, fptag);
+ cpu_stw_data(env, ptr + 6, 0);
+ cpu_stw_data(env, ptr + 8, 0);
+ cpu_stw_data(env, ptr + 10, 0);
+ cpu_stw_data(env, ptr + 12, 0);
}
}
-void helper_fldenv(target_ulong ptr, int data32)
+void helper_fldenv(CPUX86State *env, target_ulong ptr, int data32)
{
int i, fpus, fptag;
if (data32) {
- env->fpuc = lduw(ptr);
- fpus = lduw(ptr + 4);
- fptag = lduw(ptr + 8);
+ env->fpuc = cpu_lduw_data(env, ptr);
+ fpus = cpu_lduw_data(env, ptr + 4);
+ fptag = cpu_lduw_data(env, ptr + 8);
} else {
- env->fpuc = lduw(ptr);
- fpus = lduw(ptr + 2);
- fptag = lduw(ptr + 4);
+ env->fpuc = cpu_lduw_data(env, ptr);
+ fpus = cpu_lduw_data(env, ptr + 2);
+ fptag = cpu_lduw_data(env, ptr + 4);
}
env->fpstt = (fpus >> 11) & 7;
env->fpus = fpus & ~0x3800;
@@ -1031,17 +1030,17 @@
}
}
-void helper_fsave(target_ulong ptr, int data32)
+void helper_fsave(CPUX86State *env, target_ulong ptr, int data32)
{
floatx80 tmp;
int i;
- helper_fstenv(ptr, data32);
+ helper_fstenv(env, ptr, data32);
ptr += (14 << data32);
for (i = 0; i < 8; i++) {
tmp = ST(i);
- helper_fstt(tmp, ptr);
+ helper_fstt(env, tmp, ptr);
ptr += 10;
}
@@ -1059,48 +1058,34 @@
env->fptags[7] = 1;
}
-void helper_frstor(target_ulong ptr, int data32)
+void helper_frstor(CPUX86State *env, target_ulong ptr, int data32)
{
floatx80 tmp;
int i;
- helper_fldenv(ptr, data32);
+ helper_fldenv(env, ptr, data32);
ptr += (14 << data32);
for (i = 0; i < 8; i++) {
- tmp = helper_fldt(ptr);
+ tmp = helper_fldt(env, ptr);
ST(i) = tmp;
ptr += 10;
}
}
#if defined(CONFIG_USER_ONLY)
-void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32)
+void cpu_x86_fsave(CPUX86State *env, target_ulong ptr, int data32)
{
- CPUX86State *saved_env;
-
- saved_env = env;
- env = s;
-
- helper_fsave(ptr, data32);
-
- env = saved_env;
+ helper_fsave(env, ptr, data32);
}
-void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)
+void cpu_x86_frstor(CPUX86State *env, target_ulong ptr, int data32)
{
- CPUX86State *saved_env;
-
- saved_env = env;
- env = s;
-
- helper_frstor(ptr, data32);
-
- env = saved_env;
+ helper_frstor(env, ptr, data32);
}
#endif
-void helper_fxsave(target_ulong ptr, int data64)
+void helper_fxsave(CPUX86State *env, target_ulong ptr, int data64)
{
int fpus, fptag, i, nb_xmm_regs;
floatx80 tmp;
@@ -1116,33 +1101,33 @@
for (i = 0; i < 8; i++) {
fptag |= (env->fptags[i] << i);
}
- stw(ptr, env->fpuc);
- stw(ptr + 2, fpus);
- stw(ptr + 4, fptag ^ 0xff);
+ cpu_stw_data(env, ptr, env->fpuc);
+ cpu_stw_data(env, ptr + 2, fpus);
+ cpu_stw_data(env, ptr + 4, fptag ^ 0xff);
#ifdef TARGET_X86_64
if (data64) {
- stq(ptr + 0x08, 0); /* rip */
- stq(ptr + 0x10, 0); /* rdp */
+ cpu_stq_data(env, ptr + 0x08, 0); /* rip */
+ cpu_stq_data(env, ptr + 0x10, 0); /* rdp */
} else
#endif
{
- stl(ptr + 0x08, 0); /* eip */
- stl(ptr + 0x0c, 0); /* sel */
- stl(ptr + 0x10, 0); /* dp */
- stl(ptr + 0x14, 0); /* sel */
+ cpu_stl_data(env, ptr + 0x08, 0); /* eip */
+ cpu_stl_data(env, ptr + 0x0c, 0); /* sel */
+ cpu_stl_data(env, ptr + 0x10, 0); /* dp */
+ cpu_stl_data(env, ptr + 0x14, 0); /* sel */
}
addr = ptr + 0x20;
for (i = 0; i < 8; i++) {
tmp = ST(i);
- helper_fstt(tmp, addr);
+ helper_fstt(env, tmp, addr);
addr += 16;
}
if (env->cr[4] & CR4_OSFXSR_MASK) {
/* XXX: finish it */
- stl(ptr + 0x18, env->mxcsr); /* mxcsr */
- stl(ptr + 0x1c, 0x0000ffff); /* mxcsr_mask */
+ cpu_stl_data(env, ptr + 0x18, env->mxcsr); /* mxcsr */
+ cpu_stl_data(env, ptr + 0x1c, 0x0000ffff); /* mxcsr_mask */
if (env->hflags & HF_CS64_MASK) {
nb_xmm_regs = 16;
} else {
@@ -1154,15 +1139,15 @@
|| (env->hflags & HF_CPL_MASK)
|| !(env->hflags & HF_LMA_MASK)) {
for (i = 0; i < nb_xmm_regs; i++) {
- stq(addr, env->xmm_regs[i].XMM_Q(0));
- stq(addr + 8, env->xmm_regs[i].XMM_Q(1));
+ cpu_stq_data(env, addr, env->xmm_regs[i].XMM_Q(0));
+ cpu_stq_data(env, addr + 8, env->xmm_regs[i].XMM_Q(1));
addr += 16;
}
}
}
}
-void helper_fxrstor(target_ulong ptr, int data64)
+void helper_fxrstor(CPUX86State *env, target_ulong ptr, int data64)
{
int i, fpus, fptag, nb_xmm_regs;
floatx80 tmp;
@@ -1173,9 +1158,9 @@
raise_exception(env, EXCP0D_GPF);
}
- env->fpuc = lduw(ptr);
- fpus = lduw(ptr + 2);
- fptag = lduw(ptr + 4);
+ env->fpuc = cpu_lduw_data(env, ptr);
+ fpus = cpu_lduw_data(env, ptr + 2);
+ fptag = cpu_lduw_data(env, ptr + 4);
env->fpstt = (fpus >> 11) & 7;
env->fpus = fpus & ~0x3800;
fptag ^= 0xff;
@@ -1185,15 +1170,15 @@
addr = ptr + 0x20;
for (i = 0; i < 8; i++) {
- tmp = helper_fldt(addr);
+ tmp = helper_fldt(env, addr);
ST(i) = tmp;
addr += 16;
}
if (env->cr[4] & CR4_OSFXSR_MASK) {
/* XXX: finish it */
- env->mxcsr = ldl(ptr + 0x18);
- /* ldl(ptr + 0x1c); */
+ env->mxcsr = cpu_ldl_data(env, ptr + 0x18);
+ /* cpu_ldl_data(env, ptr + 0x1c); */
if (env->hflags & HF_CS64_MASK) {
nb_xmm_regs = 16;
} else {
@@ -1205,8 +1190,8 @@
|| (env->hflags & HF_CPL_MASK)
|| !(env->hflags & HF_LMA_MASK)) {
for (i = 0; i < nb_xmm_regs; i++) {
- env->xmm_regs[i].XMM_Q(0) = ldq(addr);
- env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8);
+ env->xmm_regs[i].XMM_Q(0) = cpu_ldq_data(env, addr);
+ env->xmm_regs[i].XMM_Q(1) = cpu_ldq_data(env, addr + 8);
addr += 16;
}
}
@@ -1242,7 +1227,7 @@
#define SSE_RC_CHOP 0x6000
#define SSE_FZ 0x8000
-static void update_sse_status(void)
+static void update_sse_status(CPUX86State *env)
{
int rnd_type;
@@ -1271,20 +1256,20 @@
set_flush_to_zero((env->mxcsr & SSE_FZ) ? 1 : 0, &env->fp_status);
}
-void helper_ldmxcsr(uint32_t val)
+void helper_ldmxcsr(CPUX86State *env, uint32_t val)
{
env->mxcsr = val;
- update_sse_status();
+ update_sse_status(env);
}
-void helper_enter_mmx(void)
+void helper_enter_mmx(CPUX86State *env)
{
env->fpstt = 0;
*(uint32_t *)(env->fptags) = 0;
*(uint32_t *)(env->fptags + 4) = 0;
}
-void helper_emms(void)
+void helper_emms(CPUX86State *env)
{
/* set to empty state */
*(uint32_t *)(env->fptags) = 0x01010101;
@@ -1292,7 +1277,7 @@
}
/* XXX: suppress */
-void helper_movq(void *d, void *s)
+void helper_movq(CPUX86State *env, void *d, void *s)
{
*(uint64_t *)d = *(uint64_t *)s;
}
diff --git a/target-i386/helper.h b/target-i386/helper.h
index 99ca183..ab6af63 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -1,93 +1,93 @@
#include "def-helper.h"
-DEF_HELPER_FLAGS_1(cc_compute_all, TCG_CALL_PURE, i32, int)
-DEF_HELPER_FLAGS_1(cc_compute_c, TCG_CALL_PURE, i32, int)
+DEF_HELPER_FLAGS_2(cc_compute_all, TCG_CALL_PURE, i32, env, int)
+DEF_HELPER_FLAGS_2(cc_compute_c, TCG_CALL_PURE, i32, env, int)
DEF_HELPER_0(lock, void)
DEF_HELPER_0(unlock, void)
-DEF_HELPER_2(write_eflags, void, tl, i32)
-DEF_HELPER_0(read_eflags, tl)
-DEF_HELPER_1(divb_AL, void, tl)
-DEF_HELPER_1(idivb_AL, void, tl)
-DEF_HELPER_1(divw_AX, void, tl)
-DEF_HELPER_1(idivw_AX, void, tl)
-DEF_HELPER_1(divl_EAX, void, tl)
-DEF_HELPER_1(idivl_EAX, void, tl)
+DEF_HELPER_3(write_eflags, void, env, tl, i32)
+DEF_HELPER_1(read_eflags, tl, env)
+DEF_HELPER_2(divb_AL, void, env, tl)
+DEF_HELPER_2(idivb_AL, void, env, tl)
+DEF_HELPER_2(divw_AX, void, env, tl)
+DEF_HELPER_2(idivw_AX, void, env, tl)
+DEF_HELPER_2(divl_EAX, void, env, tl)
+DEF_HELPER_2(idivl_EAX, void, env, tl)
#ifdef TARGET_X86_64
-DEF_HELPER_1(mulq_EAX_T0, void, tl)
-DEF_HELPER_1(imulq_EAX_T0, void, tl)
-DEF_HELPER_2(imulq_T0_T1, tl, tl, tl)
-DEF_HELPER_1(divq_EAX, void, tl)
-DEF_HELPER_1(idivq_EAX, void, tl)
+DEF_HELPER_2(mulq_EAX_T0, void, env, tl)
+DEF_HELPER_2(imulq_EAX_T0, void, env, tl)
+DEF_HELPER_3(imulq_T0_T1, tl, env, tl, tl)
+DEF_HELPER_2(divq_EAX, void, env, tl)
+DEF_HELPER_2(idivq_EAX, void, env, tl)
#endif
-DEF_HELPER_1(aam, void, int)
-DEF_HELPER_1(aad, void, int)
-DEF_HELPER_0(aaa, void)
-DEF_HELPER_0(aas, void)
-DEF_HELPER_0(daa, void)
-DEF_HELPER_0(das, void)
+DEF_HELPER_2(aam, void, env, int)
+DEF_HELPER_2(aad, void, env, int)
+DEF_HELPER_1(aaa, void, env)
+DEF_HELPER_1(aas, void, env)
+DEF_HELPER_1(daa, void, env)
+DEF_HELPER_1(das, void, env)
-DEF_HELPER_1(lsl, tl, tl)
-DEF_HELPER_1(lar, tl, tl)
-DEF_HELPER_1(verr, void, tl)
-DEF_HELPER_1(verw, void, tl)
-DEF_HELPER_1(lldt, void, int)
-DEF_HELPER_1(ltr, void, int)
-DEF_HELPER_2(load_seg, void, int, int)
-DEF_HELPER_3(ljmp_protected, void, int, tl, int)
-DEF_HELPER_4(lcall_real, void, int, tl, int, int)
-DEF_HELPER_4(lcall_protected, void, int, tl, int, int)
-DEF_HELPER_1(iret_real, void, int)
-DEF_HELPER_2(iret_protected, void, int, int)
-DEF_HELPER_2(lret_protected, void, int, int)
-DEF_HELPER_1(read_crN, tl, int)
-DEF_HELPER_2(write_crN, void, int, tl)
-DEF_HELPER_1(lmsw, void, tl)
-DEF_HELPER_0(clts, void)
-DEF_HELPER_2(movl_drN_T0, void, int, tl)
-DEF_HELPER_1(invlpg, void, tl)
+DEF_HELPER_2(lsl, tl, env, tl)
+DEF_HELPER_2(lar, tl, env, tl)
+DEF_HELPER_2(verr, void, env, tl)
+DEF_HELPER_2(verw, void, env, tl)
+DEF_HELPER_2(lldt, void, env, int)
+DEF_HELPER_2(ltr, void, env, int)
+DEF_HELPER_3(load_seg, void, env, int, int)
+DEF_HELPER_4(ljmp_protected, void, env, int, tl, int)
+DEF_HELPER_5(lcall_real, void, env, int, tl, int, int)
+DEF_HELPER_5(lcall_protected, void, env, int, tl, int, int)
+DEF_HELPER_2(iret_real, void, env, int)
+DEF_HELPER_3(iret_protected, void, env, int, int)
+DEF_HELPER_3(lret_protected, void, env, int, int)
+DEF_HELPER_2(read_crN, tl, env, int)
+DEF_HELPER_3(write_crN, void, env, int, tl)
+DEF_HELPER_2(lmsw, void, env, tl)
+DEF_HELPER_1(clts, void, env)
+DEF_HELPER_3(movl_drN_T0, void, env, int, tl)
+DEF_HELPER_2(invlpg, void, env, tl)
-DEF_HELPER_3(enter_level, void, int, int, tl)
+DEF_HELPER_4(enter_level, void, env, int, int, tl)
#ifdef TARGET_X86_64
-DEF_HELPER_3(enter64_level, void, int, int, tl)
+DEF_HELPER_4(enter64_level, void, env, int, int, tl)
#endif
-DEF_HELPER_0(sysenter, void)
-DEF_HELPER_1(sysexit, void, int)
+DEF_HELPER_1(sysenter, void, env)
+DEF_HELPER_2(sysexit, void, env, int)
#ifdef TARGET_X86_64
-DEF_HELPER_1(syscall, void, int)
-DEF_HELPER_1(sysret, void, int)
+DEF_HELPER_2(syscall, void, env, int)
+DEF_HELPER_2(sysret, void, env, int)
#endif
-DEF_HELPER_1(hlt, void, int)
-DEF_HELPER_1(monitor, void, tl)
-DEF_HELPER_1(mwait, void, int)
-DEF_HELPER_0(debug, void)
-DEF_HELPER_0(reset_rf, void)
+DEF_HELPER_2(hlt, void, env, int)
+DEF_HELPER_2(monitor, void, env, tl)
+DEF_HELPER_2(mwait, void, env, int)
+DEF_HELPER_1(debug, void, env)
+DEF_HELPER_1(reset_rf, void, env)
DEF_HELPER_3(raise_interrupt, void, env, int, int)
DEF_HELPER_2(raise_exception, void, env, int)
-DEF_HELPER_0(cli, void)
-DEF_HELPER_0(sti, void)
-DEF_HELPER_0(set_inhibit_irq, void)
-DEF_HELPER_0(reset_inhibit_irq, void)
-DEF_HELPER_2(boundw, void, tl, int)
-DEF_HELPER_2(boundl, void, tl, int)
-DEF_HELPER_0(rsm, void)
-DEF_HELPER_1(into, void, int)
-DEF_HELPER_1(cmpxchg8b, void, tl)
+DEF_HELPER_1(cli, void, env)
+DEF_HELPER_1(sti, void, env)
+DEF_HELPER_1(set_inhibit_irq, void, env)
+DEF_HELPER_1(reset_inhibit_irq, void, env)
+DEF_HELPER_3(boundw, void, env, tl, int)
+DEF_HELPER_3(boundl, void, env, tl, int)
+DEF_HELPER_1(rsm, void, env)
+DEF_HELPER_2(into, void, env, int)
+DEF_HELPER_2(cmpxchg8b, void, env, tl)
#ifdef TARGET_X86_64
-DEF_HELPER_1(cmpxchg16b, void, tl)
+DEF_HELPER_2(cmpxchg16b, void, env, tl)
#endif
-DEF_HELPER_0(single_step, void)
-DEF_HELPER_0(cpuid, void)
-DEF_HELPER_0(rdtsc, void)
-DEF_HELPER_0(rdtscp, void)
-DEF_HELPER_0(rdpmc, void)
-DEF_HELPER_0(rdmsr, void)
-DEF_HELPER_0(wrmsr, void)
+DEF_HELPER_1(single_step, void, env)
+DEF_HELPER_1(cpuid, void, env)
+DEF_HELPER_1(rdtsc, void, env)
+DEF_HELPER_1(rdtscp, void, env)
+DEF_HELPER_1(rdpmc, void, env)
+DEF_HELPER_1(rdmsr, void, env)
+DEF_HELPER_1(wrmsr, void, env)
-DEF_HELPER_1(check_iob, void, i32)
-DEF_HELPER_1(check_iow, void, i32)
-DEF_HELPER_1(check_iol, void, i32)
+DEF_HELPER_2(check_iob, void, env, i32)
+DEF_HELPER_2(check_iow, void, env, i32)
+DEF_HELPER_2(check_iol, void, env, i32)
DEF_HELPER_2(outb, void, i32, i32)
DEF_HELPER_1(inb, tl, i32)
DEF_HELPER_2(outw, void, i32, i32)
@@ -95,127 +95,127 @@
DEF_HELPER_2(outl, void, i32, i32)
DEF_HELPER_1(inl, tl, i32)
-DEF_HELPER_2(svm_check_intercept_param, void, i32, i64)
-DEF_HELPER_2(vmexit, void, i32, i64)
-DEF_HELPER_3(svm_check_io, void, i32, i32, i32)
-DEF_HELPER_2(vmrun, void, int, int)
-DEF_HELPER_0(vmmcall, void)
-DEF_HELPER_1(vmload, void, int)
-DEF_HELPER_1(vmsave, void, int)
-DEF_HELPER_0(stgi, void)
-DEF_HELPER_0(clgi, void)
-DEF_HELPER_0(skinit, void)
-DEF_HELPER_1(invlpga, void, int)
+DEF_HELPER_3(svm_check_intercept_param, void, env, i32, i64)
+DEF_HELPER_3(vmexit, void, env, i32, i64)
+DEF_HELPER_4(svm_check_io, void, env, i32, i32, i32)
+DEF_HELPER_3(vmrun, void, env, int, int)
+DEF_HELPER_1(vmmcall, void, env)
+DEF_HELPER_2(vmload, void, env, int)
+DEF_HELPER_2(vmsave, void, env, int)
+DEF_HELPER_1(stgi, void, env)
+DEF_HELPER_1(clgi, void, env)
+DEF_HELPER_1(skinit, void, env)
+DEF_HELPER_2(invlpga, void, env, int)
/* x86 FPU */
-DEF_HELPER_1(flds_FT0, void, i32)
-DEF_HELPER_1(fldl_FT0, void, i64)
-DEF_HELPER_1(fildl_FT0, void, s32)
-DEF_HELPER_1(flds_ST0, void, i32)
-DEF_HELPER_1(fldl_ST0, void, i64)
-DEF_HELPER_1(fildl_ST0, void, s32)
-DEF_HELPER_1(fildll_ST0, void, s64)
-DEF_HELPER_0(fsts_ST0, i32)
-DEF_HELPER_0(fstl_ST0, i64)
-DEF_HELPER_0(fist_ST0, s32)
-DEF_HELPER_0(fistl_ST0, s32)
-DEF_HELPER_0(fistll_ST0, s64)
-DEF_HELPER_0(fistt_ST0, s32)
-DEF_HELPER_0(fisttl_ST0, s32)
-DEF_HELPER_0(fisttll_ST0, s64)
-DEF_HELPER_1(fldt_ST0, void, tl)
-DEF_HELPER_1(fstt_ST0, void, tl)
-DEF_HELPER_0(fpush, void)
-DEF_HELPER_0(fpop, void)
-DEF_HELPER_0(fdecstp, void)
-DEF_HELPER_0(fincstp, void)
-DEF_HELPER_1(ffree_STN, void, int)
-DEF_HELPER_0(fmov_ST0_FT0, void)
-DEF_HELPER_1(fmov_FT0_STN, void, int)
-DEF_HELPER_1(fmov_ST0_STN, void, int)
-DEF_HELPER_1(fmov_STN_ST0, void, int)
-DEF_HELPER_1(fxchg_ST0_STN, void, int)
-DEF_HELPER_0(fcom_ST0_FT0, void)
-DEF_HELPER_0(fucom_ST0_FT0, void)
-DEF_HELPER_0(fcomi_ST0_FT0, void)
-DEF_HELPER_0(fucomi_ST0_FT0, void)
-DEF_HELPER_0(fadd_ST0_FT0, void)
-DEF_HELPER_0(fmul_ST0_FT0, void)
-DEF_HELPER_0(fsub_ST0_FT0, void)
-DEF_HELPER_0(fsubr_ST0_FT0, void)
-DEF_HELPER_0(fdiv_ST0_FT0, void)
-DEF_HELPER_0(fdivr_ST0_FT0, void)
-DEF_HELPER_1(fadd_STN_ST0, void, int)
-DEF_HELPER_1(fmul_STN_ST0, void, int)
-DEF_HELPER_1(fsub_STN_ST0, void, int)
-DEF_HELPER_1(fsubr_STN_ST0, void, int)
-DEF_HELPER_1(fdiv_STN_ST0, void, int)
-DEF_HELPER_1(fdivr_STN_ST0, void, int)
-DEF_HELPER_0(fchs_ST0, void)
-DEF_HELPER_0(fabs_ST0, void)
-DEF_HELPER_0(fxam_ST0, void)
-DEF_HELPER_0(fld1_ST0, void)
-DEF_HELPER_0(fldl2t_ST0, void)
-DEF_HELPER_0(fldl2e_ST0, void)
-DEF_HELPER_0(fldpi_ST0, void)
-DEF_HELPER_0(fldlg2_ST0, void)
-DEF_HELPER_0(fldln2_ST0, void)
-DEF_HELPER_0(fldz_ST0, void)
-DEF_HELPER_0(fldz_FT0, void)
-DEF_HELPER_0(fnstsw, i32)
-DEF_HELPER_0(fnstcw, i32)
-DEF_HELPER_1(fldcw, void, i32)
-DEF_HELPER_0(fclex, void)
-DEF_HELPER_0(fwait, void)
-DEF_HELPER_0(fninit, void)
-DEF_HELPER_1(fbld_ST0, void, tl)
-DEF_HELPER_1(fbst_ST0, void, tl)
-DEF_HELPER_0(f2xm1, void)
-DEF_HELPER_0(fyl2x, void)
-DEF_HELPER_0(fptan, void)
-DEF_HELPER_0(fpatan, void)
-DEF_HELPER_0(fxtract, void)
-DEF_HELPER_0(fprem1, void)
-DEF_HELPER_0(fprem, void)
-DEF_HELPER_0(fyl2xp1, void)
-DEF_HELPER_0(fsqrt, void)
-DEF_HELPER_0(fsincos, void)
-DEF_HELPER_0(frndint, void)
-DEF_HELPER_0(fscale, void)
-DEF_HELPER_0(fsin, void)
-DEF_HELPER_0(fcos, void)
-DEF_HELPER_2(fstenv, void, tl, int)
-DEF_HELPER_2(fldenv, void, tl, int)
-DEF_HELPER_2(fsave, void, tl, int)
-DEF_HELPER_2(frstor, void, tl, int)
-DEF_HELPER_2(fxsave, void, tl, int)
-DEF_HELPER_2(fxrstor, void, tl, int)
+DEF_HELPER_2(flds_FT0, void, env, i32)
+DEF_HELPER_2(fldl_FT0, void, env, i64)
+DEF_HELPER_2(fildl_FT0, void, env, s32)
+DEF_HELPER_2(flds_ST0, void, env, i32)
+DEF_HELPER_2(fldl_ST0, void, env, i64)
+DEF_HELPER_2(fildl_ST0, void, env, s32)
+DEF_HELPER_2(fildll_ST0, void, env, s64)
+DEF_HELPER_1(fsts_ST0, i32, env)
+DEF_HELPER_1(fstl_ST0, i64, env)
+DEF_HELPER_1(fist_ST0, s32, env)
+DEF_HELPER_1(fistl_ST0, s32, env)
+DEF_HELPER_1(fistll_ST0, s64, env)
+DEF_HELPER_1(fistt_ST0, s32, env)
+DEF_HELPER_1(fisttl_ST0, s32, env)
+DEF_HELPER_1(fisttll_ST0, s64, env)
+DEF_HELPER_2(fldt_ST0, void, env, tl)
+DEF_HELPER_2(fstt_ST0, void, env, tl)
+DEF_HELPER_1(fpush, void, env)
+DEF_HELPER_1(fpop, void, env)
+DEF_HELPER_1(fdecstp, void, env)
+DEF_HELPER_1(fincstp, void, env)
+DEF_HELPER_2(ffree_STN, void, env, int)
+DEF_HELPER_1(fmov_ST0_FT0, void, env)
+DEF_HELPER_2(fmov_FT0_STN, void, env, int)
+DEF_HELPER_2(fmov_ST0_STN, void, env, int)
+DEF_HELPER_2(fmov_STN_ST0, void, env, int)
+DEF_HELPER_2(fxchg_ST0_STN, void, env, int)
+DEF_HELPER_1(fcom_ST0_FT0, void, env)
+DEF_HELPER_1(fucom_ST0_FT0, void, env)
+DEF_HELPER_1(fcomi_ST0_FT0, void, env)
+DEF_HELPER_1(fucomi_ST0_FT0, void, env)
+DEF_HELPER_1(fadd_ST0_FT0, void, env)
+DEF_HELPER_1(fmul_ST0_FT0, void, env)
+DEF_HELPER_1(fsub_ST0_FT0, void, env)
+DEF_HELPER_1(fsubr_ST0_FT0, void, env)
+DEF_HELPER_1(fdiv_ST0_FT0, void, env)
+DEF_HELPER_1(fdivr_ST0_FT0, void, env)
+DEF_HELPER_2(fadd_STN_ST0, void, env, int)
+DEF_HELPER_2(fmul_STN_ST0, void, env, int)
+DEF_HELPER_2(fsub_STN_ST0, void, env, int)
+DEF_HELPER_2(fsubr_STN_ST0, void, env, int)
+DEF_HELPER_2(fdiv_STN_ST0, void, env, int)
+DEF_HELPER_2(fdivr_STN_ST0, void, env, int)
+DEF_HELPER_1(fchs_ST0, void, env)
+DEF_HELPER_1(fabs_ST0, void, env)
+DEF_HELPER_1(fxam_ST0, void, env)
+DEF_HELPER_1(fld1_ST0, void, env)
+DEF_HELPER_1(fldl2t_ST0, void, env)
+DEF_HELPER_1(fldl2e_ST0, void, env)
+DEF_HELPER_1(fldpi_ST0, void, env)
+DEF_HELPER_1(fldlg2_ST0, void, env)
+DEF_HELPER_1(fldln2_ST0, void, env)
+DEF_HELPER_1(fldz_ST0, void, env)
+DEF_HELPER_1(fldz_FT0, void, env)
+DEF_HELPER_1(fnstsw, i32, env)
+DEF_HELPER_1(fnstcw, i32, env)
+DEF_HELPER_2(fldcw, void, env, i32)
+DEF_HELPER_1(fclex, void, env)
+DEF_HELPER_1(fwait, void, env)
+DEF_HELPER_1(fninit, void, env)
+DEF_HELPER_2(fbld_ST0, void, env, tl)
+DEF_HELPER_2(fbst_ST0, void, env, tl)
+DEF_HELPER_1(f2xm1, void, env)
+DEF_HELPER_1(fyl2x, void, env)
+DEF_HELPER_1(fptan, void, env)
+DEF_HELPER_1(fpatan, void, env)
+DEF_HELPER_1(fxtract, void, env)
+DEF_HELPER_1(fprem1, void, env)
+DEF_HELPER_1(fprem, void, env)
+DEF_HELPER_1(fyl2xp1, void, env)
+DEF_HELPER_1(fsqrt, void, env)
+DEF_HELPER_1(fsincos, void, env)
+DEF_HELPER_1(frndint, void, env)
+DEF_HELPER_1(fscale, void, env)
+DEF_HELPER_1(fsin, void, env)
+DEF_HELPER_1(fcos, void, env)
+DEF_HELPER_3(fstenv, void, env, tl, int)
+DEF_HELPER_3(fldenv, void, env, tl, int)
+DEF_HELPER_3(fsave, void, env, tl, int)
+DEF_HELPER_3(frstor, void, env, tl, int)
+DEF_HELPER_3(fxsave, void, env, tl, int)
+DEF_HELPER_3(fxrstor, void, env, tl, int)
DEF_HELPER_1(bsf, tl, tl)
DEF_HELPER_1(bsr, tl, tl)
DEF_HELPER_2(lzcnt, tl, tl, int)
/* MMX/SSE */
-DEF_HELPER_1(ldmxcsr, void, i32)
-DEF_HELPER_0(enter_mmx, void)
-DEF_HELPER_0(emms, void)
-DEF_HELPER_2(movq, void, ptr, ptr)
+DEF_HELPER_2(ldmxcsr, void, env, i32)
+DEF_HELPER_1(enter_mmx, void, env)
+DEF_HELPER_1(emms, void, env)
+DEF_HELPER_3(movq, void, env, ptr, ptr)
#define SHIFT 0
#include "ops_sse_header.h"
#define SHIFT 1
#include "ops_sse_header.h"
-DEF_HELPER_2(rclb, tl, tl, tl)
-DEF_HELPER_2(rclw, tl, tl, tl)
-DEF_HELPER_2(rcll, tl, tl, tl)
-DEF_HELPER_2(rcrb, tl, tl, tl)
-DEF_HELPER_2(rcrw, tl, tl, tl)
-DEF_HELPER_2(rcrl, tl, tl, tl)
+DEF_HELPER_3(rclb, tl, env, tl, tl)
+DEF_HELPER_3(rclw, tl, env, tl, tl)
+DEF_HELPER_3(rcll, tl, env, tl, tl)
+DEF_HELPER_3(rcrb, tl, env, tl, tl)
+DEF_HELPER_3(rcrw, tl, env, tl, tl)
+DEF_HELPER_3(rcrl, tl, env, tl, tl)
#ifdef TARGET_X86_64
-DEF_HELPER_2(rclq, tl, tl, tl)
-DEF_HELPER_2(rcrq, tl, tl, tl)
+DEF_HELPER_3(rclq, tl, env, tl, tl)
+DEF_HELPER_3(rcrq, tl, env, tl, tl)
#endif
#include "def-helper.h"
diff --git a/target-i386/int_helper.c b/target-i386/int_helper.c
index e1f66f5..f39747e 100644
--- a/target-i386/int_helper.c
+++ b/target-i386/int_helper.c
@@ -18,7 +18,6 @@
*/
#include "cpu.h"
-#include "dyngen-exec.h"
#include "host-utils.h"
#include "helper.h"
@@ -42,7 +41,7 @@
/* division, flags are undefined */
-void helper_divb_AL(target_ulong t0)
+void helper_divb_AL(CPUX86State *env, target_ulong t0)
{
unsigned int num, den, q, r;
@@ -60,7 +59,7 @@
EAX = (EAX & ~0xffff) | (r << 8) | q;
}
-void helper_idivb_AL(target_ulong t0)
+void helper_idivb_AL(CPUX86State *env, target_ulong t0)
{
int num, den, q, r;
@@ -78,7 +77,7 @@
EAX = (EAX & ~0xffff) | (r << 8) | q;
}
-void helper_divw_AX(target_ulong t0)
+void helper_divw_AX(CPUX86State *env, target_ulong t0)
{
unsigned int num, den, q, r;
@@ -97,7 +96,7 @@
EDX = (EDX & ~0xffff) | r;
}
-void helper_idivw_AX(target_ulong t0)
+void helper_idivw_AX(CPUX86State *env, target_ulong t0)
{
int num, den, q, r;
@@ -116,7 +115,7 @@
EDX = (EDX & ~0xffff) | r;
}
-void helper_divl_EAX(target_ulong t0)
+void helper_divl_EAX(CPUX86State *env, target_ulong t0)
{
unsigned int den, r;
uint64_t num, q;
@@ -135,7 +134,7 @@
EDX = (uint32_t)r;
}
-void helper_idivl_EAX(target_ulong t0)
+void helper_idivl_EAX(CPUX86State *env, target_ulong t0)
{
int den, r;
int64_t num, q;
@@ -157,7 +156,7 @@
/* bcd */
/* XXX: exception */
-void helper_aam(int base)
+void helper_aam(CPUX86State *env, int base)
{
int al, ah;
@@ -168,7 +167,7 @@
CC_DST = al;
}
-void helper_aad(int base)
+void helper_aad(CPUX86State *env, int base)
{
int al, ah;
@@ -179,13 +178,13 @@
CC_DST = al;
}
-void helper_aaa(void)
+void helper_aaa(CPUX86State *env)
{
int icarry;
int al, ah, af;
int eflags;
- eflags = helper_cc_compute_all(CC_OP);
+ eflags = cpu_cc_compute_all(env, CC_OP);
af = eflags & CC_A;
al = EAX & 0xff;
ah = (EAX >> 8) & 0xff;
@@ -203,13 +202,13 @@
CC_SRC = eflags;
}
-void helper_aas(void)
+void helper_aas(CPUX86State *env)
{
int icarry;
int al, ah, af;
int eflags;
- eflags = helper_cc_compute_all(CC_OP);
+ eflags = cpu_cc_compute_all(env, CC_OP);
af = eflags & CC_A;
al = EAX & 0xff;
ah = (EAX >> 8) & 0xff;
@@ -227,12 +226,12 @@
CC_SRC = eflags;
}
-void helper_daa(void)
+void helper_daa(CPUX86State *env)
{
int old_al, al, af, cf;
int eflags;
- eflags = helper_cc_compute_all(CC_OP);
+ eflags = cpu_cc_compute_all(env, CC_OP);
cf = eflags & CC_C;
af = eflags & CC_A;
old_al = al = EAX & 0xff;
@@ -254,12 +253,12 @@
CC_SRC = eflags;
}
-void helper_das(void)
+void helper_das(CPUX86State *env)
{
int al, al1, af, cf;
int eflags;
- eflags = helper_cc_compute_all(CC_OP);
+ eflags = cpu_cc_compute_all(env, CC_OP);
cf = eflags & CC_C;
af = eflags & CC_A;
al = EAX & 0xff;
@@ -375,7 +374,7 @@
return 0;
}
-void helper_mulq_EAX_T0(target_ulong t0)
+void helper_mulq_EAX_T0(CPUX86State *env, target_ulong t0)
{
uint64_t r0, r1;
@@ -386,7 +385,7 @@
CC_SRC = r1;
}
-void helper_imulq_EAX_T0(target_ulong t0)
+void helper_imulq_EAX_T0(CPUX86State *env, target_ulong t0)
{
uint64_t r0, r1;
@@ -397,7 +396,8 @@
CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
}
-target_ulong helper_imulq_T0_T1(target_ulong t0, target_ulong t1)
+target_ulong helper_imulq_T0_T1(CPUX86State *env, target_ulong t0,
+ target_ulong t1)
{
uint64_t r0, r1;
@@ -407,7 +407,7 @@
return r0;
}
-void helper_divq_EAX(target_ulong t0)
+void helper_divq_EAX(CPUX86State *env, target_ulong t0)
{
uint64_t r0, r1;
@@ -423,7 +423,7 @@
EDX = r1;
}
-void helper_idivq_EAX(target_ulong t0)
+void helper_idivq_EAX(CPUX86State *env, target_ulong t0)
{
uint64_t r0, r1;
diff --git a/target-i386/kvm-stub.c b/target-i386/kvm-stub.c
new file mode 100644
index 0000000..11429c4
--- /dev/null
+++ b/target-i386/kvm-stub.c
@@ -0,0 +1,18 @@
+/*
+ * QEMU KVM x86 specific function stubs
+ *
+ * Copyright Linaro Limited 2012
+ *
+ * Author: Peter Maydell <peter.maydell@linaro.org>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#include "qemu-common.h"
+#include "kvm_i386.h"
+
+bool kvm_allows_irq0_override(void)
+{
+ return 1;
+}
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 4cfb3fa..696b14a 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -23,6 +23,7 @@
#include "qemu-common.h"
#include "sysemu.h"
#include "kvm.h"
+#include "kvm_i386.h"
#include "cpu.h"
#include "gdbstub.h"
#include "host-utils.h"
@@ -65,6 +66,11 @@
static bool has_msr_misc_enable;
static int lm_capable_kernel;
+bool kvm_allows_irq0_override(void)
+{
+ return !kvm_irqchip_in_kernel() || kvm_has_gsi_routing();
+}
+
static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
{
struct kvm_cpuid2 *cpuid;
@@ -2041,4 +2047,11 @@
*/
no_hpet = 1;
}
+ /* We know at this point that we're using the in-kernel
+ * irqchip, so we can use irqfds, and on x86 we know
+ * we can use msi via irqfd and GSI routing.
+ */
+ kvm_irqfds_allowed = true;
+ kvm_msi_via_irqfd_allowed = true;
+ kvm_gsi_routing_allowed = true;
}
diff --git a/target-i386/kvm_i386.h b/target-i386/kvm_i386.h
new file mode 100644
index 0000000..b82bbf4
--- /dev/null
+++ b/target-i386/kvm_i386.h
@@ -0,0 +1,16 @@
+/*
+ * QEMU KVM support -- x86 specific functions.
+ *
+ * Copyright (c) 2012 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_KVM_I386_H
+#define QEMU_KVM_I386_H
+
+bool kvm_allows_irq0_override(void);
+
+#endif
diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
index 91353c0..7f99c7c 100644
--- a/target-i386/mem_helper.c
+++ b/target-i386/mem_helper.c
@@ -18,7 +18,6 @@
*/
#include "cpu.h"
-#include "dyngen-exec.h"
#include "helper.h"
#if !defined(CONFIG_USER_ONLY)
@@ -39,19 +38,19 @@
spin_unlock(&global_cpu_lock);
}
-void helper_cmpxchg8b(target_ulong a0)
+void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
{
uint64_t d;
int eflags;
- eflags = helper_cc_compute_all(CC_OP);
- d = ldq(a0);
+ eflags = cpu_cc_compute_all(env, CC_OP);
+ d = cpu_ldq_data(env, a0);
if (d == (((uint64_t)EDX << 32) | (uint32_t)EAX)) {
- stq(a0, ((uint64_t)ECX << 32) | (uint32_t)EBX);
+ cpu_stq_data(env, a0, ((uint64_t)ECX << 32) | (uint32_t)EBX);
eflags |= CC_Z;
} else {
/* always do the store */
- stq(a0, d);
+ cpu_stq_data(env, a0, d);
EDX = (uint32_t)(d >> 32);
EAX = (uint32_t)d;
eflags &= ~CC_Z;
@@ -60,7 +59,7 @@
}
#ifdef TARGET_X86_64
-void helper_cmpxchg16b(target_ulong a0)
+void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
{
uint64_t d0, d1;
int eflags;
@@ -68,17 +67,17 @@
if ((a0 & 0xf) != 0) {
raise_exception(env, EXCP0D_GPF);
}
- eflags = helper_cc_compute_all(CC_OP);
- d0 = ldq(a0);
- d1 = ldq(a0 + 8);
+ eflags = cpu_cc_compute_all(env, CC_OP);
+ d0 = cpu_ldq_data(env, a0);
+ d1 = cpu_ldq_data(env, a0 + 8);
if (d0 == EAX && d1 == EDX) {
- stq(a0, EBX);
- stq(a0 + 8, ECX);
+ cpu_stq_data(env, a0, EBX);
+ cpu_stq_data(env, a0 + 8, ECX);
eflags |= CC_Z;
} else {
/* always do the store */
- stq(a0, d0);
- stq(a0 + 8, d1);
+ cpu_stq_data(env, a0, d0);
+ cpu_stq_data(env, a0 + 8, d1);
EDX = d1;
EAX = d0;
eflags &= ~CC_Z;
@@ -87,24 +86,24 @@
}
#endif
-void helper_boundw(target_ulong a0, int v)
+void helper_boundw(CPUX86State *env, target_ulong a0, int v)
{
int low, high;
- low = ldsw(a0);
- high = ldsw(a0 + 2);
+ low = cpu_ldsw_data(env, a0);
+ high = cpu_ldsw_data(env, a0 + 2);
v = (int16_t)v;
if (v < low || v > high) {
raise_exception(env, EXCP05_BOUND);
}
}
-void helper_boundl(target_ulong a0, int v)
+void helper_boundl(CPUX86State *env, target_ulong a0, int v)
{
int low, high;
- low = ldl(a0);
- high = ldl(a0 + 4);
+ low = cpu_ldl_data(env, a0);
+ high = cpu_ldl_data(env, a0 + 4);
if (v < low || v > high) {
raise_exception(env, EXCP05_BOUND);
}
@@ -133,15 +132,11 @@
NULL, it means that the function was called in C code (i.e. not
from generated code or from helper.c) */
/* XXX: fix it to restore all registers */
-void tlb_fill(CPUX86State *env1, target_ulong addr, int is_write, int mmu_idx,
+void tlb_fill(CPUX86State *env, target_ulong addr, int is_write, int mmu_idx,
uintptr_t retaddr)
{
TranslationBlock *tb;
int ret;
- CPUX86State *saved_env;
-
- saved_env = env;
- env = env1;
ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx);
if (ret) {
@@ -156,6 +151,5 @@
}
raise_exception_err(env, env->exception_index, env->error_code);
}
- env = saved_env;
}
#endif
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index ce675b7..a020379 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -18,7 +18,6 @@
*/
#include "cpu.h"
-#include "dyngen-exec.h"
#include "ioport.h"
#include "helper.h"
@@ -27,7 +26,7 @@
#endif /* !defined(CONFIG_USER_ONLY) */
/* check if Port I/O is allowed in TSS */
-static inline void check_io(int addr, int size)
+static inline void check_io(CPUX86State *env, int addr, int size)
{
int io_offset, val, mask;
@@ -37,13 +36,13 @@
env->tr.limit < 103) {
goto fail;
}
- io_offset = lduw_kernel(env->tr.base + 0x66);
+ io_offset = cpu_lduw_kernel(env, env->tr.base + 0x66);
io_offset += (addr >> 3);
/* Note: the check needs two bytes */
if ((io_offset + 1) > env->tr.limit) {
goto fail;
}
- val = lduw_kernel(env->tr.base + io_offset);
+ val = cpu_lduw_kernel(env, env->tr.base + io_offset);
val >>= (addr & 7);
mask = (1 << size) - 1;
/* all bits must be zero to allow the I/O */
@@ -53,19 +52,19 @@
}
}
-void helper_check_iob(uint32_t t0)
+void helper_check_iob(CPUX86State *env, uint32_t t0)
{
- check_io(t0, 1);
+ check_io(env, t0, 1);
}
-void helper_check_iow(uint32_t t0)
+void helper_check_iow(CPUX86State *env, uint32_t t0)
{
- check_io(t0, 2);
+ check_io(env, t0, 2);
}
-void helper_check_iol(uint32_t t0)
+void helper_check_iol(CPUX86State *env, uint32_t t0)
{
- check_io(t0, 4);
+ check_io(env, t0, 4);
}
void helper_outb(uint32_t port, uint32_t data)
@@ -98,17 +97,17 @@
return cpu_inl(port);
}
-void helper_into(int next_eip_addend)
+void helper_into(CPUX86State *env, int next_eip_addend)
{
int eflags;
- eflags = helper_cc_compute_all(CC_OP);
+ eflags = cpu_cc_compute_all(env, CC_OP);
if (eflags & CC_O) {
raise_interrupt(env, EXCP04_INTO, 1, 0, next_eip_addend);
}
}
-void helper_single_step(void)
+void helper_single_step(CPUX86State *env)
{
#ifndef CONFIG_USER_ONLY
check_hw_breakpoints(env, 1);
@@ -117,7 +116,7 @@
raise_exception(env, EXCP01_DB);
}
-void helper_cpuid(void)
+void helper_cpuid(CPUX86State *env)
{
uint32_t eax, ebx, ecx, edx;
@@ -131,20 +130,20 @@
}
#if defined(CONFIG_USER_ONLY)
-target_ulong helper_read_crN(int reg)
+target_ulong helper_read_crN(CPUX86State *env, int reg)
{
return 0;
}
-void helper_write_crN(int reg, target_ulong t0)
+void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
{
}
-void helper_movl_drN_T0(int reg, target_ulong t0)
+void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
{
}
#else
-target_ulong helper_read_crN(int reg)
+target_ulong helper_read_crN(CPUX86State *env, int reg)
{
target_ulong val;
@@ -164,7 +163,7 @@
return val;
}
-void helper_write_crN(int reg, target_ulong t0)
+void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
{
cpu_svm_check_intercept_param(env, SVM_EXIT_WRITE_CR0 + reg, 0);
switch (reg) {
@@ -189,7 +188,7 @@
}
}
-void helper_movl_drN_T0(int reg, target_ulong t0)
+void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
{
int i;
@@ -211,21 +210,21 @@
}
#endif
-void helper_lmsw(target_ulong t0)
+void helper_lmsw(CPUX86State *env, target_ulong t0)
{
/* only 4 lower bits of CR0 are modified. PE cannot be set to zero
if already set to one. */
t0 = (env->cr[0] & ~0xe) | (t0 & 0xf);
- helper_write_crN(0, t0);
+ helper_write_crN(env, 0, t0);
}
-void helper_invlpg(target_ulong addr)
+void helper_invlpg(CPUX86State *env, target_ulong addr)
{
cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPG, 0);
tlb_flush_page(env, addr);
}
-void helper_rdtsc(void)
+void helper_rdtsc(CPUX86State *env)
{
uint64_t val;
@@ -239,13 +238,13 @@
EDX = (uint32_t)(val >> 32);
}
-void helper_rdtscp(void)
+void helper_rdtscp(CPUX86State *env)
{
- helper_rdtsc();
+ helper_rdtsc(env);
ECX = (uint32_t)(env->tsc_aux);
}
-void helper_rdpmc(void)
+void helper_rdpmc(CPUX86State *env)
{
if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
raise_exception(env, EXCP0D_GPF);
@@ -258,15 +257,15 @@
}
#if defined(CONFIG_USER_ONLY)
-void helper_wrmsr(void)
+void helper_wrmsr(CPUX86State *env)
{
}
-void helper_rdmsr(void)
+void helper_rdmsr(CPUX86State *env)
{
}
#else
-void helper_wrmsr(void)
+void helper_wrmsr(CPUX86State *env)
{
uint64_t val;
@@ -413,7 +412,7 @@
}
}
-void helper_rdmsr(void)
+void helper_rdmsr(CPUX86State *env)
{
uint64_t val;
@@ -554,7 +553,7 @@
}
#endif
-static void do_hlt(void)
+static void do_hlt(CPUX86State *env)
{
env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
env->halted = 1;
@@ -562,15 +561,15 @@
cpu_loop_exit(env);
}
-void helper_hlt(int next_eip_addend)
+void helper_hlt(CPUX86State *env, int next_eip_addend)
{
cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0);
EIP += next_eip_addend;
- do_hlt();
+ do_hlt(env);
}
-void helper_monitor(target_ulong ptr)
+void helper_monitor(CPUX86State *env, target_ulong ptr)
{
if ((uint32_t)ECX != 0) {
raise_exception(env, EXCP0D_GPF);
@@ -579,7 +578,7 @@
cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0);
}
-void helper_mwait(int next_eip_addend)
+void helper_mwait(CPUX86State *env, int next_eip_addend)
{
if ((uint32_t)ECX != 0) {
raise_exception(env, EXCP0D_GPF);
@@ -592,11 +591,11 @@
/* more than one CPU: do not sleep because another CPU may
wake this one */
} else {
- do_hlt();
+ do_hlt(env);
}
}
-void helper_debug(void)
+void helper_debug(CPUX86State *env)
{
env->exception_index = EXCP_DEBUG;
cpu_loop_exit(env);
diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h
index d109512..cad9d75 100644
--- a/target-i386/ops_sse.h
+++ b/target-i386/ops_sse.h
@@ -35,7 +35,7 @@
#define SUFFIX _xmm
#endif
-void glue(helper_psrlw, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_psrlw, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
int shift;
@@ -59,7 +59,7 @@
}
}
-void glue(helper_psraw, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_psraw, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
int shift;
@@ -80,7 +80,7 @@
#endif
}
-void glue(helper_psllw, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_psllw, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
int shift;
@@ -104,7 +104,7 @@
}
}
-void glue(helper_psrld, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_psrld, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
int shift;
@@ -124,7 +124,7 @@
}
}
-void glue(helper_psrad, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_psrad, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
int shift;
@@ -141,7 +141,7 @@
#endif
}
-void glue(helper_pslld, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_pslld, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
int shift;
@@ -161,7 +161,7 @@
}
}
-void glue(helper_psrlq, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_psrlq, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
int shift;
@@ -179,7 +179,7 @@
}
}
-void glue(helper_psllq, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_psllq, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
int shift;
@@ -198,7 +198,7 @@
}
#if SHIFT == 1
-void glue(helper_psrldq, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_psrldq, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
int shift, i;
@@ -214,7 +214,7 @@
}
}
-void glue(helper_pslldq, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_pslldq, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
int shift, i;
@@ -232,7 +232,7 @@
#endif
#define SSE_HELPER_B(name, F) \
- void glue(name, SUFFIX)(Reg *d, Reg *s) \
+ void glue(name, SUFFIX)(CPUX86State *env, Reg *d, Reg *s) \
{ \
d->B(0) = F(d->B(0), s->B(0)); \
d->B(1) = F(d->B(1), s->B(1)); \
@@ -255,7 +255,7 @@
}
#define SSE_HELPER_W(name, F) \
- void glue(name, SUFFIX)(Reg *d, Reg *s) \
+ void glue(name, SUFFIX)(CPUX86State *env, Reg *d, Reg *s) \
{ \
d->W(0) = F(d->W(0), s->W(0)); \
d->W(1) = F(d->W(1), s->W(1)); \
@@ -270,7 +270,7 @@
}
#define SSE_HELPER_L(name, F) \
- void glue(name, SUFFIX)(Reg *d, Reg *s) \
+ void glue(name, SUFFIX)(CPUX86State *env, Reg *d, Reg *s) \
{ \
d->L(0) = F(d->L(0), s->L(0)); \
d->L(1) = F(d->L(1), s->L(1)); \
@@ -281,7 +281,7 @@
}
#define SSE_HELPER_Q(name, F) \
- void glue(name, SUFFIX)(Reg *d, Reg *s) \
+ void glue(name, SUFFIX)(CPUX86State *env, Reg *d, Reg *s) \
{ \
d->Q(0) = F(d->Q(0), s->Q(0)); \
XMM_ONLY( \
@@ -417,7 +417,7 @@
SSE_HELPER_B(helper_pavgb, FAVG)
SSE_HELPER_W(helper_pavgw, FAVG)
-void glue(helper_pmuludq, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_pmuludq, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
d->Q(0) = (uint64_t)s->L(0) * (uint64_t)d->L(0);
#if SHIFT == 1
@@ -425,7 +425,7 @@
#endif
}
-void glue(helper_pmaddwd, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_pmaddwd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
int i;
@@ -445,7 +445,7 @@
}
}
#endif
-void glue(helper_psadbw, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_psadbw, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
unsigned int val;
@@ -473,13 +473,14 @@
#endif
}
-void glue(helper_maskmov, SUFFIX)(Reg *d, Reg *s, target_ulong a0)
+void glue(helper_maskmov, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
+ target_ulong a0)
{
int i;
for (i = 0; i < (8 << SHIFT); i++) {
if (s->B(i) & 0x80) {
- stb(a0 + i, d->B(i));
+ cpu_stb_data(env, a0 + i, d->B(i));
}
}
}
@@ -575,29 +576,29 @@
/* FPU ops */
/* XXX: not accurate */
-#define SSE_HELPER_S(name, F) \
- void helper_ ## name ## ps(Reg *d, Reg *s) \
- { \
- d->XMM_S(0) = F(32, d->XMM_S(0), s->XMM_S(0)); \
- d->XMM_S(1) = F(32, d->XMM_S(1), s->XMM_S(1)); \
- d->XMM_S(2) = F(32, d->XMM_S(2), s->XMM_S(2)); \
- d->XMM_S(3) = F(32, d->XMM_S(3), s->XMM_S(3)); \
- } \
- \
- void helper_ ## name ## ss(Reg *d, Reg *s) \
- { \
- d->XMM_S(0) = F(32, d->XMM_S(0), s->XMM_S(0)); \
- } \
- \
- void helper_ ## name ## pd(Reg *d, Reg *s) \
- { \
- d->XMM_D(0) = F(64, d->XMM_D(0), s->XMM_D(0)); \
- d->XMM_D(1) = F(64, d->XMM_D(1), s->XMM_D(1)); \
- } \
- \
- void helper_ ## name ## sd(Reg *d, Reg *s) \
- { \
- d->XMM_D(0) = F(64, d->XMM_D(0), s->XMM_D(0)); \
+#define SSE_HELPER_S(name, F) \
+ void helper_ ## name ## ps(CPUX86State *env, Reg *d, Reg *s) \
+ { \
+ d->XMM_S(0) = F(32, d->XMM_S(0), s->XMM_S(0)); \
+ d->XMM_S(1) = F(32, d->XMM_S(1), s->XMM_S(1)); \
+ d->XMM_S(2) = F(32, d->XMM_S(2), s->XMM_S(2)); \
+ d->XMM_S(3) = F(32, d->XMM_S(3), s->XMM_S(3)); \
+ } \
+ \
+ void helper_ ## name ## ss(CPUX86State *env, Reg *d, Reg *s) \
+ { \
+ d->XMM_S(0) = F(32, d->XMM_S(0), s->XMM_S(0)); \
+ } \
+ \
+ void helper_ ## name ## pd(CPUX86State *env, Reg *d, Reg *s) \
+ { \
+ d->XMM_D(0) = F(64, d->XMM_D(0), s->XMM_D(0)); \
+ d->XMM_D(1) = F(64, d->XMM_D(1), s->XMM_D(1)); \
+ } \
+ \
+ void helper_ ## name ## sd(CPUX86State *env, Reg *d, Reg *s) \
+ { \
+ d->XMM_D(0) = F(64, d->XMM_D(0), s->XMM_D(0)); \
}
#define FPU_ADD(size, a, b) float ## size ## _add(a, b, &env->sse_status)
@@ -625,7 +626,7 @@
/* float to float conversions */
-void helper_cvtps2pd(Reg *d, Reg *s)
+void helper_cvtps2pd(CPUX86State *env, Reg *d, Reg *s)
{
float32 s0, s1;
@@ -635,25 +636,25 @@
d->XMM_D(1) = float32_to_float64(s1, &env->sse_status);
}
-void helper_cvtpd2ps(Reg *d, Reg *s)
+void helper_cvtpd2ps(CPUX86State *env, Reg *d, Reg *s)
{
d->XMM_S(0) = float64_to_float32(s->XMM_D(0), &env->sse_status);
d->XMM_S(1) = float64_to_float32(s->XMM_D(1), &env->sse_status);
d->Q(1) = 0;
}
-void helper_cvtss2sd(Reg *d, Reg *s)
+void helper_cvtss2sd(CPUX86State *env, Reg *d, Reg *s)
{
d->XMM_D(0) = float32_to_float64(s->XMM_S(0), &env->sse_status);
}
-void helper_cvtsd2ss(Reg *d, Reg *s)
+void helper_cvtsd2ss(CPUX86State *env, Reg *d, Reg *s)
{
d->XMM_S(0) = float64_to_float32(s->XMM_D(0), &env->sse_status);
}
/* integer to float */
-void helper_cvtdq2ps(Reg *d, Reg *s)
+void helper_cvtdq2ps(CPUX86State *env, Reg *d, Reg *s)
{
d->XMM_S(0) = int32_to_float32(s->XMM_L(0), &env->sse_status);
d->XMM_S(1) = int32_to_float32(s->XMM_L(1), &env->sse_status);
@@ -661,7 +662,7 @@
d->XMM_S(3) = int32_to_float32(s->XMM_L(3), &env->sse_status);
}
-void helper_cvtdq2pd(Reg *d, Reg *s)
+void helper_cvtdq2pd(CPUX86State *env, Reg *d, Reg *s)
{
int32_t l0, l1;
@@ -671,42 +672,42 @@
d->XMM_D(1) = int32_to_float64(l1, &env->sse_status);
}
-void helper_cvtpi2ps(XMMReg *d, MMXReg *s)
+void helper_cvtpi2ps(CPUX86State *env, XMMReg *d, MMXReg *s)
{
d->XMM_S(0) = int32_to_float32(s->MMX_L(0), &env->sse_status);
d->XMM_S(1) = int32_to_float32(s->MMX_L(1), &env->sse_status);
}
-void helper_cvtpi2pd(XMMReg *d, MMXReg *s)
+void helper_cvtpi2pd(CPUX86State *env, XMMReg *d, MMXReg *s)
{
d->XMM_D(0) = int32_to_float64(s->MMX_L(0), &env->sse_status);
d->XMM_D(1) = int32_to_float64(s->MMX_L(1), &env->sse_status);
}
-void helper_cvtsi2ss(XMMReg *d, uint32_t val)
+void helper_cvtsi2ss(CPUX86State *env, XMMReg *d, uint32_t val)
{
d->XMM_S(0) = int32_to_float32(val, &env->sse_status);
}
-void helper_cvtsi2sd(XMMReg *d, uint32_t val)
+void helper_cvtsi2sd(CPUX86State *env, XMMReg *d, uint32_t val)
{
d->XMM_D(0) = int32_to_float64(val, &env->sse_status);
}
#ifdef TARGET_X86_64
-void helper_cvtsq2ss(XMMReg *d, uint64_t val)
+void helper_cvtsq2ss(CPUX86State *env, XMMReg *d, uint64_t val)
{
d->XMM_S(0) = int64_to_float32(val, &env->sse_status);
}
-void helper_cvtsq2sd(XMMReg *d, uint64_t val)
+void helper_cvtsq2sd(CPUX86State *env, XMMReg *d, uint64_t val)
{
d->XMM_D(0) = int64_to_float64(val, &env->sse_status);
}
#endif
/* float to integer */
-void helper_cvtps2dq(XMMReg *d, XMMReg *s)
+void helper_cvtps2dq(CPUX86State *env, XMMReg *d, XMMReg *s)
{
d->XMM_L(0) = float32_to_int32(s->XMM_S(0), &env->sse_status);
d->XMM_L(1) = float32_to_int32(s->XMM_S(1), &env->sse_status);
@@ -714,49 +715,49 @@
d->XMM_L(3) = float32_to_int32(s->XMM_S(3), &env->sse_status);
}
-void helper_cvtpd2dq(XMMReg *d, XMMReg *s)
+void helper_cvtpd2dq(CPUX86State *env, XMMReg *d, XMMReg *s)
{
d->XMM_L(0) = float64_to_int32(s->XMM_D(0), &env->sse_status);
d->XMM_L(1) = float64_to_int32(s->XMM_D(1), &env->sse_status);
d->XMM_Q(1) = 0;
}
-void helper_cvtps2pi(MMXReg *d, XMMReg *s)
+void helper_cvtps2pi(CPUX86State *env, MMXReg *d, XMMReg *s)
{
d->MMX_L(0) = float32_to_int32(s->XMM_S(0), &env->sse_status);
d->MMX_L(1) = float32_to_int32(s->XMM_S(1), &env->sse_status);
}
-void helper_cvtpd2pi(MMXReg *d, XMMReg *s)
+void helper_cvtpd2pi(CPUX86State *env, MMXReg *d, XMMReg *s)
{
d->MMX_L(0) = float64_to_int32(s->XMM_D(0), &env->sse_status);
d->MMX_L(1) = float64_to_int32(s->XMM_D(1), &env->sse_status);
}
-int32_t helper_cvtss2si(XMMReg *s)
+int32_t helper_cvtss2si(CPUX86State *env, XMMReg *s)
{
return float32_to_int32(s->XMM_S(0), &env->sse_status);
}
-int32_t helper_cvtsd2si(XMMReg *s)
+int32_t helper_cvtsd2si(CPUX86State *env, XMMReg *s)
{
return float64_to_int32(s->XMM_D(0), &env->sse_status);
}
#ifdef TARGET_X86_64
-int64_t helper_cvtss2sq(XMMReg *s)
+int64_t helper_cvtss2sq(CPUX86State *env, XMMReg *s)
{
return float32_to_int64(s->XMM_S(0), &env->sse_status);
}
-int64_t helper_cvtsd2sq(XMMReg *s)
+int64_t helper_cvtsd2sq(CPUX86State *env, XMMReg *s)
{
return float64_to_int64(s->XMM_D(0), &env->sse_status);
}
#endif
/* float to integer truncated */
-void helper_cvttps2dq(XMMReg *d, XMMReg *s)
+void helper_cvttps2dq(CPUX86State *env, XMMReg *d, XMMReg *s)
{
d->XMM_L(0) = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
d->XMM_L(1) = float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status);
@@ -764,48 +765,48 @@
d->XMM_L(3) = float32_to_int32_round_to_zero(s->XMM_S(3), &env->sse_status);
}
-void helper_cvttpd2dq(XMMReg *d, XMMReg *s)
+void helper_cvttpd2dq(CPUX86State *env, XMMReg *d, XMMReg *s)
{
d->XMM_L(0) = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
d->XMM_L(1) = float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status);
d->XMM_Q(1) = 0;
}
-void helper_cvttps2pi(MMXReg *d, XMMReg *s)
+void helper_cvttps2pi(CPUX86State *env, MMXReg *d, XMMReg *s)
{
d->MMX_L(0) = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
d->MMX_L(1) = float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status);
}
-void helper_cvttpd2pi(MMXReg *d, XMMReg *s)
+void helper_cvttpd2pi(CPUX86State *env, MMXReg *d, XMMReg *s)
{
d->MMX_L(0) = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
d->MMX_L(1) = float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status);
}
-int32_t helper_cvttss2si(XMMReg *s)
+int32_t helper_cvttss2si(CPUX86State *env, XMMReg *s)
{
return float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
}
-int32_t helper_cvttsd2si(XMMReg *s)
+int32_t helper_cvttsd2si(CPUX86State *env, XMMReg *s)
{
return float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
}
#ifdef TARGET_X86_64
-int64_t helper_cvttss2sq(XMMReg *s)
+int64_t helper_cvttss2sq(CPUX86State *env, XMMReg *s)
{
return float32_to_int64_round_to_zero(s->XMM_S(0), &env->sse_status);
}
-int64_t helper_cvttsd2sq(XMMReg *s)
+int64_t helper_cvttsd2sq(CPUX86State *env, XMMReg *s)
{
return float64_to_int64_round_to_zero(s->XMM_D(0), &env->sse_status);
}
#endif
-void helper_rsqrtps(XMMReg *d, XMMReg *s)
+void helper_rsqrtps(CPUX86State *env, XMMReg *d, XMMReg *s)
{
d->XMM_S(0) = float32_div(float32_one,
float32_sqrt(s->XMM_S(0), &env->sse_status),
@@ -821,14 +822,14 @@
&env->sse_status);
}
-void helper_rsqrtss(XMMReg *d, XMMReg *s)
+void helper_rsqrtss(CPUX86State *env, XMMReg *d, XMMReg *s)
{
d->XMM_S(0) = float32_div(float32_one,
float32_sqrt(s->XMM_S(0), &env->sse_status),
&env->sse_status);
}
-void helper_rcpps(XMMReg *d, XMMReg *s)
+void helper_rcpps(CPUX86State *env, XMMReg *d, XMMReg *s)
{
d->XMM_S(0) = float32_div(float32_one, s->XMM_S(0), &env->sse_status);
d->XMM_S(1) = float32_div(float32_one, s->XMM_S(1), &env->sse_status);
@@ -836,7 +837,7 @@
d->XMM_S(3) = float32_div(float32_one, s->XMM_S(3), &env->sse_status);
}
-void helper_rcpss(XMMReg *d, XMMReg *s)
+void helper_rcpss(CPUX86State *env, XMMReg *d, XMMReg *s)
{
d->XMM_S(0) = float32_div(float32_one, s->XMM_S(0), &env->sse_status);
}
@@ -853,12 +854,12 @@
return (src >> shift) & mask;
}
-void helper_extrq_r(XMMReg *d, XMMReg *s)
+void helper_extrq_r(CPUX86State *env, XMMReg *d, XMMReg *s)
{
d->XMM_Q(0) = helper_extrq(d->XMM_Q(0), s->XMM_B(1), s->XMM_B(0));
}
-void helper_extrq_i(XMMReg *d, int index, int length)
+void helper_extrq_i(CPUX86State *env, XMMReg *d, int index, int length)
{
d->XMM_Q(0) = helper_extrq(d->XMM_Q(0), index, length);
}
@@ -875,17 +876,17 @@
return (src & ~(mask << shift)) | ((src & mask) << shift);
}
-void helper_insertq_r(XMMReg *d, XMMReg *s)
+void helper_insertq_r(CPUX86State *env, XMMReg *d, XMMReg *s)
{
d->XMM_Q(0) = helper_insertq(s->XMM_Q(0), s->XMM_B(9), s->XMM_B(8));
}
-void helper_insertq_i(XMMReg *d, int index, int length)
+void helper_insertq_i(CPUX86State *env, XMMReg *d, int index, int length)
{
d->XMM_Q(0) = helper_insertq(d->XMM_Q(0), index, length);
}
-void helper_haddps(XMMReg *d, XMMReg *s)
+void helper_haddps(CPUX86State *env, XMMReg *d, XMMReg *s)
{
XMMReg r;
@@ -896,7 +897,7 @@
*d = r;
}
-void helper_haddpd(XMMReg *d, XMMReg *s)
+void helper_haddpd(CPUX86State *env, XMMReg *d, XMMReg *s)
{
XMMReg r;
@@ -905,7 +906,7 @@
*d = r;
}
-void helper_hsubps(XMMReg *d, XMMReg *s)
+void helper_hsubps(CPUX86State *env, XMMReg *d, XMMReg *s)
{
XMMReg r;
@@ -916,7 +917,7 @@
*d = r;
}
-void helper_hsubpd(XMMReg *d, XMMReg *s)
+void helper_hsubpd(CPUX86State *env, XMMReg *d, XMMReg *s)
{
XMMReg r;
@@ -925,7 +926,7 @@
*d = r;
}
-void helper_addsubps(XMMReg *d, XMMReg *s)
+void helper_addsubps(CPUX86State *env, XMMReg *d, XMMReg *s)
{
d->XMM_S(0) = float32_sub(d->XMM_S(0), s->XMM_S(0), &env->sse_status);
d->XMM_S(1) = float32_add(d->XMM_S(1), s->XMM_S(1), &env->sse_status);
@@ -933,36 +934,36 @@
d->XMM_S(3) = float32_add(d->XMM_S(3), s->XMM_S(3), &env->sse_status);
}
-void helper_addsubpd(XMMReg *d, XMMReg *s)
+void helper_addsubpd(CPUX86State *env, XMMReg *d, XMMReg *s)
{
d->XMM_D(0) = float64_sub(d->XMM_D(0), s->XMM_D(0), &env->sse_status);
d->XMM_D(1) = float64_add(d->XMM_D(1), s->XMM_D(1), &env->sse_status);
}
/* XXX: unordered */
-#define SSE_HELPER_CMP(name, F) \
- void helper_ ## name ## ps(Reg *d, Reg *s) \
- { \
- d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0)); \
- d->XMM_L(1) = F(32, d->XMM_S(1), s->XMM_S(1)); \
- d->XMM_L(2) = F(32, d->XMM_S(2), s->XMM_S(2)); \
- d->XMM_L(3) = F(32, d->XMM_S(3), s->XMM_S(3)); \
- } \
- \
- void helper_ ## name ## ss(Reg *d, Reg *s) \
- { \
- d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0)); \
- } \
- \
- void helper_ ## name ## pd(Reg *d, Reg *s) \
- { \
- d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0)); \
- d->XMM_Q(1) = F(64, d->XMM_D(1), s->XMM_D(1)); \
- } \
- \
- void helper_ ## name ## sd(Reg *d, Reg *s) \
- { \
- d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0)); \
+#define SSE_HELPER_CMP(name, F) \
+ void helper_ ## name ## ps(CPUX86State *env, Reg *d, Reg *s) \
+ { \
+ d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0)); \
+ d->XMM_L(1) = F(32, d->XMM_S(1), s->XMM_S(1)); \
+ d->XMM_L(2) = F(32, d->XMM_S(2), s->XMM_S(2)); \
+ d->XMM_L(3) = F(32, d->XMM_S(3), s->XMM_S(3)); \
+ } \
+ \
+ void helper_ ## name ## ss(CPUX86State *env, Reg *d, Reg *s) \
+ { \
+ d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0)); \
+ } \
+ \
+ void helper_ ## name ## pd(CPUX86State *env, Reg *d, Reg *s) \
+ { \
+ d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0)); \
+ d->XMM_Q(1) = F(64, d->XMM_D(1), s->XMM_D(1)); \
+ } \
+ \
+ void helper_ ## name ## sd(CPUX86State *env, Reg *d, Reg *s) \
+ { \
+ d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0)); \
}
#define FPU_CMPEQ(size, a, b) \
@@ -993,7 +994,7 @@
static const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C};
-void helper_ucomiss(Reg *d, Reg *s)
+void helper_ucomiss(CPUX86State *env, Reg *d, Reg *s)
{
int ret;
float32 s0, s1;
@@ -1004,7 +1005,7 @@
CC_SRC = comis_eflags[ret + 1];
}
-void helper_comiss(Reg *d, Reg *s)
+void helper_comiss(CPUX86State *env, Reg *d, Reg *s)
{
int ret;
float32 s0, s1;
@@ -1015,7 +1016,7 @@
CC_SRC = comis_eflags[ret + 1];
}
-void helper_ucomisd(Reg *d, Reg *s)
+void helper_ucomisd(CPUX86State *env, Reg *d, Reg *s)
{
int ret;
float64 d0, d1;
@@ -1026,7 +1027,7 @@
CC_SRC = comis_eflags[ret + 1];
}
-void helper_comisd(Reg *d, Reg *s)
+void helper_comisd(CPUX86State *env, Reg *d, Reg *s)
{
int ret;
float64 d0, d1;
@@ -1037,7 +1038,7 @@
CC_SRC = comis_eflags[ret + 1];
}
-uint32_t helper_movmskps(Reg *s)
+uint32_t helper_movmskps(CPUX86State *env, Reg *s)
{
int b0, b1, b2, b3;
@@ -1048,7 +1049,7 @@
return b0 | (b1 << 1) | (b2 << 2) | (b3 << 3);
}
-uint32_t helper_movmskpd(Reg *s)
+uint32_t helper_movmskpd(CPUX86State *env, Reg *s)
{
int b0, b1;
@@ -1059,7 +1060,7 @@
#endif
-uint32_t glue(helper_pmovmskb, SUFFIX)(Reg *s)
+uint32_t glue(helper_pmovmskb, SUFFIX)(CPUX86State *env, Reg *s)
{
uint32_t val;
@@ -1085,7 +1086,7 @@
return val;
}
-void glue(helper_packsswb, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_packsswb, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
Reg r;
@@ -1112,7 +1113,7 @@
*d = r;
}
-void glue(helper_packuswb, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_packuswb, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
Reg r;
@@ -1139,7 +1140,7 @@
*d = r;
}
-void glue(helper_packssdw, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_packssdw, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
Reg r;
@@ -1160,7 +1161,8 @@
#define UNPCK_OP(base_name, base) \
\
- void glue(helper_punpck ## base_name ## bw, SUFFIX)(Reg *d, Reg *s) \
+ void glue(helper_punpck ## base_name ## bw, SUFFIX)(CPUX86State *env,\
+ Reg *d, Reg *s) \
{ \
Reg r; \
\
@@ -1181,11 +1183,12 @@
r.B(13) = s->B((base << (SHIFT + 2)) + 6); \
r.B(14) = d->B((base << (SHIFT + 2)) + 7); \
r.B(15) = s->B((base << (SHIFT + 2)) + 7); \
- ) \
+ ) \
*d = r; \
} \
\
- void glue(helper_punpck ## base_name ## wd, SUFFIX)(Reg *d, Reg *s) \
+ void glue(helper_punpck ## base_name ## wd, SUFFIX)(CPUX86State *env,\
+ Reg *d, Reg *s) \
{ \
Reg r; \
\
@@ -1198,11 +1201,12 @@
r.W(5) = s->W((base << (SHIFT + 1)) + 2); \
r.W(6) = d->W((base << (SHIFT + 1)) + 3); \
r.W(7) = s->W((base << (SHIFT + 1)) + 3); \
- ) \
+ ) \
*d = r; \
} \
\
- void glue(helper_punpck ## base_name ## dq, SUFFIX)(Reg *d, Reg *s) \
+ void glue(helper_punpck ## base_name ## dq, SUFFIX)(CPUX86State *env,\
+ Reg *d, Reg *s) \
{ \
Reg r; \
\
@@ -1211,12 +1215,14 @@
XMM_ONLY( \
r.L(2) = d->L((base << SHIFT) + 1); \
r.L(3) = s->L((base << SHIFT) + 1); \
- ) \
+ ) \
*d = r; \
} \
\
XMM_ONLY( \
- void glue(helper_punpck ## base_name ## qdq, SUFFIX)(Reg *d, \
+ void glue(helper_punpck ## base_name ## qdq, SUFFIX)(CPUX86State \
+ *env, \
+ Reg *d, \
Reg *s) \
{ \
Reg r; \
@@ -1232,25 +1238,25 @@
/* 3DNow! float ops */
#if SHIFT == 0
-void helper_pi2fd(MMXReg *d, MMXReg *s)
+void helper_pi2fd(CPUX86State *env, MMXReg *d, MMXReg *s)
{
d->MMX_S(0) = int32_to_float32(s->MMX_L(0), &env->mmx_status);
d->MMX_S(1) = int32_to_float32(s->MMX_L(1), &env->mmx_status);
}
-void helper_pi2fw(MMXReg *d, MMXReg *s)
+void helper_pi2fw(CPUX86State *env, MMXReg *d, MMXReg *s)
{
d->MMX_S(0) = int32_to_float32((int16_t)s->MMX_W(0), &env->mmx_status);
d->MMX_S(1) = int32_to_float32((int16_t)s->MMX_W(2), &env->mmx_status);
}
-void helper_pf2id(MMXReg *d, MMXReg *s)
+void helper_pf2id(CPUX86State *env, MMXReg *d, MMXReg *s)
{
d->MMX_L(0) = float32_to_int32_round_to_zero(s->MMX_S(0), &env->mmx_status);
d->MMX_L(1) = float32_to_int32_round_to_zero(s->MMX_S(1), &env->mmx_status);
}
-void helper_pf2iw(MMXReg *d, MMXReg *s)
+void helper_pf2iw(CPUX86State *env, MMXReg *d, MMXReg *s)
{
d->MMX_L(0) = satsw(float32_to_int32_round_to_zero(s->MMX_S(0),
&env->mmx_status));
@@ -1258,7 +1264,7 @@
&env->mmx_status));
}
-void helper_pfacc(MMXReg *d, MMXReg *s)
+void helper_pfacc(CPUX86State *env, MMXReg *d, MMXReg *s)
{
MMXReg r;
@@ -1267,13 +1273,13 @@
*d = r;
}
-void helper_pfadd(MMXReg *d, MMXReg *s)
+void helper_pfadd(CPUX86State *env, MMXReg *d, MMXReg *s)
{
d->MMX_S(0) = float32_add(d->MMX_S(0), s->MMX_S(0), &env->mmx_status);
d->MMX_S(1) = float32_add(d->MMX_S(1), s->MMX_S(1), &env->mmx_status);
}
-void helper_pfcmpeq(MMXReg *d, MMXReg *s)
+void helper_pfcmpeq(CPUX86State *env, MMXReg *d, MMXReg *s)
{
d->MMX_L(0) = float32_eq_quiet(d->MMX_S(0), s->MMX_S(0),
&env->mmx_status) ? -1 : 0;
@@ -1281,7 +1287,7 @@
&env->mmx_status) ? -1 : 0;
}
-void helper_pfcmpge(MMXReg *d, MMXReg *s)
+void helper_pfcmpge(CPUX86State *env, MMXReg *d, MMXReg *s)
{
d->MMX_L(0) = float32_le(s->MMX_S(0), d->MMX_S(0),
&env->mmx_status) ? -1 : 0;
@@ -1289,7 +1295,7 @@
&env->mmx_status) ? -1 : 0;
}
-void helper_pfcmpgt(MMXReg *d, MMXReg *s)
+void helper_pfcmpgt(CPUX86State *env, MMXReg *d, MMXReg *s)
{
d->MMX_L(0) = float32_lt(s->MMX_S(0), d->MMX_S(0),
&env->mmx_status) ? -1 : 0;
@@ -1297,7 +1303,7 @@
&env->mmx_status) ? -1 : 0;
}
-void helper_pfmax(MMXReg *d, MMXReg *s)
+void helper_pfmax(CPUX86State *env, MMXReg *d, MMXReg *s)
{
if (float32_lt(d->MMX_S(0), s->MMX_S(0), &env->mmx_status)) {
d->MMX_S(0) = s->MMX_S(0);
@@ -1307,7 +1313,7 @@
}
}
-void helper_pfmin(MMXReg *d, MMXReg *s)
+void helper_pfmin(CPUX86State *env, MMXReg *d, MMXReg *s)
{
if (float32_lt(s->MMX_S(0), d->MMX_S(0), &env->mmx_status)) {
d->MMX_S(0) = s->MMX_S(0);
@@ -1317,13 +1323,13 @@
}
}
-void helper_pfmul(MMXReg *d, MMXReg *s)
+void helper_pfmul(CPUX86State *env, MMXReg *d, MMXReg *s)
{
d->MMX_S(0) = float32_mul(d->MMX_S(0), s->MMX_S(0), &env->mmx_status);
d->MMX_S(1) = float32_mul(d->MMX_S(1), s->MMX_S(1), &env->mmx_status);
}
-void helper_pfnacc(MMXReg *d, MMXReg *s)
+void helper_pfnacc(CPUX86State *env, MMXReg *d, MMXReg *s)
{
MMXReg r;
@@ -1332,7 +1338,7 @@
*d = r;
}
-void helper_pfpnacc(MMXReg *d, MMXReg *s)
+void helper_pfpnacc(CPUX86State *env, MMXReg *d, MMXReg *s)
{
MMXReg r;
@@ -1341,13 +1347,13 @@
*d = r;
}
-void helper_pfrcp(MMXReg *d, MMXReg *s)
+void helper_pfrcp(CPUX86State *env, MMXReg *d, MMXReg *s)
{
d->MMX_S(0) = float32_div(float32_one, s->MMX_S(0), &env->mmx_status);
d->MMX_S(1) = d->MMX_S(0);
}
-void helper_pfrsqrt(MMXReg *d, MMXReg *s)
+void helper_pfrsqrt(CPUX86State *env, MMXReg *d, MMXReg *s)
{
d->MMX_L(1) = s->MMX_L(0) & 0x7fffffff;
d->MMX_S(1) = float32_div(float32_one,
@@ -1357,19 +1363,19 @@
d->MMX_L(0) = d->MMX_L(1);
}
-void helper_pfsub(MMXReg *d, MMXReg *s)
+void helper_pfsub(CPUX86State *env, MMXReg *d, MMXReg *s)
{
d->MMX_S(0) = float32_sub(d->MMX_S(0), s->MMX_S(0), &env->mmx_status);
d->MMX_S(1) = float32_sub(d->MMX_S(1), s->MMX_S(1), &env->mmx_status);
}
-void helper_pfsubr(MMXReg *d, MMXReg *s)
+void helper_pfsubr(CPUX86State *env, MMXReg *d, MMXReg *s)
{
d->MMX_S(0) = float32_sub(s->MMX_S(0), d->MMX_S(0), &env->mmx_status);
d->MMX_S(1) = float32_sub(s->MMX_S(1), d->MMX_S(1), &env->mmx_status);
}
-void helper_pswapd(MMXReg *d, MMXReg *s)
+void helper_pswapd(CPUX86State *env, MMXReg *d, MMXReg *s)
{
MMXReg r;
@@ -1380,7 +1386,7 @@
#endif
/* SSSE3 op helpers */
-void glue(helper_pshufb, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_pshufb, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
int i;
Reg r;
@@ -1392,7 +1398,7 @@
*d = r;
}
-void glue(helper_phaddw, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_phaddw, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
d->W(0) = (int16_t)d->W(0) + (int16_t)d->W(1);
d->W(1) = (int16_t)d->W(2) + (int16_t)d->W(3);
@@ -1404,7 +1410,7 @@
XMM_ONLY(d->W(7) = (int16_t)s->W(6) + (int16_t)s->W(7));
}
-void glue(helper_phaddd, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_phaddd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
d->L(0) = (int32_t)d->L(0) + (int32_t)d->L(1);
XMM_ONLY(d->L(1) = (int32_t)d->L(2) + (int32_t)d->L(3));
@@ -1412,7 +1418,7 @@
XMM_ONLY(d->L(3) = (int32_t)s->L(2) + (int32_t)s->L(3));
}
-void glue(helper_phaddsw, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_phaddsw, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
d->W(0) = satsw((int16_t)d->W(0) + (int16_t)d->W(1));
d->W(1) = satsw((int16_t)d->W(2) + (int16_t)d->W(3));
@@ -1424,7 +1430,7 @@
XMM_ONLY(d->W(7) = satsw((int16_t)s->W(6) + (int16_t)s->W(7)));
}
-void glue(helper_pmaddubsw, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_pmaddubsw, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
d->W(0) = satsw((int8_t)s->B(0) * (uint8_t)d->B(0) +
(int8_t)s->B(1) * (uint8_t)d->B(1));
@@ -1446,7 +1452,7 @@
#endif
}
-void glue(helper_phsubw, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_phsubw, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
d->W(0) = (int16_t)d->W(0) - (int16_t)d->W(1);
d->W(1) = (int16_t)d->W(2) - (int16_t)d->W(3);
@@ -1458,7 +1464,7 @@
XMM_ONLY(d->W(7) = (int16_t)s->W(6) - (int16_t)s->W(7));
}
-void glue(helper_phsubd, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_phsubd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
d->L(0) = (int32_t)d->L(0) - (int32_t)d->L(1);
XMM_ONLY(d->L(1) = (int32_t)d->L(2) - (int32_t)d->L(3));
@@ -1466,7 +1472,7 @@
XMM_ONLY(d->L(3) = (int32_t)s->L(2) - (int32_t)s->L(3));
}
-void glue(helper_phsubsw, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_phsubsw, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
d->W(0) = satsw((int16_t)d->W(0) - (int16_t)d->W(1));
d->W(1) = satsw((int16_t)d->W(2) - (int16_t)d->W(3));
@@ -1495,7 +1501,8 @@
SSE_HELPER_W(helper_psignw, FSIGNW)
SSE_HELPER_L(helper_psignd, FSIGNL)
-void glue(helper_palignr, SUFFIX)(Reg *d, Reg *s, int32_t shift)
+void glue(helper_palignr, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
+ int32_t shift)
{
Reg r;
@@ -1529,7 +1536,7 @@
#if SHIFT == 1
#define SSE_HELPER_V(name, elem, num, F) \
- void glue(name, SUFFIX)(Reg *d, Reg *s) \
+ void glue(name, SUFFIX)(CPUX86State *env, Reg *d, Reg *s) \
{ \
d->elem(0) = F(d->elem(0), s->elem(0), XMM0.elem(0)); \
d->elem(1) = F(d->elem(1), s->elem(1), XMM0.elem(1)); \
@@ -1556,7 +1563,7 @@
}
#define SSE_HELPER_I(name, elem, num, F) \
- void glue(name, SUFFIX)(Reg *d, Reg *s, uint32_t imm) \
+ void glue(name, SUFFIX)(CPUX86State *env, Reg *d, Reg *s, uint32_t imm) \
{ \
d->elem(0) = F(d->elem(0), s->elem(0), ((imm >> 0) & 1)); \
d->elem(1) = F(d->elem(1), s->elem(1), ((imm >> 1) & 1)); \
@@ -1596,7 +1603,7 @@
SSE_HELPER_V(helper_blendvps, L, 4, FBLENDVPS)
SSE_HELPER_V(helper_blendvpd, Q, 2, FBLENDVPD)
-void glue(helper_ptest, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_ptest, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
uint64_t zf = (s->Q(0) & d->Q(0)) | (s->Q(1) & d->Q(1));
uint64_t cf = (s->Q(0) & ~d->Q(0)) | (s->Q(1) & ~d->Q(1));
@@ -1605,7 +1612,7 @@
}
#define SSE_HELPER_F(name, elem, num, F) \
- void glue(name, SUFFIX)(Reg *d, Reg *s) \
+ void glue(name, SUFFIX)(CPUX86State *env, Reg *d, Reg *s) \
{ \
d->elem(0) = F(0); \
d->elem(1) = F(1); \
@@ -1634,7 +1641,7 @@
SSE_HELPER_F(helper_pmovzxwq, Q, 2, s->W)
SSE_HELPER_F(helper_pmovzxdq, Q, 2, s->L)
-void glue(helper_pmuldq, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_pmuldq, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
d->Q(0) = (int64_t)(int32_t) d->L(0) * (int32_t) s->L(0);
d->Q(1) = (int64_t)(int32_t) d->L(2) * (int32_t) s->L(2);
@@ -1643,7 +1650,7 @@
#define FCMPEQQ(d, s) (d == s ? -1 : 0)
SSE_HELPER_Q(helper_pcmpeqq, FCMPEQQ)
-void glue(helper_packusdw, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_packusdw, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
d->W(0) = satuw((int32_t) d->L(0));
d->W(1) = satuw((int32_t) d->L(1));
@@ -1671,7 +1678,7 @@
#define FMULLD(d, s) ((int32_t)d * (int32_t)s)
SSE_HELPER_L(helper_pmulld, FMULLD)
-void glue(helper_phminposuw, SUFFIX)(Reg *d, Reg *s)
+void glue(helper_phminposuw, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
{
int idx = 0;
@@ -1703,7 +1710,8 @@
d->W(0) = s->W(idx);
}
-void glue(helper_roundps, SUFFIX)(Reg *d, Reg *s, uint32_t mode)
+void glue(helper_roundps, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
+ uint32_t mode)
{
signed char prev_rounding_mode;
@@ -1740,7 +1748,8 @@
env->sse_status.float_rounding_mode = prev_rounding_mode;
}
-void glue(helper_roundpd, SUFFIX)(Reg *d, Reg *s, uint32_t mode)
+void glue(helper_roundpd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
+ uint32_t mode)
{
signed char prev_rounding_mode;
@@ -1775,7 +1784,8 @@
env->sse_status.float_rounding_mode = prev_rounding_mode;
}
-void glue(helper_roundss, SUFFIX)(Reg *d, Reg *s, uint32_t mode)
+void glue(helper_roundss, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
+ uint32_t mode)
{
signed char prev_rounding_mode;
@@ -1809,7 +1819,8 @@
env->sse_status.float_rounding_mode = prev_rounding_mode;
}
-void glue(helper_roundsd, SUFFIX)(Reg *d, Reg *s, uint32_t mode)
+void glue(helper_roundsd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
+ uint32_t mode)
{
signed char prev_rounding_mode;
@@ -1848,7 +1859,7 @@
SSE_HELPER_I(helper_blendpd, Q, 2, FBLENDP)
SSE_HELPER_I(helper_pblendw, W, 8, FBLENDP)
-void glue(helper_dpps, SUFFIX)(Reg *d, Reg *s, uint32_t mask)
+void glue(helper_dpps, SUFFIX)(CPUX86State *env, Reg *d, Reg *s, uint32_t mask)
{
float32 iresult = float32_zero;
@@ -1882,7 +1893,7 @@
d->XMM_S(3) = (mask & (1 << 3)) ? iresult : float32_zero;
}
-void glue(helper_dppd, SUFFIX)(Reg *d, Reg *s, uint32_t mask)
+void glue(helper_dppd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s, uint32_t mask)
{
float64 iresult = float64_zero;
@@ -1902,7 +1913,8 @@
d->XMM_D(1) = (mask & (1 << 1)) ? iresult : float64_zero;
}
-void glue(helper_mpsadbw, SUFFIX)(Reg *d, Reg *s, uint32_t offset)
+void glue(helper_mpsadbw, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
+ uint32_t offset)
{
int s0 = (offset & 3) << 2;
int d0 = (offset & 4) << 0;
@@ -1925,7 +1937,7 @@
#define FCMPGTQ(d, s) (d > s ? -1 : 0)
SSE_HELPER_Q(helper_pcmpgtq, FCMPGTQ)
-static inline int pcmp_elen(int reg, uint32_t ctrl)
+static inline int pcmp_elen(CPUX86State *env, int reg, uint32_t ctrl)
{
int val;
@@ -1980,7 +1992,7 @@
}
}
-static inline unsigned pcmpxstrx(Reg *d, Reg *s,
+static inline unsigned pcmpxstrx(CPUX86State *env, Reg *d, Reg *s,
int8_t ctrl, int valids, int validd)
{
unsigned int res = 0;
@@ -2080,11 +2092,12 @@
return ret;
}
-void glue(helper_pcmpestri, SUFFIX)(Reg *d, Reg *s, uint32_t ctrl)
+void glue(helper_pcmpestri, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
+ uint32_t ctrl)
{
- unsigned int res = pcmpxstrx(d, s, ctrl,
- pcmp_elen(R_EDX, ctrl),
- pcmp_elen(R_EAX, ctrl));
+ unsigned int res = pcmpxstrx(env, d, s, ctrl,
+ pcmp_elen(env, R_EDX, ctrl),
+ pcmp_elen(env, R_EAX, ctrl));
if (res) {
env->regs[R_ECX] = ((ctrl & (1 << 6)) ? rffs1 : ffs1)(res) - 1;
@@ -2093,12 +2106,13 @@
}
}
-void glue(helper_pcmpestrm, SUFFIX)(Reg *d, Reg *s, uint32_t ctrl)
+void glue(helper_pcmpestrm, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
+ uint32_t ctrl)
{
int i;
- unsigned int res = pcmpxstrx(d, s, ctrl,
- pcmp_elen(R_EDX, ctrl),
- pcmp_elen(R_EAX, ctrl));
+ unsigned int res = pcmpxstrx(env, d, s, ctrl,
+ pcmp_elen(env, R_EDX, ctrl),
+ pcmp_elen(env, R_EAX, ctrl));
if ((ctrl >> 6) & 1) {
if (ctrl & 1) {
@@ -2116,9 +2130,10 @@
}
}
-void glue(helper_pcmpistri, SUFFIX)(Reg *d, Reg *s, uint32_t ctrl)
+void glue(helper_pcmpistri, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
+ uint32_t ctrl)
{
- unsigned int res = pcmpxstrx(d, s, ctrl,
+ unsigned int res = pcmpxstrx(env, d, s, ctrl,
pcmp_ilen(s, ctrl),
pcmp_ilen(d, ctrl));
@@ -2129,10 +2144,11 @@
}
}
-void glue(helper_pcmpistrm, SUFFIX)(Reg *d, Reg *s, uint32_t ctrl)
+void glue(helper_pcmpistrm, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
+ uint32_t ctrl)
{
int i;
- unsigned int res = pcmpxstrx(d, s, ctrl,
+ unsigned int res = pcmpxstrx(env, d, s, ctrl,
pcmp_ilen(s, ctrl),
pcmp_ilen(d, ctrl));
@@ -2168,7 +2184,7 @@
#define POPMASK(i) ((target_ulong) -1 / ((1LL << (1 << i)) + 1))
#define POPCOUNT(n, i) ((n & POPMASK(i)) + ((n >> (1 << i)) & POPMASK(i)))
-target_ulong helper_popcnt(target_ulong n, uint32_t type)
+target_ulong helper_popcnt(CPUX86State *env, target_ulong n, uint32_t type)
{
CC_SRC = n ? 0 : CC_Z;
diff --git a/target-i386/ops_sse_header.h b/target-i386/ops_sse_header.h
index 8d4b2b7..401eac6 100644
--- a/target-i386/ops_sse_header.h
+++ b/target-i386/ops_sse_header.h
@@ -34,31 +34,31 @@
#define dh_is_signed_XMMReg dh_is_signed_ptr
#define dh_is_signed_MMXReg dh_is_signed_ptr
-DEF_HELPER_2(glue(psrlw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(psraw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(psllw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(psrld, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(psrad, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pslld, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(psrlq, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(psllq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_3(glue(psrlw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(psraw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(psllw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(psrld, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(psrad, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pslld, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(psrlq, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(psllq, SUFFIX), void, env, Reg, Reg)
#if SHIFT == 1
-DEF_HELPER_2(glue(psrldq, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pslldq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_3(glue(psrldq, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pslldq, SUFFIX), void, env, Reg, Reg)
#endif
#define SSE_HELPER_B(name, F)\
- DEF_HELPER_2(glue(name, SUFFIX), void, Reg, Reg)
+ DEF_HELPER_3(glue(name, SUFFIX), void, env, Reg, Reg)
#define SSE_HELPER_W(name, F)\
- DEF_HELPER_2(glue(name, SUFFIX), void, Reg, Reg)
+ DEF_HELPER_3(glue(name, SUFFIX), void, env, Reg, Reg)
#define SSE_HELPER_L(name, F)\
- DEF_HELPER_2(glue(name, SUFFIX), void, Reg, Reg)
+ DEF_HELPER_3(glue(name, SUFFIX), void, env, Reg, Reg)
#define SSE_HELPER_Q(name, F)\
- DEF_HELPER_2(glue(name, SUFFIX), void, Reg, Reg)
+ DEF_HELPER_3(glue(name, SUFFIX), void, env, Reg, Reg)
SSE_HELPER_B(paddb, FADD)
SSE_HELPER_W(paddw, FADD)
@@ -109,11 +109,11 @@
SSE_HELPER_B(pavgb, FAVG)
SSE_HELPER_W(pavgw, FAVG)
-DEF_HELPER_2(glue(pmuludq, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmaddwd, SUFFIX), void, Reg, Reg)
+DEF_HELPER_3(glue(pmuludq, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmaddwd, SUFFIX), void, env, Reg, Reg)
-DEF_HELPER_2(glue(psadbw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_3(glue(maskmov, SUFFIX), void, Reg, Reg, tl)
+DEF_HELPER_3(glue(psadbw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_4(glue(maskmov, SUFFIX), void, env, Reg, Reg, tl)
DEF_HELPER_2(glue(movl_mm_T0, SUFFIX), void, Reg, i32)
#ifdef TARGET_X86_64
DEF_HELPER_2(glue(movq_mm_T0, SUFFIX), void, Reg, i64)
@@ -133,11 +133,11 @@
/* FPU ops */
/* XXX: not accurate */
-#define SSE_HELPER_S(name, F)\
- DEF_HELPER_2(name ## ps , void, Reg, Reg) \
- DEF_HELPER_2(name ## ss , void, Reg, Reg) \
- DEF_HELPER_2(name ## pd , void, Reg, Reg) \
- DEF_HELPER_2(name ## sd , void, Reg, Reg)
+#define SSE_HELPER_S(name, F) \
+ DEF_HELPER_3(name ## ps, void, env, Reg, Reg) \
+ DEF_HELPER_3(name ## ss, void, env, Reg, Reg) \
+ DEF_HELPER_3(name ## pd, void, env, Reg, Reg) \
+ DEF_HELPER_3(name ## sd, void, env, Reg, Reg)
SSE_HELPER_S(add, FPU_ADD)
SSE_HELPER_S(sub, FPU_SUB)
@@ -148,64 +148,64 @@
SSE_HELPER_S(sqrt, FPU_SQRT)
-DEF_HELPER_2(cvtps2pd, void, Reg, Reg)
-DEF_HELPER_2(cvtpd2ps, void, Reg, Reg)
-DEF_HELPER_2(cvtss2sd, void, Reg, Reg)
-DEF_HELPER_2(cvtsd2ss, void, Reg, Reg)
-DEF_HELPER_2(cvtdq2ps, void, Reg, Reg)
-DEF_HELPER_2(cvtdq2pd, void, Reg, Reg)
-DEF_HELPER_2(cvtpi2ps, void, XMMReg, MMXReg)
-DEF_HELPER_2(cvtpi2pd, void, XMMReg, MMXReg)
-DEF_HELPER_2(cvtsi2ss, void, XMMReg, i32)
-DEF_HELPER_2(cvtsi2sd, void, XMMReg, i32)
+DEF_HELPER_3(cvtps2pd, void, env, Reg, Reg)
+DEF_HELPER_3(cvtpd2ps, void, env, Reg, Reg)
+DEF_HELPER_3(cvtss2sd, void, env, Reg, Reg)
+DEF_HELPER_3(cvtsd2ss, void, env, Reg, Reg)
+DEF_HELPER_3(cvtdq2ps, void, env, Reg, Reg)
+DEF_HELPER_3(cvtdq2pd, void, env, Reg, Reg)
+DEF_HELPER_3(cvtpi2ps, void, env, XMMReg, MMXReg)
+DEF_HELPER_3(cvtpi2pd, void, env, XMMReg, MMXReg)
+DEF_HELPER_3(cvtsi2ss, void, env, XMMReg, i32)
+DEF_HELPER_3(cvtsi2sd, void, env, XMMReg, i32)
#ifdef TARGET_X86_64
-DEF_HELPER_2(cvtsq2ss, void, XMMReg, i64)
-DEF_HELPER_2(cvtsq2sd, void, XMMReg, i64)
+DEF_HELPER_3(cvtsq2ss, void, env, XMMReg, i64)
+DEF_HELPER_3(cvtsq2sd, void, env, XMMReg, i64)
#endif
-DEF_HELPER_2(cvtps2dq, void, XMMReg, XMMReg)
-DEF_HELPER_2(cvtpd2dq, void, XMMReg, XMMReg)
-DEF_HELPER_2(cvtps2pi, void, MMXReg, XMMReg)
-DEF_HELPER_2(cvtpd2pi, void, MMXReg, XMMReg)
-DEF_HELPER_1(cvtss2si, s32, XMMReg)
-DEF_HELPER_1(cvtsd2si, s32, XMMReg)
+DEF_HELPER_3(cvtps2dq, void, env, XMMReg, XMMReg)
+DEF_HELPER_3(cvtpd2dq, void, env, XMMReg, XMMReg)
+DEF_HELPER_3(cvtps2pi, void, env, MMXReg, XMMReg)
+DEF_HELPER_3(cvtpd2pi, void, env, MMXReg, XMMReg)
+DEF_HELPER_2(cvtss2si, s32, env, XMMReg)
+DEF_HELPER_2(cvtsd2si, s32, env, XMMReg)
#ifdef TARGET_X86_64
-DEF_HELPER_1(cvtss2sq, s64, XMMReg)
-DEF_HELPER_1(cvtsd2sq, s64, XMMReg)
+DEF_HELPER_2(cvtss2sq, s64, env, XMMReg)
+DEF_HELPER_2(cvtsd2sq, s64, env, XMMReg)
#endif
-DEF_HELPER_2(cvttps2dq, void, XMMReg, XMMReg)
-DEF_HELPER_2(cvttpd2dq, void, XMMReg, XMMReg)
-DEF_HELPER_2(cvttps2pi, void, MMXReg, XMMReg)
-DEF_HELPER_2(cvttpd2pi, void, MMXReg, XMMReg)
-DEF_HELPER_1(cvttss2si, s32, XMMReg)
-DEF_HELPER_1(cvttsd2si, s32, XMMReg)
+DEF_HELPER_3(cvttps2dq, void, env, XMMReg, XMMReg)
+DEF_HELPER_3(cvttpd2dq, void, env, XMMReg, XMMReg)
+DEF_HELPER_3(cvttps2pi, void, env, MMXReg, XMMReg)
+DEF_HELPER_3(cvttpd2pi, void, env, MMXReg, XMMReg)
+DEF_HELPER_2(cvttss2si, s32, env, XMMReg)
+DEF_HELPER_2(cvttsd2si, s32, env, XMMReg)
#ifdef TARGET_X86_64
-DEF_HELPER_1(cvttss2sq, s64, XMMReg)
-DEF_HELPER_1(cvttsd2sq, s64, XMMReg)
+DEF_HELPER_2(cvttss2sq, s64, env, XMMReg)
+DEF_HELPER_2(cvttsd2sq, s64, env, XMMReg)
#endif
-DEF_HELPER_2(rsqrtps, void, XMMReg, XMMReg)
-DEF_HELPER_2(rsqrtss, void, XMMReg, XMMReg)
-DEF_HELPER_2(rcpps, void, XMMReg, XMMReg)
-DEF_HELPER_2(rcpss, void, XMMReg, XMMReg)
-DEF_HELPER_2(extrq_r, void, XMMReg, XMMReg)
-DEF_HELPER_3(extrq_i, void, XMMReg, int, int)
-DEF_HELPER_2(insertq_r, void, XMMReg, XMMReg)
-DEF_HELPER_3(insertq_i, void, XMMReg, int, int)
-DEF_HELPER_2(haddps, void, XMMReg, XMMReg)
-DEF_HELPER_2(haddpd, void, XMMReg, XMMReg)
-DEF_HELPER_2(hsubps, void, XMMReg, XMMReg)
-DEF_HELPER_2(hsubpd, void, XMMReg, XMMReg)
-DEF_HELPER_2(addsubps, void, XMMReg, XMMReg)
-DEF_HELPER_2(addsubpd, void, XMMReg, XMMReg)
+DEF_HELPER_3(rsqrtps, void, env, XMMReg, XMMReg)
+DEF_HELPER_3(rsqrtss, void, env, XMMReg, XMMReg)
+DEF_HELPER_3(rcpps, void, env, XMMReg, XMMReg)
+DEF_HELPER_3(rcpss, void, env, XMMReg, XMMReg)
+DEF_HELPER_3(extrq_r, void, env, XMMReg, XMMReg)
+DEF_HELPER_4(extrq_i, void, env, XMMReg, int, int)
+DEF_HELPER_3(insertq_r, void, env, XMMReg, XMMReg)
+DEF_HELPER_4(insertq_i, void, env, XMMReg, int, int)
+DEF_HELPER_3(haddps, void, env, XMMReg, XMMReg)
+DEF_HELPER_3(haddpd, void, env, XMMReg, XMMReg)
+DEF_HELPER_3(hsubps, void, env, XMMReg, XMMReg)
+DEF_HELPER_3(hsubpd, void, env, XMMReg, XMMReg)
+DEF_HELPER_3(addsubps, void, env, XMMReg, XMMReg)
+DEF_HELPER_3(addsubpd, void, env, XMMReg, XMMReg)
-#define SSE_HELPER_CMP(name, F)\
- DEF_HELPER_2( name ## ps , void, Reg, Reg) \
- DEF_HELPER_2( name ## ss , void, Reg, Reg) \
- DEF_HELPER_2( name ## pd , void, Reg, Reg) \
- DEF_HELPER_2( name ## sd , void, Reg, Reg)
+#define SSE_HELPER_CMP(name, F) \
+ DEF_HELPER_3(name ## ps, void, env, Reg, Reg) \
+ DEF_HELPER_3(name ## ss, void, env, Reg, Reg) \
+ DEF_HELPER_3(name ## pd, void, env, Reg, Reg) \
+ DEF_HELPER_3(name ## sd, void, env, Reg, Reg)
SSE_HELPER_CMP(cmpeq, FPU_CMPEQ)
SSE_HELPER_CMP(cmplt, FPU_CMPLT)
@@ -216,124 +216,124 @@
SSE_HELPER_CMP(cmpnle, FPU_CMPNLE)
SSE_HELPER_CMP(cmpord, FPU_CMPORD)
-DEF_HELPER_2(ucomiss, void, Reg, Reg)
-DEF_HELPER_2(comiss, void, Reg, Reg)
-DEF_HELPER_2(ucomisd, void, Reg, Reg)
-DEF_HELPER_2(comisd, void, Reg, Reg)
-DEF_HELPER_1(movmskps, i32, Reg)
-DEF_HELPER_1(movmskpd, i32, Reg)
+DEF_HELPER_3(ucomiss, void, env, Reg, Reg)
+DEF_HELPER_3(comiss, void, env, Reg, Reg)
+DEF_HELPER_3(ucomisd, void, env, Reg, Reg)
+DEF_HELPER_3(comisd, void, env, Reg, Reg)
+DEF_HELPER_2(movmskps, i32, env, Reg)
+DEF_HELPER_2(movmskpd, i32, env, Reg)
#endif
-DEF_HELPER_1(glue(pmovmskb, SUFFIX), i32, Reg)
-DEF_HELPER_2(glue(packsswb, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(packuswb, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(packssdw, SUFFIX), void, Reg, Reg)
-#define UNPCK_OP(base_name, base) \
- DEF_HELPER_2(glue(punpck ## base_name ## bw, SUFFIX) , void, Reg, Reg) \
- DEF_HELPER_2(glue(punpck ## base_name ## wd, SUFFIX) , void, Reg, Reg) \
- DEF_HELPER_2(glue(punpck ## base_name ## dq, SUFFIX) , void, Reg, Reg)
+DEF_HELPER_2(glue(pmovmskb, SUFFIX), i32, env, Reg)
+DEF_HELPER_3(glue(packsswb, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(packuswb, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(packssdw, SUFFIX), void, env, Reg, Reg)
+#define UNPCK_OP(base_name, base) \
+ DEF_HELPER_3(glue(punpck ## base_name ## bw, SUFFIX), void, env, Reg, Reg) \
+ DEF_HELPER_3(glue(punpck ## base_name ## wd, SUFFIX), void, env, Reg, Reg) \
+ DEF_HELPER_3(glue(punpck ## base_name ## dq, SUFFIX), void, env, Reg, Reg)
UNPCK_OP(l, 0)
UNPCK_OP(h, 1)
#if SHIFT == 1
-DEF_HELPER_2(glue(punpcklqdq, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(punpckhqdq, SUFFIX), void, Reg, Reg)
+DEF_HELPER_3(glue(punpcklqdq, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(punpckhqdq, SUFFIX), void, env, Reg, Reg)
#endif
/* 3DNow! float ops */
#if SHIFT == 0
-DEF_HELPER_2(pi2fd, void, MMXReg, MMXReg)
-DEF_HELPER_2(pi2fw, void, MMXReg, MMXReg)
-DEF_HELPER_2(pf2id, void, MMXReg, MMXReg)
-DEF_HELPER_2(pf2iw, void, MMXReg, MMXReg)
-DEF_HELPER_2(pfacc, void, MMXReg, MMXReg)
-DEF_HELPER_2(pfadd, void, MMXReg, MMXReg)
-DEF_HELPER_2(pfcmpeq, void, MMXReg, MMXReg)
-DEF_HELPER_2(pfcmpge, void, MMXReg, MMXReg)
-DEF_HELPER_2(pfcmpgt, void, MMXReg, MMXReg)
-DEF_HELPER_2(pfmax, void, MMXReg, MMXReg)
-DEF_HELPER_2(pfmin, void, MMXReg, MMXReg)
-DEF_HELPER_2(pfmul, void, MMXReg, MMXReg)
-DEF_HELPER_2(pfnacc, void, MMXReg, MMXReg)
-DEF_HELPER_2(pfpnacc, void, MMXReg, MMXReg)
-DEF_HELPER_2(pfrcp, void, MMXReg, MMXReg)
-DEF_HELPER_2(pfrsqrt, void, MMXReg, MMXReg)
-DEF_HELPER_2(pfsub, void, MMXReg, MMXReg)
-DEF_HELPER_2(pfsubr, void, MMXReg, MMXReg)
-DEF_HELPER_2(pswapd, void, MMXReg, MMXReg)
+DEF_HELPER_3(pi2fd, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pi2fw, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pf2id, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pf2iw, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pfacc, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pfadd, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pfcmpeq, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pfcmpge, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pfcmpgt, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pfmax, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pfmin, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pfmul, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pfnacc, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pfpnacc, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pfrcp, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pfrsqrt, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pfsub, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pfsubr, void, env, MMXReg, MMXReg)
+DEF_HELPER_3(pswapd, void, env, MMXReg, MMXReg)
#endif
/* SSSE3 op helpers */
-DEF_HELPER_2(glue(phaddw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(phaddd, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(phaddsw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(phsubw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(phsubd, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(phsubsw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pabsb, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pabsw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pabsd, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmaddubsw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmulhrsw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pshufb, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(psignb, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(psignw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(psignd, SUFFIX), void, Reg, Reg)
-DEF_HELPER_3(glue(palignr, SUFFIX), void, Reg, Reg, s32)
+DEF_HELPER_3(glue(phaddw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(phaddd, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(phaddsw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(phsubw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(phsubd, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(phsubsw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pabsb, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pabsw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pabsd, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmaddubsw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmulhrsw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pshufb, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(psignb, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(psignw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(psignd, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_4(glue(palignr, SUFFIX), void, env, Reg, Reg, s32)
/* SSE4.1 op helpers */
#if SHIFT == 1
-DEF_HELPER_2(glue(pblendvb, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(blendvps, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(blendvpd, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(ptest, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmovsxbw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmovsxbd, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmovsxbq, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmovsxwd, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmovsxwq, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmovsxdq, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmovzxbw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmovzxbd, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmovzxbq, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmovzxwd, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmovzxwq, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmovzxdq, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmuldq, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pcmpeqq, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(packusdw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pminsb, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pminsd, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pminuw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pminud, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmaxsb, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmaxsd, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmaxuw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmaxud, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(pmulld, SUFFIX), void, Reg, Reg)
-DEF_HELPER_2(glue(phminposuw, SUFFIX), void, Reg, Reg)
-DEF_HELPER_3(glue(roundps, SUFFIX), void, Reg, Reg, i32)
-DEF_HELPER_3(glue(roundpd, SUFFIX), void, Reg, Reg, i32)
-DEF_HELPER_3(glue(roundss, SUFFIX), void, Reg, Reg, i32)
-DEF_HELPER_3(glue(roundsd, SUFFIX), void, Reg, Reg, i32)
-DEF_HELPER_3(glue(blendps, SUFFIX), void, Reg, Reg, i32)
-DEF_HELPER_3(glue(blendpd, SUFFIX), void, Reg, Reg, i32)
-DEF_HELPER_3(glue(pblendw, SUFFIX), void, Reg, Reg, i32)
-DEF_HELPER_3(glue(dpps, SUFFIX), void, Reg, Reg, i32)
-DEF_HELPER_3(glue(dppd, SUFFIX), void, Reg, Reg, i32)
-DEF_HELPER_3(glue(mpsadbw, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(glue(pblendvb, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(blendvps, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(blendvpd, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(ptest, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmovsxbw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmovsxbd, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmovsxbq, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmovsxwd, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmovsxwq, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmovsxdq, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmovzxbw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmovzxbd, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmovzxbq, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmovzxwd, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmovzxwq, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmovzxdq, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmuldq, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pcmpeqq, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(packusdw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pminsb, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pminsd, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pminuw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pminud, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmaxsb, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmaxsd, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmaxuw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmaxud, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(pmulld, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_3(glue(phminposuw, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_4(glue(roundps, SUFFIX), void, env, Reg, Reg, i32)
+DEF_HELPER_4(glue(roundpd, SUFFIX), void, env, Reg, Reg, i32)
+DEF_HELPER_4(glue(roundss, SUFFIX), void, env, Reg, Reg, i32)
+DEF_HELPER_4(glue(roundsd, SUFFIX), void, env, Reg, Reg, i32)
+DEF_HELPER_4(glue(blendps, SUFFIX), void, env, Reg, Reg, i32)
+DEF_HELPER_4(glue(blendpd, SUFFIX), void, env, Reg, Reg, i32)
+DEF_HELPER_4(glue(pblendw, SUFFIX), void, env, Reg, Reg, i32)
+DEF_HELPER_4(glue(dpps, SUFFIX), void, env, Reg, Reg, i32)
+DEF_HELPER_4(glue(dppd, SUFFIX), void, env, Reg, Reg, i32)
+DEF_HELPER_4(glue(mpsadbw, SUFFIX), void, env, Reg, Reg, i32)
#endif
/* SSE4.2 op helpers */
#if SHIFT == 1
-DEF_HELPER_2(glue(pcmpgtq, SUFFIX), void, Reg, Reg)
-DEF_HELPER_3(glue(pcmpestri, SUFFIX), void, Reg, Reg, i32)
-DEF_HELPER_3(glue(pcmpestrm, SUFFIX), void, Reg, Reg, i32)
-DEF_HELPER_3(glue(pcmpistri, SUFFIX), void, Reg, Reg, i32)
-DEF_HELPER_3(glue(pcmpistrm, SUFFIX), void, Reg, Reg, i32)
+DEF_HELPER_3(glue(pcmpgtq, SUFFIX), void, env, Reg, Reg)
+DEF_HELPER_4(glue(pcmpestri, SUFFIX), void, env, Reg, Reg, i32)
+DEF_HELPER_4(glue(pcmpestrm, SUFFIX), void, env, Reg, Reg, i32)
+DEF_HELPER_4(glue(pcmpistri, SUFFIX), void, env, Reg, Reg, i32)
+DEF_HELPER_4(glue(pcmpistrm, SUFFIX), void, env, Reg, Reg, i32)
DEF_HELPER_3(crc32, tl, i32, tl, i32)
-DEF_HELPER_2(popcnt, tl, tl, i32)
+DEF_HELPER_3(popcnt, tl, env, tl, i32)
#endif
#undef SHIFT
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index a4b8b64..5fff8d5 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -19,16 +19,15 @@
*/
#include "cpu.h"
-#include "dyngen-exec.h"
#include "qemu-log.h"
#include "helper.h"
+//#define DEBUG_PCALL
+
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif /* !defined(CONFIG_USER_ONLY) */
-//#define DEBUG_PCALL
-
#ifdef DEBUG_PCALL
# define LOG_PCALL(...) qemu_log_mask(CPU_LOG_PCALL, ## __VA_ARGS__)
# define LOG_PCALL_STATE(env) \
@@ -39,8 +38,8 @@
#endif
/* return non zero if error */
-static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,
- int selector)
+static inline int load_segment(CPUX86State *env, uint32_t *e1_ptr,
+ uint32_t *e2_ptr, int selector)
{
SegmentCache *dt;
int index;
@@ -56,8 +55,8 @@
return -1;
}
ptr = dt->base + index;
- *e1_ptr = ldl_kernel(ptr);
- *e2_ptr = ldl_kernel(ptr + 4);
+ *e1_ptr = cpu_ldl_kernel(env, ptr);
+ *e2_ptr = cpu_ldl_kernel(env, ptr + 4);
return 0;
}
@@ -86,14 +85,14 @@
}
/* init the segment cache in vm86 mode. */
-static inline void load_seg_vm(int seg, int selector)
+static inline void load_seg_vm(CPUX86State *env, int seg, int selector)
{
selector &= 0xffff;
cpu_x86_load_seg_cache(env, seg, selector,
(selector << 4), 0xffff, 0);
}
-static inline void get_ss_esp_from_tss(uint32_t *ss_ptr,
+static inline void get_ss_esp_from_tss(CPUX86State *env, uint32_t *ss_ptr,
uint32_t *esp_ptr, int dpl)
{
int type, index, shift;
@@ -125,22 +124,22 @@
raise_exception_err(env, EXCP0A_TSS, env->tr.selector & 0xfffc);
}
if (shift == 0) {
- *esp_ptr = lduw_kernel(env->tr.base + index);
- *ss_ptr = lduw_kernel(env->tr.base + index + 2);
+ *esp_ptr = cpu_lduw_kernel(env, env->tr.base + index);
+ *ss_ptr = cpu_lduw_kernel(env, env->tr.base + index + 2);
} else {
- *esp_ptr = ldl_kernel(env->tr.base + index);
- *ss_ptr = lduw_kernel(env->tr.base + index + 4);
+ *esp_ptr = cpu_ldl_kernel(env, env->tr.base + index);
+ *ss_ptr = cpu_lduw_kernel(env, env->tr.base + index + 4);
}
}
/* XXX: merge with load_seg() */
-static void tss_load_seg(int seg_reg, int selector)
+static void tss_load_seg(CPUX86State *env, int seg_reg, int selector)
{
uint32_t e1, e2;
int rpl, dpl, cpl;
if ((selector & 0xfffc) != 0) {
- if (load_segment(&e1, &e2, selector) != 0) {
+ if (load_segment(env, &e1, &e2, selector) != 0) {
raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);
}
if (!(e2 & DESC_S_MASK)) {
@@ -199,7 +198,7 @@
#define SWITCH_TSS_CALL 2
/* XXX: restore CPU state in registers (PowerPC case) */
-static void switch_tss(int tss_selector,
+static void switch_tss(CPUX86State *env, int tss_selector,
uint32_t e1, uint32_t e2, int source,
uint32_t next_eip)
{
@@ -225,7 +224,7 @@
if (tss_selector & 4) {
raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc);
}
- if (load_segment(&e1, &e2, tss_selector) != 0) {
+ if (load_segment(env, &e1, &e2, tss_selector) != 0) {
raise_exception_err(env, EXCP0D_GPF, tss_selector & 0xfffc);
}
if (e2 & DESC_S_MASK) {
@@ -262,29 +261,30 @@
/* read all the registers from the new TSS */
if (type & 8) {
/* 32 bit */
- new_cr3 = ldl_kernel(tss_base + 0x1c);
- new_eip = ldl_kernel(tss_base + 0x20);
- new_eflags = ldl_kernel(tss_base + 0x24);
+ new_cr3 = cpu_ldl_kernel(env, tss_base + 0x1c);
+ new_eip = cpu_ldl_kernel(env, tss_base + 0x20);
+ new_eflags = cpu_ldl_kernel(env, tss_base + 0x24);
for (i = 0; i < 8; i++) {
- new_regs[i] = ldl_kernel(tss_base + (0x28 + i * 4));
+ new_regs[i] = cpu_ldl_kernel(env, tss_base + (0x28 + i * 4));
}
for (i = 0; i < 6; i++) {
- new_segs[i] = lduw_kernel(tss_base + (0x48 + i * 4));
+ new_segs[i] = cpu_lduw_kernel(env, tss_base + (0x48 + i * 4));
}
- new_ldt = lduw_kernel(tss_base + 0x60);
- new_trap = ldl_kernel(tss_base + 0x64);
+ new_ldt = cpu_lduw_kernel(env, tss_base + 0x60);
+ new_trap = cpu_ldl_kernel(env, tss_base + 0x64);
} else {
/* 16 bit */
new_cr3 = 0;
- new_eip = lduw_kernel(tss_base + 0x0e);
- new_eflags = lduw_kernel(tss_base + 0x10);
+ new_eip = cpu_lduw_kernel(env, tss_base + 0x0e);
+ new_eflags = cpu_lduw_kernel(env, tss_base + 0x10);
for (i = 0; i < 8; i++) {
- new_regs[i] = lduw_kernel(tss_base + (0x12 + i * 2)) | 0xffff0000;
+ new_regs[i] = cpu_lduw_kernel(env, tss_base + (0x12 + i * 2)) |
+ 0xffff0000;
}
for (i = 0; i < 4; i++) {
- new_segs[i] = lduw_kernel(tss_base + (0x22 + i * 4));
+ new_segs[i] = cpu_lduw_kernel(env, tss_base + (0x22 + i * 4));
}
- new_ldt = lduw_kernel(tss_base + 0x2a);
+ new_ldt = cpu_lduw_kernel(env, tss_base + 0x2a);
new_segs[R_FS] = 0;
new_segs[R_GS] = 0;
new_trap = 0;
@@ -299,10 +299,10 @@
/* XXX: it can still fail in some cases, so a bigger hack is
necessary to valid the TLB after having done the accesses */
- v1 = ldub_kernel(env->tr.base);
- v2 = ldub_kernel(env->tr.base + old_tss_limit_max);
- stb_kernel(env->tr.base, v1);
- stb_kernel(env->tr.base + old_tss_limit_max, v2);
+ v1 = cpu_ldub_kernel(env, env->tr.base);
+ v2 = cpu_ldub_kernel(env, env->tr.base + old_tss_limit_max);
+ cpu_stb_kernel(env, env->tr.base, v1);
+ cpu_stb_kernel(env, env->tr.base + old_tss_limit_max, v2);
/* clear busy bit (it is restartable) */
if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_IRET) {
@@ -310,9 +310,9 @@
uint32_t e2;
ptr = env->gdt.base + (env->tr.selector & ~7);
- e2 = ldl_kernel(ptr + 4);
+ e2 = cpu_ldl_kernel(env, ptr + 4);
e2 &= ~DESC_TSS_BUSY_MASK;
- stl_kernel(ptr + 4, e2);
+ cpu_stl_kernel(env, ptr + 4, e2);
}
old_eflags = cpu_compute_eflags(env);
if (source == SWITCH_TSS_IRET) {
@@ -322,33 +322,35 @@
/* save the current state in the old TSS */
if (type & 8) {
/* 32 bit */
- stl_kernel(env->tr.base + 0x20, next_eip);
- stl_kernel(env->tr.base + 0x24, old_eflags);
- stl_kernel(env->tr.base + (0x28 + 0 * 4), EAX);
- stl_kernel(env->tr.base + (0x28 + 1 * 4), ECX);
- stl_kernel(env->tr.base + (0x28 + 2 * 4), EDX);
- stl_kernel(env->tr.base + (0x28 + 3 * 4), EBX);
- stl_kernel(env->tr.base + (0x28 + 4 * 4), ESP);
- stl_kernel(env->tr.base + (0x28 + 5 * 4), EBP);
- stl_kernel(env->tr.base + (0x28 + 6 * 4), ESI);
- stl_kernel(env->tr.base + (0x28 + 7 * 4), EDI);
+ cpu_stl_kernel(env, env->tr.base + 0x20, next_eip);
+ cpu_stl_kernel(env, env->tr.base + 0x24, old_eflags);
+ cpu_stl_kernel(env, env->tr.base + (0x28 + 0 * 4), EAX);
+ cpu_stl_kernel(env, env->tr.base + (0x28 + 1 * 4), ECX);
+ cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), EDX);
+ cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), EBX);
+ cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), ESP);
+ cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), EBP);
+ cpu_stl_kernel(env, env->tr.base + (0x28 + 6 * 4), ESI);
+ cpu_stl_kernel(env, env->tr.base + (0x28 + 7 * 4), EDI);
for (i = 0; i < 6; i++) {
- stw_kernel(env->tr.base + (0x48 + i * 4), env->segs[i].selector);
+ cpu_stw_kernel(env, env->tr.base + (0x48 + i * 4),
+ env->segs[i].selector);
}
} else {
/* 16 bit */
- stw_kernel(env->tr.base + 0x0e, next_eip);
- stw_kernel(env->tr.base + 0x10, old_eflags);
- stw_kernel(env->tr.base + (0x12 + 0 * 2), EAX);
- stw_kernel(env->tr.base + (0x12 + 1 * 2), ECX);
- stw_kernel(env->tr.base + (0x12 + 2 * 2), EDX);
- stw_kernel(env->tr.base + (0x12 + 3 * 2), EBX);
- stw_kernel(env->tr.base + (0x12 + 4 * 2), ESP);
- stw_kernel(env->tr.base + (0x12 + 5 * 2), EBP);
- stw_kernel(env->tr.base + (0x12 + 6 * 2), ESI);
- stw_kernel(env->tr.base + (0x12 + 7 * 2), EDI);
+ cpu_stw_kernel(env, env->tr.base + 0x0e, next_eip);
+ cpu_stw_kernel(env, env->tr.base + 0x10, old_eflags);
+ cpu_stw_kernel(env, env->tr.base + (0x12 + 0 * 2), EAX);
+ cpu_stw_kernel(env, env->tr.base + (0x12 + 1 * 2), ECX);
+ cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), EDX);
+ cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), EBX);
+ cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), ESP);
+ cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), EBP);
+ cpu_stw_kernel(env, env->tr.base + (0x12 + 6 * 2), ESI);
+ cpu_stw_kernel(env, env->tr.base + (0x12 + 7 * 2), EDI);
for (i = 0; i < 4; i++) {
- stw_kernel(env->tr.base + (0x22 + i * 4), env->segs[i].selector);
+ cpu_stw_kernel(env, env->tr.base + (0x22 + i * 4),
+ env->segs[i].selector);
}
}
@@ -356,7 +358,7 @@
context */
if (source == SWITCH_TSS_CALL) {
- stw_kernel(tss_base, env->tr.selector);
+ cpu_stw_kernel(env, tss_base, env->tr.selector);
new_eflags |= NT_MASK;
}
@@ -366,9 +368,9 @@
uint32_t e2;
ptr = env->gdt.base + (tss_selector & ~7);
- e2 = ldl_kernel(ptr + 4);
+ e2 = cpu_ldl_kernel(env, ptr + 4);
e2 |= DESC_TSS_BUSY_MASK;
- stl_kernel(ptr + 4, e2);
+ cpu_stl_kernel(env, ptr + 4, e2);
}
/* set the new CPU state */
@@ -404,7 +406,7 @@
EDI = new_regs[7];
if (new_eflags & VM_MASK) {
for (i = 0; i < 6; i++) {
- load_seg_vm(i, new_segs[i]);
+ load_seg_vm(env, i, new_segs[i]);
}
/* in vm86, CPL is always 3 */
cpu_x86_set_cpl(env, 3);
@@ -434,8 +436,8 @@
raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc);
}
ptr = dt->base + index;
- e1 = ldl_kernel(ptr);
- e2 = ldl_kernel(ptr + 4);
+ e1 = cpu_ldl_kernel(env, ptr);
+ e2 = cpu_ldl_kernel(env, ptr + 4);
if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) {
raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc);
}
@@ -447,12 +449,12 @@
/* load the segments */
if (!(new_eflags & VM_MASK)) {
- tss_load_seg(R_CS, new_segs[R_CS]);
- tss_load_seg(R_SS, new_segs[R_SS]);
- tss_load_seg(R_ES, new_segs[R_ES]);
- tss_load_seg(R_DS, new_segs[R_DS]);
- tss_load_seg(R_FS, new_segs[R_FS]);
- tss_load_seg(R_GS, new_segs[R_GS]);
+ tss_load_seg(env, R_CS, new_segs[R_CS]);
+ tss_load_seg(env, R_SS, new_segs[R_SS]);
+ tss_load_seg(env, R_ES, new_segs[R_ES]);
+ tss_load_seg(env, R_DS, new_segs[R_DS]);
+ tss_load_seg(env, R_FS, new_segs[R_FS]);
+ tss_load_seg(env, R_GS, new_segs[R_GS]);
}
/* check that EIP is in the CS segment limits */
@@ -521,33 +523,34 @@
#define SEG_ADDL(ssp, sp, sp_mask) ((uint32_t)((ssp) + (sp & (sp_mask))))
/* XXX: add a is_user flag to have proper security support */
-#define PUSHW(ssp, sp, sp_mask, val) \
- { \
- sp -= 2; \
- stw_kernel((ssp) + (sp & (sp_mask)), (val)); \
+#define PUSHW(ssp, sp, sp_mask, val) \
+ { \
+ sp -= 2; \
+ cpu_stw_kernel(env, (ssp) + (sp & (sp_mask)), (val)); \
}
#define PUSHL(ssp, sp, sp_mask, val) \
{ \
sp -= 4; \
- stl_kernel(SEG_ADDL(ssp, sp, sp_mask), (uint32_t)(val)); \
+ cpu_stl_kernel(env, SEG_ADDL(ssp, sp, sp_mask), (uint32_t)(val)); \
}
-#define POPW(ssp, sp, sp_mask, val) \
- { \
- val = lduw_kernel((ssp) + (sp & (sp_mask))); \
- sp += 2; \
+#define POPW(ssp, sp, sp_mask, val) \
+ { \
+ val = cpu_lduw_kernel(env, (ssp) + (sp & (sp_mask))); \
+ sp += 2; \
}
-#define POPL(ssp, sp, sp_mask, val) \
- { \
- val = (uint32_t)ldl_kernel(SEG_ADDL(ssp, sp, sp_mask)); \
- sp += 4; \
+#define POPL(ssp, sp, sp_mask, val) \
+ { \
+ val = (uint32_t)cpu_ldl_kernel(env, SEG_ADDL(ssp, sp, sp_mask)); \
+ sp += 4; \
}
/* protected mode interrupt */
-static void do_interrupt_protected(int intno, int is_int, int error_code,
- unsigned int next_eip, int is_hw)
+static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
+ int error_code, unsigned int next_eip,
+ int is_hw)
{
SegmentCache *dt;
target_ulong ptr, ssp;
@@ -571,8 +574,8 @@
raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);
}
ptr = dt->base + intno * 8;
- e1 = ldl_kernel(ptr);
- e2 = ldl_kernel(ptr + 4);
+ e1 = cpu_ldl_kernel(env, ptr);
+ e2 = cpu_ldl_kernel(env, ptr + 4);
/* check gate type */
type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;
switch (type) {
@@ -581,7 +584,7 @@
if (!(e2 & DESC_P_MASK)) {
raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2);
}
- switch_tss(intno * 8, e1, e2, SWITCH_TSS_CALL, old_eip);
+ switch_tss(env, intno * 8, e1, e2, SWITCH_TSS_CALL, old_eip);
if (has_error_code) {
int type;
uint32_t mask;
@@ -597,9 +600,9 @@
esp = (ESP - (2 << shift)) & mask;
ssp = env->segs[R_SS].base + esp;
if (shift) {
- stl_kernel(ssp, error_code);
+ cpu_stl_kernel(env, ssp, error_code);
} else {
- stw_kernel(ssp, error_code);
+ cpu_stw_kernel(env, ssp, error_code);
}
SET_ESP(esp, mask);
}
@@ -628,7 +631,7 @@
if ((selector & 0xfffc) == 0) {
raise_exception_err(env, EXCP0D_GPF, 0);
}
- if (load_segment(&e1, &e2, selector) != 0) {
+ if (load_segment(env, &e1, &e2, selector) != 0) {
raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) {
@@ -643,14 +646,14 @@
}
if (!(e2 & DESC_C_MASK) && dpl < cpl) {
/* to inner privilege */
- get_ss_esp_from_tss(&ss, &esp, dpl);
+ get_ss_esp_from_tss(env, &ss, &esp, dpl);
if ((ss & 0xfffc) == 0) {
raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
if ((ss & 3) != dpl) {
raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
- if (load_segment(&ss_e1, &ss_e2, ss) != 0) {
+ if (load_segment(env, &ss_e1, &ss_e2, ss) != 0) {
raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
@@ -765,16 +768,16 @@
#define PUSHQ(sp, val) \
{ \
sp -= 8; \
- stq_kernel(sp, (val)); \
+ cpu_stq_kernel(env, sp, (val)); \
}
#define POPQ(sp, val) \
{ \
- val = ldq_kernel(sp); \
+ val = cpu_ldq_kernel(env, sp); \
sp += 8; \
}
-static inline target_ulong get_rsp_from_tss(int level)
+static inline target_ulong get_rsp_from_tss(CPUX86State *env, int level)
{
int index;
@@ -790,12 +793,12 @@
if ((index + 7) > env->tr.limit) {
raise_exception_err(env, EXCP0A_TSS, env->tr.selector & 0xfffc);
}
- return ldq_kernel(env->tr.base + index);
+ return cpu_ldq_kernel(env, env->tr.base + index);
}
/* 64 bit interrupt */
-static void do_interrupt64(int intno, int is_int, int error_code,
- target_ulong next_eip, int is_hw)
+static void do_interrupt64(CPUX86State *env, int intno, int is_int,
+ int error_code, target_ulong next_eip, int is_hw)
{
SegmentCache *dt;
target_ulong ptr;
@@ -819,9 +822,9 @@
raise_exception_err(env, EXCP0D_GPF, intno * 16 + 2);
}
ptr = dt->base + intno * 16;
- e1 = ldl_kernel(ptr);
- e2 = ldl_kernel(ptr + 4);
- e3 = ldl_kernel(ptr + 8);
+ e1 = cpu_ldl_kernel(env, ptr);
+ e2 = cpu_ldl_kernel(env, ptr + 4);
+ e3 = cpu_ldl_kernel(env, ptr + 8);
/* check gate type */
type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;
switch (type) {
@@ -849,7 +852,7 @@
raise_exception_err(env, EXCP0D_GPF, 0);
}
- if (load_segment(&e1, &e2, selector) != 0) {
+ if (load_segment(env, &e1, &e2, selector) != 0) {
raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) {
@@ -868,9 +871,9 @@
if ((!(e2 & DESC_C_MASK) && dpl < cpl) || ist != 0) {
/* to inner privilege */
if (ist != 0) {
- esp = get_rsp_from_tss(ist + 3);
+ esp = get_rsp_from_tss(env, ist + 3);
} else {
- esp = get_rsp_from_tss(dpl);
+ esp = get_rsp_from_tss(env, dpl);
}
esp &= ~0xfLL; /* align stack */
ss = 0;
@@ -882,7 +885,7 @@
}
new_stack = 0;
if (ist != 0) {
- esp = get_rsp_from_tss(ist + 3);
+ esp = get_rsp_from_tss(env, ist + 3);
} else {
esp = ESP;
}
@@ -927,14 +930,14 @@
#ifdef TARGET_X86_64
#if defined(CONFIG_USER_ONLY)
-void helper_syscall(int next_eip_addend)
+void helper_syscall(CPUX86State *env, int next_eip_addend)
{
env->exception_index = EXCP_SYSCALL;
env->exception_next_eip = env->eip + next_eip_addend;
cpu_loop_exit(env);
}
#else
-void helper_syscall(int next_eip_addend)
+void helper_syscall(CPUX86State *env, int next_eip_addend)
{
int selector;
@@ -991,7 +994,7 @@
#endif
#ifdef TARGET_X86_64
-void helper_sysret(int dflag)
+void helper_sysret(CPUX86State *env, int dflag)
{
int cpl, selector;
@@ -1048,8 +1051,8 @@
#endif
/* real mode interrupt */
-static void do_interrupt_real(int intno, int is_int, int error_code,
- unsigned int next_eip)
+static void do_interrupt_real(CPUX86State *env, int intno, int is_int,
+ int error_code, unsigned int next_eip)
{
SegmentCache *dt;
target_ulong ptr, ssp;
@@ -1063,8 +1066,8 @@
raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);
}
ptr = dt->base + intno * 4;
- offset = lduw_kernel(ptr);
- selector = lduw_kernel(ptr + 2);
+ offset = cpu_lduw_kernel(env, ptr);
+ selector = cpu_lduw_kernel(env, ptr + 2);
esp = ESP;
ssp = env->segs[R_SS].base;
if (is_int) {
@@ -1088,8 +1091,8 @@
#if defined(CONFIG_USER_ONLY)
/* fake user mode interrupt */
-static void do_interrupt_user(int intno, int is_int, int error_code,
- target_ulong next_eip)
+static void do_interrupt_user(CPUX86State *env, int intno, int is_int,
+ int error_code, target_ulong next_eip)
{
SegmentCache *dt;
target_ulong ptr;
@@ -1103,7 +1106,7 @@
shift = 3;
}
ptr = dt->base + (intno << shift);
- e2 = ldl_kernel(ptr + 4);
+ e2 = cpu_ldl_kernel(env, ptr + 4);
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
cpl = env->hflags & HF_CPL_MASK;
@@ -1122,8 +1125,8 @@
#else
-static void handle_even_inj(int intno, int is_int, int error_code,
- int is_hw, int rm)
+static void handle_even_inj(CPUX86State *env, int intno, int is_int,
+ int error_code, int is_hw, int rm)
{
uint32_t event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb,
control.event_inj));
@@ -1154,8 +1157,8 @@
* the int instruction. next_eip is the EIP value AFTER the interrupt
* instruction. It is only relevant if is_int is TRUE.
*/
-static void do_interrupt_all(int intno, int is_int, int error_code,
- target_ulong next_eip, int is_hw)
+static void do_interrupt_all(CPUX86State *env, int intno, int is_int,
+ int error_code, target_ulong next_eip, int is_hw)
{
if (qemu_loglevel_mask(CPU_LOG_INT)) {
if ((env->cr[0] & CR0_PE_MASK)) {
@@ -1194,24 +1197,25 @@
if (env->cr[0] & CR0_PE_MASK) {
#if !defined(CONFIG_USER_ONLY)
if (env->hflags & HF_SVMI_MASK) {
- handle_even_inj(intno, is_int, error_code, is_hw, 0);
+ handle_even_inj(env, intno, is_int, error_code, is_hw, 0);
}
#endif
#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) {
- do_interrupt64(intno, is_int, error_code, next_eip, is_hw);
+ do_interrupt64(env, intno, is_int, error_code, next_eip, is_hw);
} else
#endif
{
- do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw);
+ do_interrupt_protected(env, intno, is_int, error_code, next_eip,
+ is_hw);
}
} else {
#if !defined(CONFIG_USER_ONLY)
if (env->hflags & HF_SVMI_MASK) {
- handle_even_inj(intno, is_int, error_code, is_hw, 1);
+ handle_even_inj(env, intno, is_int, error_code, is_hw, 1);
}
#endif
- do_interrupt_real(intno, is_int, error_code, next_eip);
+ do_interrupt_real(env, intno, is_int, error_code, next_eip);
}
#if !defined(CONFIG_USER_ONLY)
@@ -1226,17 +1230,13 @@
#endif
}
-void do_interrupt(CPUX86State *env1)
+void do_interrupt(CPUX86State *env)
{
- CPUX86State *saved_env;
-
- saved_env = env;
- env = env1;
#if defined(CONFIG_USER_ONLY)
/* if user mode only, we simulate a fake exception
which will be handled outside the cpu execution
loop */
- do_interrupt_user(env->exception_index,
+ do_interrupt_user(env, env->exception_index,
env->exception_is_int,
env->error_code,
env->exception_next_eip);
@@ -1246,27 +1246,22 @@
/* simulate a real cpu exception. On i386, it can
trigger new exceptions, but we do not handle
double or triple faults yet. */
- do_interrupt_all(env->exception_index,
+ do_interrupt_all(env, env->exception_index,
env->exception_is_int,
env->error_code,
env->exception_next_eip, 0);
/* successfully delivered */
env->old_exception = -1;
#endif
- env = saved_env;
}
-void do_interrupt_x86_hardirq(CPUX86State *env1, int intno, int is_hw)
+void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw)
{
- CPUX86State *saved_env;
-
- saved_env = env;
- env = env1;
- do_interrupt_all(intno, 0, 0, 0, is_hw);
- env = saved_env;
+ do_interrupt_all(env, intno, 0, 0, 0, is_hw);
}
-void helper_enter_level(int level, int data32, target_ulong t1)
+void helper_enter_level(CPUX86State *env, int level, int data32,
+ target_ulong t1)
{
target_ulong ssp;
uint32_t esp_mask, esp, ebp;
@@ -1281,25 +1276,28 @@
while (--level) {
esp -= 4;
ebp -= 4;
- stl(ssp + (esp & esp_mask), ldl(ssp + (ebp & esp_mask)));
+ cpu_stl_data(env, ssp + (esp & esp_mask),
+ cpu_ldl_data(env, ssp + (ebp & esp_mask)));
}
esp -= 4;
- stl(ssp + (esp & esp_mask), t1);
+ cpu_stl_data(env, ssp + (esp & esp_mask), t1);
} else {
/* 16 bit */
esp -= 2;
while (--level) {
esp -= 2;
ebp -= 2;
- stw(ssp + (esp & esp_mask), lduw(ssp + (ebp & esp_mask)));
+ cpu_stw_data(env, ssp + (esp & esp_mask),
+ cpu_lduw_data(env, ssp + (ebp & esp_mask)));
}
esp -= 2;
- stw(ssp + (esp & esp_mask), t1);
+ cpu_stw_data(env, ssp + (esp & esp_mask), t1);
}
}
#ifdef TARGET_X86_64
-void helper_enter64_level(int level, int data64, target_ulong t1)
+void helper_enter64_level(CPUX86State *env, int level, int data64,
+ target_ulong t1)
{
target_ulong esp, ebp;
@@ -1312,25 +1310,25 @@
while (--level) {
esp -= 8;
ebp -= 8;
- stq(esp, ldq(ebp));
+ cpu_stq_data(env, esp, cpu_ldq_data(env, ebp));
}
esp -= 8;
- stq(esp, t1);
+ cpu_stq_data(env, esp, t1);
} else {
/* 16 bit */
esp -= 2;
while (--level) {
esp -= 2;
ebp -= 2;
- stw(esp, lduw(ebp));
+ cpu_stw_data(env, esp, cpu_lduw_data(env, ebp));
}
esp -= 2;
- stw(esp, t1);
+ cpu_stw_data(env, esp, t1);
}
}
#endif
-void helper_lldt(int selector)
+void helper_lldt(CPUX86State *env, int selector)
{
SegmentCache *dt;
uint32_t e1, e2;
@@ -1360,8 +1358,8 @@
raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
ptr = dt->base + index;
- e1 = ldl_kernel(ptr);
- e2 = ldl_kernel(ptr + 4);
+ e1 = cpu_ldl_kernel(env, ptr);
+ e2 = cpu_ldl_kernel(env, ptr + 4);
if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) {
raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
@@ -1372,7 +1370,7 @@
if (env->hflags & HF_LMA_MASK) {
uint32_t e3;
- e3 = ldl_kernel(ptr + 8);
+ e3 = cpu_ldl_kernel(env, ptr + 8);
load_seg_cache_raw_dt(&env->ldt, e1, e2);
env->ldt.base |= (target_ulong)e3 << 32;
} else
@@ -1384,7 +1382,7 @@
env->ldt.selector = selector;
}
-void helper_ltr(int selector)
+void helper_ltr(CPUX86State *env, int selector)
{
SegmentCache *dt;
uint32_t e1, e2;
@@ -1415,8 +1413,8 @@
raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
ptr = dt->base + index;
- e1 = ldl_kernel(ptr);
- e2 = ldl_kernel(ptr + 4);
+ e1 = cpu_ldl_kernel(env, ptr);
+ e2 = cpu_ldl_kernel(env, ptr + 4);
type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
if ((e2 & DESC_S_MASK) ||
(type != 1 && type != 9)) {
@@ -1429,8 +1427,8 @@
if (env->hflags & HF_LMA_MASK) {
uint32_t e3, e4;
- e3 = ldl_kernel(ptr + 8);
- e4 = ldl_kernel(ptr + 12);
+ e3 = cpu_ldl_kernel(env, ptr + 8);
+ e4 = cpu_ldl_kernel(env, ptr + 12);
if ((e4 >> DESC_TYPE_SHIFT) & 0xf) {
raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
@@ -1442,13 +1440,13 @@
load_seg_cache_raw_dt(&env->tr, e1, e2);
}
e2 |= DESC_TSS_BUSY_MASK;
- stl_kernel(ptr + 4, e2);
+ cpu_stl_kernel(env, ptr + 4, e2);
}
env->tr.selector = selector;
}
/* only works if protected mode and not VM86. seg_reg must be != R_CS */
-void helper_load_seg(int seg_reg, int selector)
+void helper_load_seg(CPUX86State *env, int seg_reg, int selector)
{
uint32_t e1, e2;
int cpl, dpl, rpl;
@@ -1480,8 +1478,8 @@
raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
ptr = dt->base + index;
- e1 = ldl_kernel(ptr);
- e2 = ldl_kernel(ptr + 4);
+ e1 = cpu_ldl_kernel(env, ptr);
+ e2 = cpu_ldl_kernel(env, ptr + 4);
if (!(e2 & DESC_S_MASK)) {
raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
@@ -1521,7 +1519,7 @@
/* set the access bit if not already set */
if (!(e2 & DESC_A_MASK)) {
e2 |= DESC_A_MASK;
- stl_kernel(ptr + 4, e2);
+ cpu_stl_kernel(env, ptr + 4, e2);
}
cpu_x86_load_seg_cache(env, seg_reg, selector,
@@ -1536,7 +1534,7 @@
}
/* protected mode jump */
-void helper_ljmp_protected(int new_cs, target_ulong new_eip,
+void helper_ljmp_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
int next_eip_addend)
{
int gate_cs, type;
@@ -1546,7 +1544,7 @@
if ((new_cs & 0xfffc) == 0) {
raise_exception_err(env, EXCP0D_GPF, 0);
}
- if (load_segment(&e1, &e2, new_cs) != 0) {
+ if (load_segment(env, &e1, &e2, new_cs) != 0) {
raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
cpl = env->hflags & HF_CPL_MASK;
@@ -1595,7 +1593,7 @@
raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
next_eip = env->eip + next_eip_addend;
- switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, next_eip);
+ switch_tss(env, new_cs, e1, e2, SWITCH_TSS_JMP, next_eip);
CC_OP = CC_OP_EFLAGS;
break;
case 4: /* 286 call gate */
@@ -1611,7 +1609,7 @@
if (type == 12) {
new_eip |= (e2 & 0xffff0000);
}
- if (load_segment(&e1, &e2, gate_cs) != 0) {
+ if (load_segment(env, &e1, &e2, gate_cs) != 0) {
raise_exception_err(env, EXCP0D_GPF, gate_cs & 0xfffc);
}
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
@@ -1643,7 +1641,7 @@
}
/* real mode call */
-void helper_lcall_real(int new_cs, target_ulong new_eip1,
+void helper_lcall_real(CPUX86State *env, int new_cs, target_ulong new_eip1,
int shift, int next_eip)
{
int new_eip;
@@ -1669,7 +1667,7 @@
}
/* protected mode call */
-void helper_lcall_protected(int new_cs, target_ulong new_eip,
+void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
int shift, int next_eip_addend)
{
int new_stack, i;
@@ -1684,7 +1682,7 @@
if ((new_cs & 0xfffc) == 0) {
raise_exception_err(env, EXCP0D_GPF, 0);
}
- if (load_segment(&e1, &e2, new_cs) != 0) {
+ if (load_segment(env, &e1, &e2, new_cs) != 0) {
raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
cpl = env->hflags & HF_CPL_MASK;
@@ -1764,7 +1762,7 @@
if (dpl < cpl || dpl < rpl) {
raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
- switch_tss(new_cs, e1, e2, SWITCH_TSS_CALL, next_eip);
+ switch_tss(env, new_cs, e1, e2, SWITCH_TSS_CALL, next_eip);
CC_OP = CC_OP_EFLAGS;
return;
case 4: /* 286 call gate */
@@ -1790,7 +1788,7 @@
raise_exception_err(env, EXCP0D_GPF, 0);
}
- if (load_segment(&e1, &e2, selector) != 0) {
+ if (load_segment(env, &e1, &e2, selector) != 0) {
raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) {
@@ -1806,7 +1804,7 @@
if (!(e2 & DESC_C_MASK) && dpl < cpl) {
/* to inner privilege */
- get_ss_esp_from_tss(&ss, &sp, dpl);
+ get_ss_esp_from_tss(env, &ss, &sp, dpl);
LOG_PCALL("new ss:esp=%04x:%08x param_count=%d ESP=" TARGET_FMT_lx
"\n",
ss, sp, param_count, ESP);
@@ -1816,7 +1814,7 @@
if ((ss & 3) != dpl) {
raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
- if (load_segment(&ss_e1, &ss_e2, ss) != 0) {
+ if (load_segment(env, &ss_e1, &ss_e2, ss) != 0) {
raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
@@ -1843,14 +1841,16 @@
PUSHL(ssp, sp, sp_mask, env->segs[R_SS].selector);
PUSHL(ssp, sp, sp_mask, ESP);
for (i = param_count - 1; i >= 0; i--) {
- val = ldl_kernel(old_ssp + ((ESP + i * 4) & old_sp_mask));
+ val = cpu_ldl_kernel(env, old_ssp + ((ESP + i * 4) &
+ old_sp_mask));
PUSHL(ssp, sp, sp_mask, val);
}
} else {
PUSHW(ssp, sp, sp_mask, env->segs[R_SS].selector);
PUSHW(ssp, sp, sp_mask, ESP);
for (i = param_count - 1; i >= 0; i--) {
- val = lduw_kernel(old_ssp + ((ESP + i * 2) & old_sp_mask));
+ val = cpu_lduw_kernel(env, old_ssp + ((ESP + i * 2) &
+ old_sp_mask));
PUSHW(ssp, sp, sp_mask, val);
}
}
@@ -1894,7 +1894,7 @@
}
/* real and vm86 mode iret */
-void helper_iret_real(int shift)
+void helper_iret_real(CPUX86State *env, int shift)
{
uint32_t sp, new_cs, new_eip, new_eflags, sp_mask;
target_ulong ssp;
@@ -1933,7 +1933,7 @@
env->hflags2 &= ~HF2_NMI_MASK;
}
-static inline void validate_seg(int seg_reg, int cpl)
+static inline void validate_seg(CPUX86State *env, int seg_reg, int cpl)
{
int dpl;
uint32_t e2;
@@ -1957,7 +1957,8 @@
}
/* protected mode iret */
-static inline void helper_ret_protected(int shift, int is_iret, int addend)
+static inline void helper_ret_protected(CPUX86State *env, int shift,
+ int is_iret, int addend)
{
uint32_t new_cs, new_eflags, new_ss;
uint32_t new_es, new_ds, new_fs, new_gs;
@@ -2013,7 +2014,7 @@
if ((new_cs & 0xfffc) == 0) {
raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
- if (load_segment(&e1, &e2, new_cs) != 0) {
+ if (load_segment(env, &e1, &e2, new_cs) != 0) {
raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
if (!(e2 & DESC_S_MASK) ||
@@ -2090,7 +2091,7 @@
if ((new_ss & 3) != rpl) {
raise_exception_err(env, EXCP0D_GPF, new_ss & 0xfffc);
}
- if (load_segment(&ss_e1, &ss_e2, new_ss) != 0) {
+ if (load_segment(env, &ss_e1, &ss_e2, new_ss) != 0) {
raise_exception_err(env, EXCP0D_GPF, new_ss & 0xfffc);
}
if (!(ss_e2 & DESC_S_MASK) ||
@@ -2127,10 +2128,10 @@
}
/* validate data segments */
- validate_seg(R_ES, rpl);
- validate_seg(R_DS, rpl);
- validate_seg(R_FS, rpl);
- validate_seg(R_GS, rpl);
+ validate_seg(env, R_ES, rpl);
+ validate_seg(env, R_DS, rpl);
+ validate_seg(env, R_FS, rpl);
+ validate_seg(env, R_GS, rpl);
sp += addend;
}
@@ -2165,19 +2166,19 @@
cpu_load_eflags(env, new_eflags, TF_MASK | AC_MASK | ID_MASK |
IF_MASK | IOPL_MASK | VM_MASK | NT_MASK | VIF_MASK |
VIP_MASK);
- load_seg_vm(R_CS, new_cs & 0xffff);
+ load_seg_vm(env, R_CS, new_cs & 0xffff);
cpu_x86_set_cpl(env, 3);
- load_seg_vm(R_SS, new_ss & 0xffff);
- load_seg_vm(R_ES, new_es & 0xffff);
- load_seg_vm(R_DS, new_ds & 0xffff);
- load_seg_vm(R_FS, new_fs & 0xffff);
- load_seg_vm(R_GS, new_gs & 0xffff);
+ load_seg_vm(env, R_SS, new_ss & 0xffff);
+ load_seg_vm(env, R_ES, new_es & 0xffff);
+ load_seg_vm(env, R_DS, new_ds & 0xffff);
+ load_seg_vm(env, R_FS, new_fs & 0xffff);
+ load_seg_vm(env, R_GS, new_gs & 0xffff);
env->eip = new_eip & 0xffff;
ESP = new_esp;
}
-void helper_iret_protected(int shift, int next_eip)
+void helper_iret_protected(CPUX86State *env, int shift, int next_eip)
{
int tss_selector, type;
uint32_t e1, e2;
@@ -2189,11 +2190,11 @@
raise_exception_err(env, EXCP0D_GPF, 0);
}
#endif
- tss_selector = lduw_kernel(env->tr.base + 0);
+ tss_selector = cpu_lduw_kernel(env, env->tr.base + 0);
if (tss_selector & 4) {
raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc);
}
- if (load_segment(&e1, &e2, tss_selector) != 0) {
+ if (load_segment(env, &e1, &e2, tss_selector) != 0) {
raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc);
}
type = (e2 >> DESC_TYPE_SHIFT) & 0x17;
@@ -2201,19 +2202,19 @@
if (type != 3) {
raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc);
}
- switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, next_eip);
+ switch_tss(env, tss_selector, e1, e2, SWITCH_TSS_IRET, next_eip);
} else {
- helper_ret_protected(shift, 1, 0);
+ helper_ret_protected(env, shift, 1, 0);
}
env->hflags2 &= ~HF2_NMI_MASK;
}
-void helper_lret_protected(int shift, int addend)
+void helper_lret_protected(CPUX86State *env, int shift, int addend)
{
- helper_ret_protected(shift, 0, addend);
+ helper_ret_protected(env, shift, 0, addend);
}
-void helper_sysenter(void)
+void helper_sysenter(CPUX86State *env)
{
if (env->sysenter_cs == 0) {
raise_exception_err(env, EXCP0D_GPF, 0);
@@ -2247,7 +2248,7 @@
EIP = env->sysenter_eip;
}
-void helper_sysexit(int dflag)
+void helper_sysexit(CPUX86State *env, int dflag)
{
int cpl;
@@ -2287,18 +2288,18 @@
EIP = EDX;
}
-target_ulong helper_lsl(target_ulong selector1)
+target_ulong helper_lsl(CPUX86State *env, target_ulong selector1)
{
unsigned int limit;
uint32_t e1, e2, eflags, selector;
int rpl, dpl, cpl, type;
selector = selector1 & 0xffff;
- eflags = helper_cc_compute_all(CC_OP);
+ eflags = cpu_cc_compute_all(env, CC_OP);
if ((selector & 0xfffc) == 0) {
goto fail;
}
- if (load_segment(&e1, &e2, selector) != 0) {
+ if (load_segment(env, &e1, &e2, selector) != 0) {
goto fail;
}
rpl = selector & 3;
@@ -2335,17 +2336,17 @@
return limit;
}
-target_ulong helper_lar(target_ulong selector1)
+target_ulong helper_lar(CPUX86State *env, target_ulong selector1)
{
uint32_t e1, e2, eflags, selector;
int rpl, dpl, cpl, type;
selector = selector1 & 0xffff;
- eflags = helper_cc_compute_all(CC_OP);
+ eflags = cpu_cc_compute_all(env, CC_OP);
if ((selector & 0xfffc) == 0) {
goto fail;
}
- if (load_segment(&e1, &e2, selector) != 0) {
+ if (load_segment(env, &e1, &e2, selector) != 0) {
goto fail;
}
rpl = selector & 3;
@@ -2384,17 +2385,17 @@
return e2 & 0x00f0ff00;
}
-void helper_verr(target_ulong selector1)
+void helper_verr(CPUX86State *env, target_ulong selector1)
{
uint32_t e1, e2, eflags, selector;
int rpl, dpl, cpl;
selector = selector1 & 0xffff;
- eflags = helper_cc_compute_all(CC_OP);
+ eflags = cpu_cc_compute_all(env, CC_OP);
if ((selector & 0xfffc) == 0) {
goto fail;
}
- if (load_segment(&e1, &e2, selector) != 0) {
+ if (load_segment(env, &e1, &e2, selector) != 0) {
goto fail;
}
if (!(e2 & DESC_S_MASK)) {
@@ -2422,17 +2423,17 @@
CC_SRC = eflags | CC_Z;
}
-void helper_verw(target_ulong selector1)
+void helper_verw(CPUX86State *env, target_ulong selector1)
{
uint32_t e1, e2, eflags, selector;
int rpl, dpl, cpl;
selector = selector1 & 0xffff;
- eflags = helper_cc_compute_all(CC_OP);
+ eflags = cpu_cc_compute_all(env, CC_OP);
if ((selector & 0xfffc) == 0) {
goto fail;
}
- if (load_segment(&e1, &e2, selector) != 0) {
+ if (load_segment(env, &e1, &e2, selector) != 0) {
goto fail;
}
if (!(e2 & DESC_S_MASK)) {
@@ -2457,19 +2458,14 @@
}
#if defined(CONFIG_USER_ONLY)
-void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
+void cpu_x86_load_seg(CPUX86State *env, int seg_reg, int selector)
{
- CPUX86State *saved_env;
-
- saved_env = env;
- env = s;
if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
selector &= 0xffff;
cpu_x86_load_seg_cache(env, seg_reg, selector,
(selector << 4), 0xffff, 0);
} else {
- helper_load_seg(seg_reg, selector);
+ helper_load_seg(env, seg_reg, selector);
}
- env = saved_env;
}
#endif
diff --git a/target-i386/shift_helper_template.h b/target-i386/shift_helper_template.h
index 239ee09..dda0da3 100644
--- a/target-i386/shift_helper_template.h
+++ b/target-i386/shift_helper_template.h
@@ -41,7 +41,8 @@
#error unhandled operand size
#endif
-target_ulong glue(helper_rcl, SUFFIX)(target_ulong t0, target_ulong t1)
+target_ulong glue(helper_rcl, SUFFIX)(CPUX86State *env, target_ulong t0,
+ target_ulong t1)
{
int count, eflags;
target_ulong src;
@@ -54,7 +55,7 @@
count = rclb_table[count];
#endif
if (count) {
- eflags = helper_cc_compute_all(CC_OP);
+ eflags = helper_cc_compute_all(env, CC_OP);
t0 &= DATA_MASK;
src = t0;
res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
@@ -71,7 +72,8 @@
return t0;
}
-target_ulong glue(helper_rcr, SUFFIX)(target_ulong t0, target_ulong t1)
+target_ulong glue(helper_rcr, SUFFIX)(CPUX86State *env, target_ulong t0,
+ target_ulong t1)
{
int count, eflags;
target_ulong src;
@@ -84,7 +86,7 @@
count = rclb_table[count];
#endif
if (count) {
- eflags = helper_cc_compute_all(CC_OP);
+ eflags = helper_cc_compute_all(env, CC_OP);
t0 &= DATA_MASK;
src = t0;
res = (t0 >> count) |
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index bc1bfa2..8b04eb2 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -18,18 +18,17 @@
*/
#include "cpu.h"
-#include "dyngen-exec.h"
#include "helper.h"
/* SMM support */
#if defined(CONFIG_USER_ONLY)
-void do_smm_enter(CPUX86State *env1)
+void do_smm_enter(CPUX86State *env)
{
}
-void helper_rsm(void)
+void helper_rsm(CPUX86State *env)
{
}
@@ -41,15 +40,11 @@
#define SMM_REVISION_ID 0x00020000
#endif
-void do_smm_enter(CPUX86State *env1)
+void do_smm_enter(CPUX86State *env)
{
target_ulong sm_state;
SegmentCache *dt;
int i, offset;
- CPUX86State *saved_env;
-
- saved_env = env;
- env = env1;
qemu_log_mask(CPU_LOG_INT, "SMM: enter\n");
log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP);
@@ -180,10 +175,9 @@
cpu_x86_update_cr4(env, 0);
env->dr[7] = 0x00000400;
CC_OP = CC_OP_EFLAGS;
- env = saved_env;
}
-void helper_rsm(void)
+void helper_rsm(CPUX86State *env)
{
target_ulong sm_state;
int i, offset;
diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c
index 64d842c..4943c37 100644
--- a/target-i386/svm_helper.c
+++ b/target-i386/svm_helper.c
@@ -18,46 +18,50 @@
*/
#include "cpu.h"
-#include "dyngen-exec.h"
+#include "cpu-all.h"
#include "helper.h"
+#if !defined(CONFIG_USER_ONLY)
+#include "softmmu_exec.h"
+#endif /* !defined(CONFIG_USER_ONLY) */
+
/* Secure Virtual Machine helpers */
#if defined(CONFIG_USER_ONLY)
-void helper_vmrun(int aflag, int next_eip_addend)
+void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
{
}
-void helper_vmmcall(void)
+void helper_vmmcall(CPUX86State *env)
{
}
-void helper_vmload(int aflag)
+void helper_vmload(CPUX86State *env, int aflag)
{
}
-void helper_vmsave(int aflag)
+void helper_vmsave(CPUX86State *env, int aflag)
{
}
-void helper_stgi(void)
+void helper_stgi(CPUX86State *env)
{
}
-void helper_clgi(void)
+void helper_clgi(CPUX86State *env)
{
}
-void helper_skinit(void)
+void helper_skinit(CPUX86State *env)
{
}
-void helper_invlpga(int aflag)
+void helper_invlpga(CPUX86State *env, int aflag)
{
}
-void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
+void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
{
}
@@ -65,7 +69,8 @@
{
}
-void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
+void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type,
+ uint64_t param)
{
}
@@ -74,13 +79,13 @@
{
}
-void helper_svm_check_io(uint32_t port, uint32_t param,
+void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param,
uint32_t next_eip_addend)
{
}
#else
-static inline void svm_save_seg(target_phys_addr_t addr,
+static inline void svm_save_seg(CPUX86State *env, target_phys_addr_t addr,
const SegmentCache *sc)
{
stw_phys(addr + offsetof(struct vmcb_seg, selector),
@@ -93,7 +98,8 @@
((sc->flags >> 8) & 0xff) | ((sc->flags >> 12) & 0x0f00));
}
-static inline void svm_load_seg(target_phys_addr_t addr, SegmentCache *sc)
+static inline void svm_load_seg(CPUX86State *env, target_phys_addr_t addr,
+ SegmentCache *sc)
{
unsigned int flags;
@@ -104,23 +110,23 @@
sc->flags = ((flags & 0xff) << 8) | ((flags & 0x0f00) << 12);
}
-static inline void svm_load_seg_cache(target_phys_addr_t addr,
- CPUX86State *env, int seg_reg)
+static inline void svm_load_seg_cache(CPUX86State *env, target_phys_addr_t addr,
+ int seg_reg)
{
SegmentCache sc1, *sc = &sc1;
- svm_load_seg(addr, sc);
+ svm_load_seg(env, addr, sc);
cpu_x86_load_seg_cache(env, seg_reg, sc->selector,
sc->base, sc->limit, sc->flags);
}
-void helper_vmrun(int aflag, int next_eip_addend)
+void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
{
target_ulong addr;
uint32_t event_inj;
uint32_t int_ctl;
- helper_svm_check_intercept_param(SVM_EXIT_VMRUN, 0);
+ cpu_svm_check_intercept_param(env, SVM_EXIT_VMRUN, 0);
if (aflag == 2) {
addr = EAX;
@@ -154,13 +160,13 @@
stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rflags),
cpu_compute_eflags(env));
- svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.es),
+ svm_save_seg(env, env->vm_hsave + offsetof(struct vmcb, save.es),
&env->segs[R_ES]);
- svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.cs),
+ svm_save_seg(env, env->vm_hsave + offsetof(struct vmcb, save.cs),
&env->segs[R_CS]);
- svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.ss),
+ svm_save_seg(env, env->vm_hsave + offsetof(struct vmcb, save.ss),
&env->segs[R_SS]);
- svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.ds),
+ svm_save_seg(env, env->vm_hsave + offsetof(struct vmcb, save.ds),
&env->segs[R_DS]);
stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip),
@@ -233,14 +239,14 @@
~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
CC_OP = CC_OP_EFLAGS;
- svm_load_seg_cache(env->vm_vmcb + offsetof(struct vmcb, save.es),
- env, R_ES);
- svm_load_seg_cache(env->vm_vmcb + offsetof(struct vmcb, save.cs),
- env, R_CS);
- svm_load_seg_cache(env->vm_vmcb + offsetof(struct vmcb, save.ss),
- env, R_SS);
- svm_load_seg_cache(env->vm_vmcb + offsetof(struct vmcb, save.ds),
- env, R_DS);
+ svm_load_seg_cache(env, env->vm_vmcb + offsetof(struct vmcb, save.es),
+ R_ES);
+ svm_load_seg_cache(env, env->vm_vmcb + offsetof(struct vmcb, save.cs),
+ R_CS);
+ svm_load_seg_cache(env, env->vm_vmcb + offsetof(struct vmcb, save.ss),
+ R_SS);
+ svm_load_seg_cache(env, env->vm_vmcb + offsetof(struct vmcb, save.ds),
+ R_DS);
EIP = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip));
env->eip = EIP;
@@ -320,17 +326,17 @@
}
}
-void helper_vmmcall(void)
+void helper_vmmcall(CPUX86State *env)
{
- helper_svm_check_intercept_param(SVM_EXIT_VMMCALL, 0);
+ cpu_svm_check_intercept_param(env, SVM_EXIT_VMMCALL, 0);
raise_exception(env, EXCP06_ILLOP);
}
-void helper_vmload(int aflag)
+void helper_vmload(CPUX86State *env, int aflag)
{
target_ulong addr;
- helper_svm_check_intercept_param(SVM_EXIT_VMLOAD, 0);
+ cpu_svm_check_intercept_param(env, SVM_EXIT_VMLOAD, 0);
if (aflag == 2) {
addr = EAX;
@@ -340,17 +346,14 @@
qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmload! " TARGET_FMT_lx
"\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n",
- addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)),
+ addr, ldq_phys(addr + offsetof(struct vmcb,
+ save.fs.base)),
env->segs[R_FS].base);
- svm_load_seg_cache(addr + offsetof(struct vmcb, save.fs),
- env, R_FS);
- svm_load_seg_cache(addr + offsetof(struct vmcb, save.gs),
- env, R_GS);
- svm_load_seg(addr + offsetof(struct vmcb, save.tr),
- &env->tr);
- svm_load_seg(addr + offsetof(struct vmcb, save.ldtr),
- &env->ldt);
+ svm_load_seg_cache(env, addr + offsetof(struct vmcb, save.fs), R_FS);
+ svm_load_seg_cache(env, addr + offsetof(struct vmcb, save.gs), R_GS);
+ svm_load_seg(env, addr + offsetof(struct vmcb, save.tr), &env->tr);
+ svm_load_seg(env, addr + offsetof(struct vmcb, save.ldtr), &env->ldt);
#ifdef TARGET_X86_64
env->kernelgsbase = ldq_phys(addr + offsetof(struct vmcb,
@@ -367,11 +370,11 @@
save.sysenter_eip));
}
-void helper_vmsave(int aflag)
+void helper_vmsave(CPUX86State *env, int aflag)
{
target_ulong addr;
- helper_svm_check_intercept_param(SVM_EXIT_VMSAVE, 0);
+ cpu_svm_check_intercept_param(env, SVM_EXIT_VMSAVE, 0);
if (aflag == 2) {
addr = EAX;
@@ -384,13 +387,13 @@
addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)),
env->segs[R_FS].base);
- svm_save_seg(addr + offsetof(struct vmcb, save.fs),
+ svm_save_seg(env, addr + offsetof(struct vmcb, save.fs),
&env->segs[R_FS]);
- svm_save_seg(addr + offsetof(struct vmcb, save.gs),
+ svm_save_seg(env, addr + offsetof(struct vmcb, save.gs),
&env->segs[R_GS]);
- svm_save_seg(addr + offsetof(struct vmcb, save.tr),
+ svm_save_seg(env, addr + offsetof(struct vmcb, save.tr),
&env->tr);
- svm_save_seg(addr + offsetof(struct vmcb, save.ldtr),
+ svm_save_seg(env, addr + offsetof(struct vmcb, save.ldtr),
&env->ldt);
#ifdef TARGET_X86_64
@@ -408,30 +411,30 @@
env->sysenter_eip);
}
-void helper_stgi(void)
+void helper_stgi(CPUX86State *env)
{
- helper_svm_check_intercept_param(SVM_EXIT_STGI, 0);
+ cpu_svm_check_intercept_param(env, SVM_EXIT_STGI, 0);
env->hflags2 |= HF2_GIF_MASK;
}
-void helper_clgi(void)
+void helper_clgi(CPUX86State *env)
{
- helper_svm_check_intercept_param(SVM_EXIT_CLGI, 0);
+ cpu_svm_check_intercept_param(env, SVM_EXIT_CLGI, 0);
env->hflags2 &= ~HF2_GIF_MASK;
}
-void helper_skinit(void)
+void helper_skinit(CPUX86State *env)
{
- helper_svm_check_intercept_param(SVM_EXIT_SKINIT, 0);
+ cpu_svm_check_intercept_param(env, SVM_EXIT_SKINIT, 0);
/* XXX: not implemented */
raise_exception(env, EXCP06_ILLOP);
}
-void helper_invlpga(int aflag)
+void helper_invlpga(CPUX86State *env, int aflag)
{
target_ulong addr;
- helper_svm_check_intercept_param(SVM_EXIT_INVLPGA, 0);
+ cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPGA, 0);
if (aflag == 2) {
addr = EAX;
@@ -444,7 +447,8 @@
tlb_flush_page(env, addr);
}
-void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
+void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type,
+ uint64_t param)
{
if (likely(!(env->hflags & HF_SVMI_MASK))) {
return;
@@ -452,27 +456,27 @@
switch (type) {
case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8:
if (env->intercept_cr_read & (1 << (type - SVM_EXIT_READ_CR0))) {
- helper_vmexit(type, param);
+ helper_vmexit(env, type, param);
}
break;
case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8:
if (env->intercept_cr_write & (1 << (type - SVM_EXIT_WRITE_CR0))) {
- helper_vmexit(type, param);
+ helper_vmexit(env, type, param);
}
break;
case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 7:
if (env->intercept_dr_read & (1 << (type - SVM_EXIT_READ_DR0))) {
- helper_vmexit(type, param);
+ helper_vmexit(env, type, param);
}
break;
case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 7:
if (env->intercept_dr_write & (1 << (type - SVM_EXIT_WRITE_DR0))) {
- helper_vmexit(type, param);
+ helper_vmexit(env, type, param);
}
break;
case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 31:
if (env->intercept_exceptions & (1 << (type - SVM_EXIT_EXCP_BASE))) {
- helper_vmexit(type, param);
+ helper_vmexit(env, type, param);
}
break;
case SVM_EXIT_MSR:
@@ -499,36 +503,31 @@
t0 %= 8;
break;
default:
- helper_vmexit(type, param);
+ helper_vmexit(env, type, param);
t0 = 0;
t1 = 0;
break;
}
if (ldub_phys(addr + t1) & ((1 << param) << t0)) {
- helper_vmexit(type, param);
+ helper_vmexit(env, type, param);
}
}
break;
default:
if (env->intercept & (1ULL << (type - SVM_EXIT_INTR))) {
- helper_vmexit(type, param);
+ helper_vmexit(env, type, param);
}
break;
}
}
-void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
+void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
uint64_t param)
{
- CPUX86State *saved_env;
-
- saved_env = env;
- env = env1;
- helper_svm_check_intercept_param(type, param);
- env = saved_env;
+ helper_svm_check_intercept_param(env, type, param);
}
-void helper_svm_check_io(uint32_t port, uint32_t param,
+void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param,
uint32_t next_eip_addend)
{
if (env->intercept & (1ULL << (SVM_EXIT_IOIO - SVM_EXIT_INTR))) {
@@ -541,13 +540,13 @@
/* next EIP */
stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
env->eip + next_eip_addend);
- helper_vmexit(SVM_EXIT_IOIO, param | (port << 16));
+ helper_vmexit(env, SVM_EXIT_IOIO, param | (port << 16));
}
}
}
/* Note: currently only 32 bits of exit_code are used */
-void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
+void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
{
uint32_t int_ctl;
@@ -567,13 +566,13 @@
}
/* Save the VM state in the vmcb */
- svm_save_seg(env->vm_vmcb + offsetof(struct vmcb, save.es),
+ svm_save_seg(env, env->vm_vmcb + offsetof(struct vmcb, save.es),
&env->segs[R_ES]);
- svm_save_seg(env->vm_vmcb + offsetof(struct vmcb, save.cs),
+ svm_save_seg(env, env->vm_vmcb + offsetof(struct vmcb, save.cs),
&env->segs[R_CS]);
- svm_save_seg(env->vm_vmcb + offsetof(struct vmcb, save.ss),
+ svm_save_seg(env, env->vm_vmcb + offsetof(struct vmcb, save.ss),
&env->segs[R_SS]);
- svm_save_seg(env->vm_vmcb + offsetof(struct vmcb, save.ds),
+ svm_save_seg(env, env->vm_vmcb + offsetof(struct vmcb, save.ds),
&env->segs[R_DS]);
stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.gdtr.base),
@@ -602,7 +601,8 @@
stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags),
cpu_compute_eflags(env));
- stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip), env->eip);
+ stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip),
+ env->eip);
stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp), ESP);
stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax), EAX);
stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7), env->dr[7]);
@@ -645,14 +645,14 @@
~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
CC_OP = CC_OP_EFLAGS;
- svm_load_seg_cache(env->vm_hsave + offsetof(struct vmcb, save.es),
- env, R_ES);
- svm_load_seg_cache(env->vm_hsave + offsetof(struct vmcb, save.cs),
- env, R_CS);
- svm_load_seg_cache(env->vm_hsave + offsetof(struct vmcb, save.ss),
- env, R_SS);
- svm_load_seg_cache(env->vm_hsave + offsetof(struct vmcb, save.ds),
- env, R_DS);
+ svm_load_seg_cache(env, env->vm_hsave + offsetof(struct vmcb, save.es),
+ R_ES);
+ svm_load_seg_cache(env, env->vm_hsave + offsetof(struct vmcb, save.cs),
+ R_CS);
+ svm_load_seg_cache(env, env->vm_hsave + offsetof(struct vmcb, save.ss),
+ R_SS);
+ svm_load_seg_cache(env, env->vm_hsave + offsetof(struct vmcb, save.ds),
+ R_DS);
EIP = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip));
ESP = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp));
@@ -707,10 +707,9 @@
cpu_loop_exit(env);
}
-void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1)
+void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
{
- env = nenv;
- helper_vmexit(exit_code, exit_info_1);
+ helper_vmexit(env, exit_code, exit_info_1);
}
#endif
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 2b11333..7ab2ccb 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -740,9 +740,15 @@
state_saved = 1;
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
switch (ot) {
- case 0: gen_helper_check_iob(cpu_tmp2_i32); break;
- case 1: gen_helper_check_iow(cpu_tmp2_i32); break;
- case 2: gen_helper_check_iol(cpu_tmp2_i32); break;
+ case 0:
+ gen_helper_check_iob(cpu_env, cpu_tmp2_i32);
+ break;
+ case 1:
+ gen_helper_check_iow(cpu_env, cpu_tmp2_i32);
+ break;
+ case 2:
+ gen_helper_check_iol(cpu_env, cpu_tmp2_i32);
+ break;
}
}
if(s->flags & HF_SVMI_MASK) {
@@ -754,7 +760,8 @@
svm_flags |= (1 << (4 + ot));
next_eip = s->pc - s->cs_base;
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_svm_check_io(cpu_tmp2_i32, tcg_const_i32(svm_flags),
+ gen_helper_svm_check_io(cpu_env, cpu_tmp2_i32,
+ tcg_const_i32(svm_flags),
tcg_const_i32(next_eip - cur_eip));
}
}
@@ -811,14 +818,14 @@
/* compute eflags.C to reg */
static void gen_compute_eflags_c(TCGv reg)
{
- gen_helper_cc_compute_c(cpu_tmp2_i32, cpu_cc_op);
+ gen_helper_cc_compute_c(cpu_tmp2_i32, cpu_env, cpu_cc_op);
tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
}
/* compute all eflags to cc_src */
static void gen_compute_eflags(TCGv reg)
{
- gen_helper_cc_compute_all(cpu_tmp2_i32, cpu_cc_op);
+ gen_helper_cc_compute_all(cpu_tmp2_i32, cpu_env, cpu_cc_op);
tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
}
@@ -1266,14 +1273,30 @@
static void gen_helper_fp_arith_ST0_FT0(int op)
{
switch (op) {
- case 0: gen_helper_fadd_ST0_FT0(); break;
- case 1: gen_helper_fmul_ST0_FT0(); break;
- case 2: gen_helper_fcom_ST0_FT0(); break;
- case 3: gen_helper_fcom_ST0_FT0(); break;
- case 4: gen_helper_fsub_ST0_FT0(); break;
- case 5: gen_helper_fsubr_ST0_FT0(); break;
- case 6: gen_helper_fdiv_ST0_FT0(); break;
- case 7: gen_helper_fdivr_ST0_FT0(); break;
+ case 0:
+ gen_helper_fadd_ST0_FT0(cpu_env);
+ break;
+ case 1:
+ gen_helper_fmul_ST0_FT0(cpu_env);
+ break;
+ case 2:
+ gen_helper_fcom_ST0_FT0(cpu_env);
+ break;
+ case 3:
+ gen_helper_fcom_ST0_FT0(cpu_env);
+ break;
+ case 4:
+ gen_helper_fsub_ST0_FT0(cpu_env);
+ break;
+ case 5:
+ gen_helper_fsubr_ST0_FT0(cpu_env);
+ break;
+ case 6:
+ gen_helper_fdiv_ST0_FT0(cpu_env);
+ break;
+ case 7:
+ gen_helper_fdivr_ST0_FT0(cpu_env);
+ break;
}
}
@@ -1282,12 +1305,24 @@
{
TCGv_i32 tmp = tcg_const_i32(opreg);
switch (op) {
- case 0: gen_helper_fadd_STN_ST0(tmp); break;
- case 1: gen_helper_fmul_STN_ST0(tmp); break;
- case 4: gen_helper_fsubr_STN_ST0(tmp); break;
- case 5: gen_helper_fsub_STN_ST0(tmp); break;
- case 6: gen_helper_fdivr_STN_ST0(tmp); break;
- case 7: gen_helper_fdiv_STN_ST0(tmp); break;
+ case 0:
+ gen_helper_fadd_STN_ST0(cpu_env, tmp);
+ break;
+ case 1:
+ gen_helper_fmul_STN_ST0(cpu_env, tmp);
+ break;
+ case 4:
+ gen_helper_fsubr_STN_ST0(cpu_env, tmp);
+ break;
+ case 5:
+ gen_helper_fsub_STN_ST0(cpu_env, tmp);
+ break;
+ case 6:
+ gen_helper_fdivr_STN_ST0(cpu_env, tmp);
+ break;
+ case 7:
+ gen_helper_fdiv_STN_ST0(cpu_env, tmp);
+ break;
}
}
@@ -1745,20 +1780,36 @@
if (is_right) {
switch (ot) {
- case 0: gen_helper_rcrb(cpu_T[0], cpu_T[0], cpu_T[1]); break;
- case 1: gen_helper_rcrw(cpu_T[0], cpu_T[0], cpu_T[1]); break;
- case 2: gen_helper_rcrl(cpu_T[0], cpu_T[0], cpu_T[1]); break;
+ case 0:
+ gen_helper_rcrb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
+ break;
+ case 1:
+ gen_helper_rcrw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
+ break;
+ case 2:
+ gen_helper_rcrl(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
+ break;
#ifdef TARGET_X86_64
- case 3: gen_helper_rcrq(cpu_T[0], cpu_T[0], cpu_T[1]); break;
+ case 3:
+ gen_helper_rcrq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
+ break;
#endif
}
} else {
switch (ot) {
- case 0: gen_helper_rclb(cpu_T[0], cpu_T[0], cpu_T[1]); break;
- case 1: gen_helper_rclw(cpu_T[0], cpu_T[0], cpu_T[1]); break;
- case 2: gen_helper_rcll(cpu_T[0], cpu_T[0], cpu_T[1]); break;
+ case 0:
+ gen_helper_rclb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
+ break;
+ case 1:
+ gen_helper_rclw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
+ break;
+ case 2:
+ gen_helper_rcll(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
+ break;
#ifdef TARGET_X86_64
- case 3: gen_helper_rclq(cpu_T[0], cpu_T[0], cpu_T[1]); break;
+ case 3:
+ gen_helper_rclq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
+ break;
#endif
}
}
@@ -1992,7 +2043,7 @@
if (base == 4) {
havesib = 1;
- code = ldub_code(s->pc++);
+ code = cpu_ldub_code(cpu_single_env, s->pc++);
scale = (code >> 6) & 3;
index = ((code >> 3) & 7) | REX_X(s);
base = (code & 7);
@@ -2003,7 +2054,7 @@
case 0:
if ((base & 7) == 5) {
base = -1;
- disp = (int32_t)ldl_code(s->pc);
+ disp = (int32_t)cpu_ldl_code(cpu_single_env, s->pc);
s->pc += 4;
if (CODE64(s) && !havesib) {
disp += s->pc + s->rip_offset;
@@ -2013,11 +2064,11 @@
}
break;
case 1:
- disp = (int8_t)ldub_code(s->pc++);
+ disp = (int8_t)cpu_ldub_code(cpu_single_env, s->pc++);
break;
default:
case 2:
- disp = (int32_t)ldl_code(s->pc);
+ disp = (int32_t)cpu_ldl_code(cpu_single_env, s->pc);
s->pc += 4;
break;
}
@@ -2080,7 +2131,7 @@
switch (mod) {
case 0:
if (rm == 6) {
- disp = lduw_code(s->pc);
+ disp = cpu_lduw_code(cpu_single_env, s->pc);
s->pc += 2;
gen_op_movl_A0_im(disp);
rm = 0; /* avoid SS override */
@@ -2090,11 +2141,11 @@
}
break;
case 1:
- disp = (int8_t)ldub_code(s->pc++);
+ disp = (int8_t)cpu_ldub_code(cpu_single_env, s->pc++);
break;
default:
case 2:
- disp = lduw_code(s->pc);
+ disp = cpu_lduw_code(cpu_single_env, s->pc);
s->pc += 2;
break;
}
@@ -2164,7 +2215,7 @@
base = rm;
if (base == 4) {
- code = ldub_code(s->pc++);
+ code = cpu_ldub_code(cpu_single_env, s->pc++);
base = (code & 7);
}
@@ -2260,16 +2311,16 @@
switch(ot) {
case OT_BYTE:
- ret = ldub_code(s->pc);
+ ret = cpu_ldub_code(cpu_single_env, s->pc);
s->pc++;
break;
case OT_WORD:
- ret = lduw_code(s->pc);
+ ret = cpu_lduw_code(cpu_single_env, s->pc);
s->pc += 2;
break;
default:
case OT_LONG:
- ret = ldl_code(s->pc);
+ ret = cpu_ldl_code(cpu_single_env, s->pc);
s->pc += 4;
break;
}
@@ -2392,7 +2443,7 @@
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(cur_eip);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_load_seg(tcg_const_i32(seg_reg), cpu_tmp2_i32);
+ gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32);
/* abort translation because the addseg value may change or
because ss32 may change. For R_SS, translation must always
stop as a special handling must be done to disable hardware
@@ -2421,7 +2472,7 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_svm_check_intercept_param(tcg_const_i32(type),
+ gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
tcg_const_i64(param));
}
@@ -2629,7 +2680,7 @@
gen_op_st_T0_A0(ot + s->mem_index);
if (level) {
/* XXX: must save state */
- gen_helper_enter64_level(tcg_const_i32(level),
+ gen_helper_enter64_level(cpu_env, tcg_const_i32(level),
tcg_const_i32((ot == OT_QUAD)),
cpu_T[1]);
}
@@ -2654,7 +2705,7 @@
gen_op_st_T0_A0(ot + s->mem_index);
if (level) {
/* XXX: must save state */
- gen_helper_enter_level(tcg_const_i32(level),
+ gen_helper_enter_level(cpu_env, tcg_const_i32(level),
tcg_const_i32(s->dflag),
cpu_T[1]);
}
@@ -2691,7 +2742,7 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(cur_eip);
- gen_helper_debug();
+ gen_helper_debug(cpu_env);
s->is_jmp = DISAS_TB_JUMP;
}
@@ -2702,15 +2753,15 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
- gen_helper_reset_inhibit_irq();
+ gen_helper_reset_inhibit_irq(cpu_env);
}
if (s->tb->flags & HF_RF_MASK) {
- gen_helper_reset_rf();
+ gen_helper_reset_rf(cpu_env);
}
if (s->singlestep_enabled) {
- gen_helper_debug();
+ gen_helper_debug(cpu_env);
} else if (s->tf) {
- gen_helper_single_step();
+ gen_helper_single_step(cpu_env);
} else {
tcg_gen_exit_tb(0);
}
@@ -2796,13 +2847,16 @@
tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
}
-typedef void (*SSEFunc_i_p)(TCGv_i32 val, TCGv_ptr reg);
-typedef void (*SSEFunc_l_p)(TCGv_i64 val, TCGv_ptr reg);
-typedef void (*SSEFunc_0_pi)(TCGv_ptr reg, TCGv_i32 val);
-typedef void (*SSEFunc_0_pl)(TCGv_ptr reg, TCGv_i64 val);
-typedef void (*SSEFunc_0_pp)(TCGv_ptr reg_a, TCGv_ptr reg_b);
+typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
+typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
+typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
+typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
+typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
+typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
+ TCGv_i32 val);
typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
-typedef void (*SSEFunc_0_ppt)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv val);
+typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
+ TCGv val);
#define SSE_SPECIAL ((void *)1)
#define SSE_DUMMY ((void *)2)
@@ -2811,7 +2865,7 @@
#define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
-static const SSEFunc_0_pp sse_op_table1[256][4] = {
+static const SSEFunc_0_epp sse_op_table1[256][4] = {
/* 3DNow! extensions */
[0x0e] = { SSE_DUMMY }, /* femms */
[0x0f] = { SSE_DUMMY }, /* pf... */
@@ -2852,8 +2906,8 @@
[0x5f] = SSE_FOP(max),
[0xc2] = SSE_FOP(cmpeq),
- [0xc6] = { (SSEFunc_0_pp)gen_helper_shufps,
- (SSEFunc_0_pp)gen_helper_shufpd }, /* XXX: casts */
+ [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps,
+ (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */
[0x38] = { SSE_SPECIAL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* SSSE3/SSE4 */
[0x3a] = { SSE_SPECIAL, SSE_SPECIAL }, /* SSSE3/SSE4 */
@@ -2875,10 +2929,10 @@
[0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
[0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
[0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
- [0x70] = { (SSEFunc_0_pp)gen_helper_pshufw_mmx,
- (SSEFunc_0_pp)gen_helper_pshufd_xmm,
- (SSEFunc_0_pp)gen_helper_pshufhw_xmm,
- (SSEFunc_0_pp)gen_helper_pshuflw_xmm }, /* XXX: casts */
+ [0x70] = { (SSEFunc_0_epp)gen_helper_pshufw_mmx,
+ (SSEFunc_0_epp)gen_helper_pshufd_xmm,
+ (SSEFunc_0_epp)gen_helper_pshufhw_xmm,
+ (SSEFunc_0_epp)gen_helper_pshuflw_xmm }, /* XXX: casts */
[0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
[0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
[0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
@@ -2933,8 +2987,8 @@
[0xf4] = MMX_OP2(pmuludq),
[0xf5] = MMX_OP2(pmaddwd),
[0xf6] = MMX_OP2(psadbw),
- [0xf7] = { (SSEFunc_0_pp)gen_helper_maskmov_mmx,
- (SSEFunc_0_pp)gen_helper_maskmov_xmm }, /* XXX: casts */
+ [0xf7] = { (SSEFunc_0_epp)gen_helper_maskmov_mmx,
+ (SSEFunc_0_epp)gen_helper_maskmov_xmm }, /* XXX: casts */
[0xf8] = MMX_OP2(psubb),
[0xf9] = MMX_OP2(psubw),
[0xfa] = MMX_OP2(psubl),
@@ -2944,7 +2998,7 @@
[0xfe] = MMX_OP2(paddl),
};
-static const SSEFunc_0_pp sse_op_table2[3 * 8][2] = {
+static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = {
[0 + 2] = MMX_OP2(psrlw),
[0 + 4] = MMX_OP2(psraw),
[0 + 6] = MMX_OP2(psllw),
@@ -2957,19 +3011,19 @@
[16 + 7] = { NULL, gen_helper_pslldq_xmm },
};
-static const SSEFunc_0_pi sse_op_table3ai[] = {
+static const SSEFunc_0_epi sse_op_table3ai[] = {
gen_helper_cvtsi2ss,
gen_helper_cvtsi2sd
};
#ifdef TARGET_X86_64
-static const SSEFunc_0_pl sse_op_table3aq[] = {
+static const SSEFunc_0_epl sse_op_table3aq[] = {
gen_helper_cvtsq2ss,
gen_helper_cvtsq2sd
};
#endif
-static const SSEFunc_i_p sse_op_table3bi[] = {
+static const SSEFunc_i_ep sse_op_table3bi[] = {
gen_helper_cvttss2si,
gen_helper_cvtss2si,
gen_helper_cvttsd2si,
@@ -2977,7 +3031,7 @@
};
#ifdef TARGET_X86_64
-static const SSEFunc_l_p sse_op_table3bq[] = {
+static const SSEFunc_l_ep sse_op_table3bq[] = {
gen_helper_cvttss2sq,
gen_helper_cvtss2sq,
gen_helper_cvttsd2sq,
@@ -2985,7 +3039,7 @@
};
#endif
-static const SSEFunc_0_pp sse_op_table4[8][4] = {
+static const SSEFunc_0_epp sse_op_table4[8][4] = {
SSE_FOP(cmpeq),
SSE_FOP(cmplt),
SSE_FOP(cmple),
@@ -2996,7 +3050,7 @@
SSE_FOP(cmpord),
};
-static const SSEFunc_0_pp sse_op_table5[256] = {
+static const SSEFunc_0_epp sse_op_table5[256] = {
[0x0c] = gen_helper_pi2fw,
[0x0d] = gen_helper_pi2fd,
[0x1c] = gen_helper_pf2iw,
@@ -3023,13 +3077,13 @@
[0xbf] = gen_helper_pavgb_mmx /* pavgusb */
};
-struct SSEOpHelper_pp {
- SSEFunc_0_pp op[2];
+struct SSEOpHelper_epp {
+ SSEFunc_0_epp op[2];
uint32_t ext_mask;
};
-struct SSEOpHelper_ppi {
- SSEFunc_0_ppi op[2];
+struct SSEOpHelper_eppi {
+ SSEFunc_0_eppi op[2];
uint32_t ext_mask;
};
@@ -3038,7 +3092,7 @@
#define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
#define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
-static const struct SSEOpHelper_pp sse_op_table6[256] = {
+static const struct SSEOpHelper_epp sse_op_table6[256] = {
[0x00] = SSSE3_OP(pshufb),
[0x01] = SSSE3_OP(phaddw),
[0x02] = SSSE3_OP(phaddd),
@@ -3087,7 +3141,7 @@
[0x41] = SSE41_OP(phminposuw),
};
-static const struct SSEOpHelper_ppi sse_op_table7[256] = {
+static const struct SSEOpHelper_eppi sse_op_table7[256] = {
[0x08] = SSE41_OP(roundps),
[0x09] = SSE41_OP(roundpd),
[0x0a] = SSE41_OP(roundss),
@@ -3116,9 +3170,10 @@
{
int b1, op1_offset, op2_offset, is_xmm, val, ot;
int modrm, mod, rm, reg, reg_addr, offset_addr;
- SSEFunc_0_pp sse_fn_pp;
+ SSEFunc_0_epp sse_fn_epp;
+ SSEFunc_0_eppi sse_fn_eppi;
SSEFunc_0_ppi sse_fn_ppi;
- SSEFunc_0_ppt sse_fn_ppt;
+ SSEFunc_0_eppt sse_fn_eppt;
b &= 0xff;
if (s->prefix & PREFIX_DATA)
@@ -3129,8 +3184,8 @@
b1 = 3;
else
b1 = 0;
- sse_fn_pp = sse_op_table1[b][b1];
- if (!sse_fn_pp) {
+ sse_fn_epp = sse_op_table1[b][b1];
+ if (!sse_fn_epp) {
goto illegal_op;
}
if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
@@ -3160,26 +3215,26 @@
if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
goto illegal_op;
/* femms */
- gen_helper_emms();
+ gen_helper_emms(cpu_env);
return;
}
if (b == 0x77) {
/* emms */
- gen_helper_emms();
+ gen_helper_emms(cpu_env);
return;
}
/* prepare MMX state (XXX: optimize by storing fptt and fptags in
the static cpu state) */
if (!is_xmm) {
- gen_helper_enter_mmx();
+ gen_helper_enter_mmx(cpu_env);
}
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7);
if (is_xmm)
reg |= rex_r;
mod = (modrm >> 6) & 3;
- if (sse_fn_pp == SSE_SPECIAL) {
+ if (sse_fn_epp == SSE_SPECIAL) {
b |= (b1 << 8);
switch(b) {
case 0x0e7: /* movntq */
@@ -3378,16 +3433,18 @@
if (b1 == 1 && reg != 0)
goto illegal_op;
- field_length = ldub_code(s->pc++) & 0x3F;
- bit_index = ldub_code(s->pc++) & 0x3F;
+ field_length = cpu_ldub_code(cpu_single_env, s->pc++) & 0x3F;
+ bit_index = cpu_ldub_code(cpu_single_env, s->pc++) & 0x3F;
tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
offsetof(CPUX86State,xmm_regs[reg]));
if (b1 == 1)
- gen_helper_extrq_i(cpu_ptr0, tcg_const_i32(bit_index),
- tcg_const_i32(field_length));
+ gen_helper_extrq_i(cpu_env, cpu_ptr0,
+ tcg_const_i32(bit_index),
+ tcg_const_i32(field_length));
else
- gen_helper_insertq_i(cpu_ptr0, tcg_const_i32(bit_index),
- tcg_const_i32(field_length));
+ gen_helper_insertq_i(cpu_env, cpu_ptr0,
+ tcg_const_i32(bit_index),
+ tcg_const_i32(field_length));
}
break;
case 0x7e: /* movd ea, mm */
@@ -3502,7 +3559,7 @@
if (b1 >= 2) {
goto illegal_op;
}
- val = ldub_code(s->pc++);
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
if (is_xmm) {
gen_op_movl_T0_im(val);
tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
@@ -3516,8 +3573,9 @@
tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
op1_offset = offsetof(CPUX86State,mmx_t0);
}
- sse_fn_pp = sse_op_table2[((b - 1) & 3) * 8 + (((modrm >> 3)) & 7)][b1];
- if (!sse_fn_pp) {
+ sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
+ (((modrm >> 3)) & 7)][b1];
+ if (!sse_fn_epp) {
goto illegal_op;
}
if (is_xmm) {
@@ -3529,13 +3587,13 @@
}
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
- sse_fn_pp(cpu_ptr0, cpu_ptr1);
+ sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
break;
case 0x050: /* movmskps */
rm = (modrm & 7) | REX_B(s);
tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
offsetof(CPUX86State,xmm_regs[rm]));
- gen_helper_movmskps(cpu_tmp2_i32, cpu_ptr0);
+ gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_mov_reg_T0(OT_LONG, reg);
break;
@@ -3543,13 +3601,13 @@
rm = (modrm & 7) | REX_B(s);
tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
offsetof(CPUX86State,xmm_regs[rm]));
- gen_helper_movmskpd(cpu_tmp2_i32, cpu_ptr0);
+ gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_mov_reg_T0(OT_LONG, reg);
break;
case 0x02a: /* cvtpi2ps */
case 0x12a: /* cvtpi2pd */
- gen_helper_enter_mmx();
+ gen_helper_enter_mmx(cpu_env);
if (mod != 3) {
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
op2_offset = offsetof(CPUX86State,mmx_t0);
@@ -3563,11 +3621,11 @@
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
switch(b >> 8) {
case 0x0:
- gen_helper_cvtpi2ps(cpu_ptr0, cpu_ptr1);
+ gen_helper_cvtpi2ps(cpu_env, cpu_ptr0, cpu_ptr1);
break;
default:
case 0x1:
- gen_helper_cvtpi2pd(cpu_ptr0, cpu_ptr1);
+ gen_helper_cvtpi2pd(cpu_env, cpu_ptr0, cpu_ptr1);
break;
}
break;
@@ -3578,13 +3636,13 @@
op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
if (ot == OT_LONG) {
- SSEFunc_0_pi sse_fn_pi = sse_op_table3ai[(b >> 8) & 1];
+ SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1];
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- sse_fn_pi(cpu_ptr0, cpu_tmp2_i32);
+ sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32);
} else {
#ifdef TARGET_X86_64
- SSEFunc_0_pl sse_fn_pl = sse_op_table3aq[(b >> 8) & 1];
- sse_fn_pl(cpu_ptr0, cpu_T[0]);
+ SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1];
+ sse_fn_epl(cpu_env, cpu_ptr0, cpu_T[0]);
#else
goto illegal_op;
#endif
@@ -3594,7 +3652,7 @@
case 0x12c: /* cvttpd2pi */
case 0x02d: /* cvtps2pi */
case 0x12d: /* cvtpd2pi */
- gen_helper_enter_mmx();
+ gen_helper_enter_mmx(cpu_env);
if (mod != 3) {
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
op2_offset = offsetof(CPUX86State,xmm_t0);
@@ -3608,16 +3666,16 @@
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
switch(b) {
case 0x02c:
- gen_helper_cvttps2pi(cpu_ptr0, cpu_ptr1);
+ gen_helper_cvttps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
break;
case 0x12c:
- gen_helper_cvttpd2pi(cpu_ptr0, cpu_ptr1);
+ gen_helper_cvttpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
break;
case 0x02d:
- gen_helper_cvtps2pi(cpu_ptr0, cpu_ptr1);
+ gen_helper_cvtps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
break;
case 0x12d:
- gen_helper_cvtpd2pi(cpu_ptr0, cpu_ptr1);
+ gen_helper_cvtpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
break;
}
break;
@@ -3641,15 +3699,15 @@
}
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
if (ot == OT_LONG) {
- SSEFunc_i_p sse_fn_i_p =
+ SSEFunc_i_ep sse_fn_i_ep =
sse_op_table3bi[((b >> 7) & 2) | (b & 1)];
- sse_fn_i_p(cpu_tmp2_i32, cpu_ptr0);
+ sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
} else {
#ifdef TARGET_X86_64
- SSEFunc_l_p sse_fn_l_p =
+ SSEFunc_l_ep sse_fn_l_ep =
sse_op_table3bq[((b >> 7) & 2) | (b & 1)];
- sse_fn_l_p(cpu_T[0], cpu_ptr0);
+ sse_fn_l_ep(cpu_T[0], cpu_env, cpu_ptr0);
#else
goto illegal_op;
#endif
@@ -3660,7 +3718,7 @@
case 0x1c4:
s->rip_offset = 1;
gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
- val = ldub_code(s->pc++);
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
if (b1) {
val &= 7;
tcg_gen_st16_tl(cpu_T[0], cpu_env,
@@ -3676,7 +3734,7 @@
if (mod != 3)
goto illegal_op;
ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
- val = ldub_code(s->pc++);
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
if (b1) {
val &= 7;
rm = (modrm & 7) | REX_B(s);
@@ -3703,14 +3761,14 @@
}
break;
case 0x2d6: /* movq2dq */
- gen_helper_enter_mmx();
+ gen_helper_enter_mmx(cpu_env);
rm = (modrm & 7);
gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
offsetof(CPUX86State,fpregs[rm].mmx));
gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
break;
case 0x3d6: /* movdq2q */
- gen_helper_enter_mmx();
+ gen_helper_enter_mmx(cpu_env);
rm = (modrm & 7) | REX_B(s);
gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
@@ -3722,11 +3780,11 @@
if (b1) {
rm = (modrm & 7) | REX_B(s);
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
- gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_ptr0);
+ gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_env, cpu_ptr0);
} else {
rm = (modrm & 7);
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
- gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_ptr0);
+ gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0);
}
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
reg = ((modrm >> 3) & 7) | rex_r;
@@ -3737,7 +3795,7 @@
goto crc32;
case 0x038:
b = modrm;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
rm = modrm & 7;
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
@@ -3745,8 +3803,8 @@
goto illegal_op;
}
- sse_fn_pp = sse_op_table6[b].op[b1];
- if (!sse_fn_pp) {
+ sse_fn_epp = sse_op_table6[b].op[b1];
+ if (!sse_fn_epp) {
goto illegal_op;
}
if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
@@ -3797,13 +3855,13 @@
gen_ldq_env_A0(s->mem_index, op2_offset);
}
}
- if (sse_fn_pp == SSE_SPECIAL) {
+ if (sse_fn_epp == SSE_SPECIAL) {
goto illegal_op;
}
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
- sse_fn_pp(cpu_ptr0, cpu_ptr1);
+ sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
if (b == 0x17)
s->cc_op = CC_OP_EFLAGS;
@@ -3811,7 +3869,7 @@
case 0x338: /* crc32 */
crc32:
b = modrm;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
if (b != 0xf0 && b != 0xf1)
@@ -3841,7 +3899,7 @@
case 0x03a:
case 0x13a:
b = modrm;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
rm = modrm & 7;
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
@@ -3849,20 +3907,20 @@
goto illegal_op;
}
- sse_fn_ppi = sse_op_table7[b].op[b1];
- if (!sse_fn_ppi) {
+ sse_fn_eppi = sse_op_table7[b].op[b1];
+ if (!sse_fn_eppi) {
goto illegal_op;
}
if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
goto illegal_op;
- if (sse_fn_ppi == SSE_SPECIAL) {
+ if (sse_fn_eppi == SSE_SPECIAL) {
ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
rm = (modrm & 7) | REX_B(s);
if (mod != 3)
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
reg = ((modrm >> 3) & 7) | rex_r;
- val = ldub_code(s->pc++);
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
switch (b) {
case 0x14: /* pextrb */
tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
@@ -4005,7 +4063,7 @@
gen_ldq_env_A0(s->mem_index, op2_offset);
}
}
- val = ldub_code(s->pc++);
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
s->cc_op = CC_OP_EFLAGS;
@@ -4017,7 +4075,7 @@
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
- sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
+ sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
break;
default:
goto illegal_op;
@@ -4071,34 +4129,34 @@
case 0x0f: /* 3DNow! data insns */
if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
goto illegal_op;
- val = ldub_code(s->pc++);
- sse_fn_pp = sse_op_table5[val];
- if (!sse_fn_pp) {
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
+ sse_fn_epp = sse_op_table5[val];
+ if (!sse_fn_epp) {
goto illegal_op;
}
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
- sse_fn_pp(cpu_ptr0, cpu_ptr1);
+ sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
break;
case 0x70: /* pshufx insn */
case 0xc6: /* pshufx insn */
- val = ldub_code(s->pc++);
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
/* XXX: introduce a new table? */
- sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_pp;
+ sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp;
sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
break;
case 0xc2:
/* compare insns */
- val = ldub_code(s->pc++);
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
if (val >= 8)
goto illegal_op;
- sse_fn_pp = sse_op_table4[val][b1];
+ sse_fn_epp = sse_op_table4[val][b1];
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
- sse_fn_pp(cpu_ptr0, cpu_ptr1);
+ sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
break;
case 0xf7:
/* maskmov : we must prepare A0 */
@@ -4119,13 +4177,13 @@
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
/* XXX: introduce a new table? */
- sse_fn_ppt = (SSEFunc_0_ppt)sse_fn_pp;
- sse_fn_ppt(cpu_ptr0, cpu_ptr1, cpu_A0);
+ sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;
+ sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0);
break;
default:
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
- sse_fn_pp(cpu_ptr0, cpu_ptr1);
+ sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
break;
}
if (b == 0x2e || b == 0x2f) {
@@ -4160,7 +4218,7 @@
#endif
s->rip_offset = 0; /* for relative ip address */
next_byte:
- b = ldub_code(s->pc);
+ b = cpu_ldub_code(cpu_single_env, s->pc);
s->pc++;
/* check prefixes */
#ifdef TARGET_X86_64
@@ -4275,7 +4333,7 @@
case 0x0f:
/**************************/
/* extended op code */
- b = ldub_code(s->pc++) | 0x100;
+ b = cpu_ldub_code(cpu_single_env, s->pc++) | 0x100;
goto reswitch;
/**************************/
@@ -4300,7 +4358,7 @@
switch(f) {
case 0: /* OP Ev, Gv */
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s);
@@ -4322,7 +4380,7 @@
gen_op(s, op, ot, opreg);
break;
case 1: /* OP Gv, Ev */
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
reg = ((modrm >> 3) & 7) | rex_r;
rm = (modrm & 7) | REX_B(s);
@@ -4359,7 +4417,7 @@
else
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s);
op = (modrm >> 3) & 7;
@@ -4408,7 +4466,7 @@
else
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s);
op = (modrm >> 3) & 7;
@@ -4506,7 +4564,7 @@
break;
#ifdef TARGET_X86_64
case OT_QUAD:
- gen_helper_mulq_EAX_T0(cpu_T[0]);
+ gen_helper_mulq_EAX_T0(cpu_env, cpu_T[0]);
s->cc_op = CC_OP_MULQ;
break;
#endif
@@ -4576,7 +4634,7 @@
break;
#ifdef TARGET_X86_64
case OT_QUAD:
- gen_helper_imulq_EAX_T0(cpu_T[0]);
+ gen_helper_imulq_EAX_T0(cpu_env, cpu_T[0]);
s->cc_op = CC_OP_MULQ;
break;
#endif
@@ -4586,21 +4644,21 @@
switch(ot) {
case OT_BYTE:
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_divb_AL(cpu_T[0]);
+ gen_helper_divb_AL(cpu_env, cpu_T[0]);
break;
case OT_WORD:
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_divw_AX(cpu_T[0]);
+ gen_helper_divw_AX(cpu_env, cpu_T[0]);
break;
default:
case OT_LONG:
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_divl_EAX(cpu_T[0]);
+ gen_helper_divl_EAX(cpu_env, cpu_T[0]);
break;
#ifdef TARGET_X86_64
case OT_QUAD:
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_divq_EAX(cpu_T[0]);
+ gen_helper_divq_EAX(cpu_env, cpu_T[0]);
break;
#endif
}
@@ -4609,21 +4667,21 @@
switch(ot) {
case OT_BYTE:
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_idivb_AL(cpu_T[0]);
+ gen_helper_idivb_AL(cpu_env, cpu_T[0]);
break;
case OT_WORD:
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_idivw_AX(cpu_T[0]);
+ gen_helper_idivw_AX(cpu_env, cpu_T[0]);
break;
default:
case OT_LONG:
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_idivl_EAX(cpu_T[0]);
+ gen_helper_idivl_EAX(cpu_env, cpu_T[0]);
break;
#ifdef TARGET_X86_64
case OT_QUAD:
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_idivq_EAX(cpu_T[0]);
+ gen_helper_idivq_EAX(cpu_env, cpu_T[0]);
break;
#endif
}
@@ -4640,7 +4698,7 @@
else
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s);
op = (modrm >> 3) & 7;
@@ -4701,13 +4759,13 @@
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_lcall_protected(cpu_tmp2_i32, cpu_T[1],
- tcg_const_i32(dflag),
+ gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T[1],
+ tcg_const_i32(dflag),
tcg_const_i32(s->pc - pc_start));
} else {
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_lcall_real(cpu_tmp2_i32, cpu_T[1],
- tcg_const_i32(dflag),
+ gen_helper_lcall_real(cpu_env, cpu_tmp2_i32, cpu_T[1],
+ tcg_const_i32(dflag),
tcg_const_i32(s->pc - s->cs_base));
}
gen_eob(s);
@@ -4728,7 +4786,7 @@
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_ljmp_protected(cpu_tmp2_i32, cpu_T[1],
+ gen_helper_ljmp_protected(cpu_env, cpu_tmp2_i32, cpu_T[1],
tcg_const_i32(s->pc - pc_start));
} else {
gen_op_movl_seg_T0_vm(R_CS);
@@ -4752,7 +4810,7 @@
else
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
@@ -4817,7 +4875,7 @@
case 0x69: /* imul Gv, Ev, I */
case 0x6b:
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
if (b == 0x69)
s->rip_offset = insn_const_size(ot);
@@ -4836,7 +4894,7 @@
#ifdef TARGET_X86_64
if (ot == OT_QUAD) {
- gen_helper_imulq_T0_T1(cpu_T[0], cpu_T[0], cpu_T[1]);
+ gen_helper_imulq_T0_T1(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
} else
#endif
if (ot == OT_LONG) {
@@ -4881,7 +4939,7 @@
ot = OT_BYTE;
else
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
if (mod == 3) {
@@ -4912,7 +4970,7 @@
ot = OT_BYTE;
else
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
t0 = tcg_temp_local_new();
@@ -4960,7 +5018,7 @@
}
break;
case 0x1c7: /* cmpxchg8b */
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
if ((mod == 3) || ((modrm & 0x38) != 0x8))
goto illegal_op;
@@ -4972,7 +5030,7 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
- gen_helper_cmpxchg16b(cpu_A0);
+ gen_helper_cmpxchg16b(cpu_env, cpu_A0);
} else
#endif
{
@@ -4982,7 +5040,7 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
- gen_helper_cmpxchg8b(cpu_A0);
+ gen_helper_cmpxchg8b(cpu_env, cpu_A0);
}
s->cc_op = CC_OP_EFLAGS;
break;
@@ -5034,7 +5092,7 @@
} else {
ot = dflag + OT_WORD;
}
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
gen_pop_T0(s);
if (mod == 3) {
@@ -5053,9 +5111,9 @@
case 0xc8: /* enter */
{
int level;
- val = lduw_code(s->pc);
+ val = cpu_lduw_code(cpu_single_env, s->pc);
s->pc += 2;
- level = ldub_code(s->pc++);
+ level = cpu_ldub_code(cpu_single_env, s->pc++);
gen_enter(s, val, level);
}
break;
@@ -5108,7 +5166,7 @@
/* If several instructions disable interrupts, only the
_first_ does it */
if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
- gen_helper_set_inhibit_irq();
+ gen_helper_set_inhibit_irq(cpu_env);
s->tf = 0;
}
if (s->is_jmp) {
@@ -5135,7 +5193,7 @@
ot = OT_BYTE;
else
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
/* generate a generic store */
@@ -5147,7 +5205,7 @@
ot = OT_BYTE;
else
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
if (mod != 3) {
s->rip_offset = insn_const_size(ot);
@@ -5166,14 +5224,14 @@
ot = OT_BYTE;
else
ot = OT_WORD + dflag;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
gen_op_mov_reg_T0(ot, reg);
break;
case 0x8e: /* mov seg, Gv */
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = (modrm >> 3) & 7;
if (reg >= 6 || reg == R_CS)
goto illegal_op;
@@ -5184,7 +5242,7 @@
/* If several instructions disable interrupts, only the
_first_ does it */
if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
- gen_helper_set_inhibit_irq();
+ gen_helper_set_inhibit_irq(cpu_env);
s->tf = 0;
}
if (s->is_jmp) {
@@ -5193,7 +5251,7 @@
}
break;
case 0x8c: /* mov Gv, seg */
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = (modrm >> 3) & 7;
mod = (modrm >> 6) & 3;
if (reg >= 6)
@@ -5216,7 +5274,7 @@
d_ot = dflag + OT_WORD;
/* ot is the size of source */
ot = (b & 1) + OT_BYTE;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s);
@@ -5253,7 +5311,7 @@
case 0x8d: /* lea */
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
if (mod == 3)
goto illegal_op;
@@ -5280,7 +5338,7 @@
ot = dflag + OT_WORD;
#ifdef TARGET_X86_64
if (s->aflag == 2) {
- offset_addr = ldq_code(s->pc);
+ offset_addr = cpu_ldq_code(cpu_single_env, s->pc);
s->pc += 8;
gen_op_movq_A0_im(offset_addr);
} else
@@ -5336,7 +5394,7 @@
if (dflag == 2) {
uint64_t tmp;
/* 64 bit case */
- tmp = ldq_code(s->pc);
+ tmp = cpu_ldq_code(cpu_single_env, s->pc);
s->pc += 8;
reg = (b & 7) | REX_B(s);
gen_movtl_T0_im(tmp);
@@ -5364,7 +5422,7 @@
ot = OT_BYTE;
else
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
if (mod == 3) {
@@ -5407,7 +5465,7 @@
op = R_GS;
do_lxx:
ot = dflag ? OT_LONG : OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
if (mod == 3)
@@ -5439,7 +5497,7 @@
else
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
op = (modrm >> 3) & 7;
@@ -5458,7 +5516,7 @@
gen_shift(s, op, ot, opreg, OR_ECX);
} else {
if (shift == 2) {
- shift = ldub_code(s->pc++);
+ shift = cpu_ldub_code(cpu_single_env, s->pc++);
}
gen_shifti(s, op, ot, opreg, shift);
}
@@ -5492,7 +5550,7 @@
shift = 0;
do_shiftd:
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s);
reg = ((modrm >> 3) & 7) | rex_r;
@@ -5505,7 +5563,7 @@
gen_op_mov_TN_reg(ot, 1, reg);
if (shift) {
- val = ldub_code(s->pc++);
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
tcg_gen_movi_tl(cpu_T3, val);
} else {
tcg_gen_mov_tl(cpu_T3, cpu_regs[R_ECX]);
@@ -5522,7 +5580,7 @@
gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
break;
}
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
rm = modrm & 7;
op = ((b & 7) << 3) | ((modrm >> 3) & 7);
@@ -5542,30 +5600,30 @@
case 0:
gen_op_ld_T0_A0(OT_LONG + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_flds_FT0(cpu_tmp2_i32);
+ gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32);
break;
case 1:
gen_op_ld_T0_A0(OT_LONG + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_fildl_FT0(cpu_tmp2_i32);
+ gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
break;
case 2:
tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
(s->mem_index >> 2) - 1);
- gen_helper_fldl_FT0(cpu_tmp1_i64);
+ gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64);
break;
case 3:
default:
gen_op_lds_T0_A0(OT_WORD + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_fildl_FT0(cpu_tmp2_i32);
+ gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
break;
}
gen_helper_fp_arith_ST0_FT0(op1);
if (op1 == 3) {
/* fcomp needs pop */
- gen_helper_fpop();
+ gen_helper_fpop(cpu_env);
}
}
break;
@@ -5581,23 +5639,23 @@
case 0:
gen_op_ld_T0_A0(OT_LONG + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_flds_ST0(cpu_tmp2_i32);
+ gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32);
break;
case 1:
gen_op_ld_T0_A0(OT_LONG + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_fildl_ST0(cpu_tmp2_i32);
+ gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
break;
case 2:
tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
(s->mem_index >> 2) - 1);
- gen_helper_fldl_ST0(cpu_tmp1_i64);
+ gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64);
break;
case 3:
default:
gen_op_lds_T0_A0(OT_WORD + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_fildl_ST0(cpu_tmp2_i32);
+ gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
break;
}
break;
@@ -5605,50 +5663,50 @@
/* XXX: the corresponding CPUID bit must be tested ! */
switch(op >> 4) {
case 1:
- gen_helper_fisttl_ST0(cpu_tmp2_i32);
+ gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(OT_LONG + s->mem_index);
break;
case 2:
- gen_helper_fisttll_ST0(cpu_tmp1_i64);
+ gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env);
tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
(s->mem_index >> 2) - 1);
break;
case 3:
default:
- gen_helper_fistt_ST0(cpu_tmp2_i32);
+ gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(OT_WORD + s->mem_index);
break;
}
- gen_helper_fpop();
+ gen_helper_fpop(cpu_env);
break;
default:
switch(op >> 4) {
case 0:
- gen_helper_fsts_ST0(cpu_tmp2_i32);
+ gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(OT_LONG + s->mem_index);
break;
case 1:
- gen_helper_fistl_ST0(cpu_tmp2_i32);
+ gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(OT_LONG + s->mem_index);
break;
case 2:
- gen_helper_fstl_ST0(cpu_tmp1_i64);
+ gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env);
tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
(s->mem_index >> 2) - 1);
break;
case 3:
default:
- gen_helper_fist_ST0(cpu_tmp2_i32);
+ gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(OT_WORD + s->mem_index);
break;
}
if ((op & 7) == 3)
- gen_helper_fpop();
+ gen_helper_fpop(cpu_env);
break;
}
break;
@@ -5656,22 +5714,21 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_fldenv(
- cpu_A0, tcg_const_i32(s->dflag));
+ gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
break;
case 0x0d: /* fldcw mem */
gen_op_ld_T0_A0(OT_WORD + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_fldcw(cpu_tmp2_i32);
+ gen_helper_fldcw(cpu_env, cpu_tmp2_i32);
break;
case 0x0e: /* fnstenv mem */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_fstenv(cpu_A0, tcg_const_i32(s->dflag));
+ gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
break;
case 0x0f: /* fnstcw mem */
- gen_helper_fnstcw(cpu_tmp2_i32);
+ gen_helper_fnstcw(cpu_tmp2_i32, cpu_env);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(OT_WORD + s->mem_index);
break;
@@ -5679,29 +5736,29 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_fldt_ST0(cpu_A0);
+ gen_helper_fldt_ST0(cpu_env, cpu_A0);
break;
case 0x1f: /* fstpt mem */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_fstt_ST0(cpu_A0);
- gen_helper_fpop();
+ gen_helper_fstt_ST0(cpu_env, cpu_A0);
+ gen_helper_fpop(cpu_env);
break;
case 0x2c: /* frstor mem */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_frstor(cpu_A0, tcg_const_i32(s->dflag));
+ gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
break;
case 0x2e: /* fnsave mem */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_fsave(cpu_A0, tcg_const_i32(s->dflag));
+ gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(s->dflag));
break;
case 0x2f: /* fnstsw mem */
- gen_helper_fnstsw(cpu_tmp2_i32);
+ gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_st_T0_A0(OT_WORD + s->mem_index);
break;
@@ -5709,25 +5766,25 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_fbld_ST0(cpu_A0);
+ gen_helper_fbld_ST0(cpu_env, cpu_A0);
break;
case 0x3e: /* fbstp */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_fbst_ST0(cpu_A0);
- gen_helper_fpop();
+ gen_helper_fbst_ST0(cpu_env, cpu_A0);
+ gen_helper_fpop(cpu_env);
break;
case 0x3d: /* fildll */
tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
(s->mem_index >> 2) - 1);
- gen_helper_fildll_ST0(cpu_tmp1_i64);
+ gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64);
break;
case 0x3f: /* fistpll */
- gen_helper_fistll_ST0(cpu_tmp1_i64);
+ gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env);
tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
(s->mem_index >> 2) - 1);
- gen_helper_fpop();
+ gen_helper_fpop(cpu_env);
break;
default:
goto illegal_op;
@@ -5738,13 +5795,14 @@
switch(op) {
case 0x08: /* fld sti */
- gen_helper_fpush();
- gen_helper_fmov_ST0_STN(tcg_const_i32((opreg + 1) & 7));
+ gen_helper_fpush(cpu_env);
+ gen_helper_fmov_ST0_STN(cpu_env,
+ tcg_const_i32((opreg + 1) & 7));
break;
case 0x09: /* fxchg sti */
case 0x29: /* fxchg4 sti, undocumented op */
case 0x39: /* fxchg7 sti, undocumented op */
- gen_helper_fxchg_ST0_STN(tcg_const_i32(opreg));
+ gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
break;
case 0x0a: /* grp d9/2 */
switch(rm) {
@@ -5753,7 +5811,7 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_fwait();
+ gen_helper_fwait(cpu_env);
break;
default:
goto illegal_op;
@@ -5762,17 +5820,17 @@
case 0x0c: /* grp d9/4 */
switch(rm) {
case 0: /* fchs */
- gen_helper_fchs_ST0();
+ gen_helper_fchs_ST0(cpu_env);
break;
case 1: /* fabs */
- gen_helper_fabs_ST0();
+ gen_helper_fabs_ST0(cpu_env);
break;
case 4: /* ftst */
- gen_helper_fldz_FT0();
- gen_helper_fcom_ST0_FT0();
+ gen_helper_fldz_FT0(cpu_env);
+ gen_helper_fcom_ST0_FT0(cpu_env);
break;
case 5: /* fxam */
- gen_helper_fxam_ST0();
+ gen_helper_fxam_ST0(cpu_env);
break;
default:
goto illegal_op;
@@ -5782,32 +5840,32 @@
{
switch(rm) {
case 0:
- gen_helper_fpush();
- gen_helper_fld1_ST0();
+ gen_helper_fpush(cpu_env);
+ gen_helper_fld1_ST0(cpu_env);
break;
case 1:
- gen_helper_fpush();
- gen_helper_fldl2t_ST0();
+ gen_helper_fpush(cpu_env);
+ gen_helper_fldl2t_ST0(cpu_env);
break;
case 2:
- gen_helper_fpush();
- gen_helper_fldl2e_ST0();
+ gen_helper_fpush(cpu_env);
+ gen_helper_fldl2e_ST0(cpu_env);
break;
case 3:
- gen_helper_fpush();
- gen_helper_fldpi_ST0();
+ gen_helper_fpush(cpu_env);
+ gen_helper_fldpi_ST0(cpu_env);
break;
case 4:
- gen_helper_fpush();
- gen_helper_fldlg2_ST0();
+ gen_helper_fpush(cpu_env);
+ gen_helper_fldlg2_ST0(cpu_env);
break;
case 5:
- gen_helper_fpush();
- gen_helper_fldln2_ST0();
+ gen_helper_fpush(cpu_env);
+ gen_helper_fldln2_ST0(cpu_env);
break;
case 6:
- gen_helper_fpush();
- gen_helper_fldz_ST0();
+ gen_helper_fpush(cpu_env);
+ gen_helper_fldz_ST0(cpu_env);
break;
default:
goto illegal_op;
@@ -5817,58 +5875,58 @@
case 0x0e: /* grp d9/6 */
switch(rm) {
case 0: /* f2xm1 */
- gen_helper_f2xm1();
+ gen_helper_f2xm1(cpu_env);
break;
case 1: /* fyl2x */
- gen_helper_fyl2x();
+ gen_helper_fyl2x(cpu_env);
break;
case 2: /* fptan */
- gen_helper_fptan();
+ gen_helper_fptan(cpu_env);
break;
case 3: /* fpatan */
- gen_helper_fpatan();
+ gen_helper_fpatan(cpu_env);
break;
case 4: /* fxtract */
- gen_helper_fxtract();
+ gen_helper_fxtract(cpu_env);
break;
case 5: /* fprem1 */
- gen_helper_fprem1();
+ gen_helper_fprem1(cpu_env);
break;
case 6: /* fdecstp */
- gen_helper_fdecstp();
+ gen_helper_fdecstp(cpu_env);
break;
default:
case 7: /* fincstp */
- gen_helper_fincstp();
+ gen_helper_fincstp(cpu_env);
break;
}
break;
case 0x0f: /* grp d9/7 */
switch(rm) {
case 0: /* fprem */
- gen_helper_fprem();
+ gen_helper_fprem(cpu_env);
break;
case 1: /* fyl2xp1 */
- gen_helper_fyl2xp1();
+ gen_helper_fyl2xp1(cpu_env);
break;
case 2: /* fsqrt */
- gen_helper_fsqrt();
+ gen_helper_fsqrt(cpu_env);
break;
case 3: /* fsincos */
- gen_helper_fsincos();
+ gen_helper_fsincos(cpu_env);
break;
case 5: /* fscale */
- gen_helper_fscale();
+ gen_helper_fscale(cpu_env);
break;
case 4: /* frndint */
- gen_helper_frndint();
+ gen_helper_frndint(cpu_env);
break;
case 6: /* fsin */
- gen_helper_fsin();
+ gen_helper_fsin(cpu_env);
break;
default:
case 7: /* fcos */
- gen_helper_fcos();
+ gen_helper_fcos(cpu_env);
break;
}
break;
@@ -5882,32 +5940,32 @@
if (op >= 0x20) {
gen_helper_fp_arith_STN_ST0(op1, opreg);
if (op >= 0x30)
- gen_helper_fpop();
+ gen_helper_fpop(cpu_env);
} else {
- gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
gen_helper_fp_arith_ST0_FT0(op1);
}
}
break;
case 0x02: /* fcom */
case 0x22: /* fcom2, undocumented op */
- gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
- gen_helper_fcom_ST0_FT0();
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fcom_ST0_FT0(cpu_env);
break;
case 0x03: /* fcomp */
case 0x23: /* fcomp3, undocumented op */
case 0x32: /* fcomp5, undocumented op */
- gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
- gen_helper_fcom_ST0_FT0();
- gen_helper_fpop();
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fcom_ST0_FT0(cpu_env);
+ gen_helper_fpop(cpu_env);
break;
case 0x15: /* da/5 */
switch(rm) {
case 1: /* fucompp */
- gen_helper_fmov_FT0_STN(tcg_const_i32(1));
- gen_helper_fucom_ST0_FT0();
- gen_helper_fpop();
- gen_helper_fpop();
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
+ gen_helper_fucom_ST0_FT0(cpu_env);
+ gen_helper_fpop(cpu_env);
+ gen_helper_fpop(cpu_env);
break;
default:
goto illegal_op;
@@ -5920,10 +5978,10 @@
case 1: /* fdisi (287 only, just do nop here) */
break;
case 2: /* fclex */
- gen_helper_fclex();
+ gen_helper_fclex(cpu_env);
break;
case 3: /* fninit */
- gen_helper_fninit();
+ gen_helper_fninit(cpu_env);
break;
case 4: /* fsetpm (287 only, just do nop here) */
break;
@@ -5934,59 +5992,59 @@
case 0x1d: /* fucomi */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
- gen_helper_fucomi_ST0_FT0();
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fucomi_ST0_FT0(cpu_env);
s->cc_op = CC_OP_EFLAGS;
break;
case 0x1e: /* fcomi */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
- gen_helper_fcomi_ST0_FT0();
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fcomi_ST0_FT0(cpu_env);
s->cc_op = CC_OP_EFLAGS;
break;
case 0x28: /* ffree sti */
- gen_helper_ffree_STN(tcg_const_i32(opreg));
+ gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
break;
case 0x2a: /* fst sti */
- gen_helper_fmov_STN_ST0(tcg_const_i32(opreg));
+ gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
break;
case 0x2b: /* fstp sti */
case 0x0b: /* fstp1 sti, undocumented op */
case 0x3a: /* fstp8 sti, undocumented op */
case 0x3b: /* fstp9 sti, undocumented op */
- gen_helper_fmov_STN_ST0(tcg_const_i32(opreg));
- gen_helper_fpop();
+ gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fpop(cpu_env);
break;
case 0x2c: /* fucom st(i) */
- gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
- gen_helper_fucom_ST0_FT0();
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fucom_ST0_FT0(cpu_env);
break;
case 0x2d: /* fucomp st(i) */
- gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
- gen_helper_fucom_ST0_FT0();
- gen_helper_fpop();
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fucom_ST0_FT0(cpu_env);
+ gen_helper_fpop(cpu_env);
break;
case 0x33: /* de/3 */
switch(rm) {
case 1: /* fcompp */
- gen_helper_fmov_FT0_STN(tcg_const_i32(1));
- gen_helper_fcom_ST0_FT0();
- gen_helper_fpop();
- gen_helper_fpop();
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
+ gen_helper_fcom_ST0_FT0(cpu_env);
+ gen_helper_fpop(cpu_env);
+ gen_helper_fpop(cpu_env);
break;
default:
goto illegal_op;
}
break;
case 0x38: /* ffreep sti, undocumented op */
- gen_helper_ffree_STN(tcg_const_i32(opreg));
- gen_helper_fpop();
+ gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fpop(cpu_env);
break;
case 0x3c: /* df/4 */
switch(rm) {
case 0:
- gen_helper_fnstsw(cpu_tmp2_i32);
+ gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
gen_op_mov_reg_T0(OT_WORD, R_EAX);
break;
@@ -5997,17 +6055,17 @@
case 0x3d: /* fucomip */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
- gen_helper_fucomi_ST0_FT0();
- gen_helper_fpop();
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fucomi_ST0_FT0(cpu_env);
+ gen_helper_fpop(cpu_env);
s->cc_op = CC_OP_EFLAGS;
break;
case 0x3e: /* fcomip */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
- gen_helper_fcomi_ST0_FT0();
- gen_helper_fpop();
+ gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
+ gen_helper_fcomi_ST0_FT0(cpu_env);
+ gen_helper_fpop(cpu_env);
s->cc_op = CC_OP_EFLAGS;
break;
case 0x10 ... 0x13: /* fcmovxx */
@@ -6023,7 +6081,7 @@
op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
l1 = gen_new_label();
gen_jcc1(s, s->cc_op, op1, l1);
- gen_helper_fmov_ST0_STN(tcg_const_i32(opreg));
+ gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
gen_set_label(l1);
}
break;
@@ -6153,7 +6211,7 @@
ot = OT_BYTE;
else
ot = dflag ? OT_LONG : OT_WORD;
- val = ldub_code(s->pc++);
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
gen_op_movl_T0_im(val);
gen_check_io(s, ot, pc_start - s->cs_base,
SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
@@ -6173,7 +6231,7 @@
ot = OT_BYTE;
else
ot = dflag ? OT_LONG : OT_WORD;
- val = ldub_code(s->pc++);
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
gen_op_movl_T0_im(val);
gen_check_io(s, ot, pc_start - s->cs_base,
svm_is_rep(prefixes));
@@ -6235,7 +6293,7 @@
/************************/
/* control */
case 0xc2: /* ret im */
- val = ldsw_code(s->pc);
+ val = cpu_ldsw_code(cpu_single_env, s->pc);
s->pc += 2;
gen_pop_T0(s);
if (CODE64(s) && s->dflag)
@@ -6255,14 +6313,14 @@
gen_eob(s);
break;
case 0xca: /* lret im */
- val = ldsw_code(s->pc);
+ val = cpu_ldsw_code(cpu_single_env, s->pc);
s->pc += 2;
do_lret:
if (s->pe && !s->vm86) {
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_lret_protected(tcg_const_i32(s->dflag),
+ gen_helper_lret_protected(cpu_env, tcg_const_i32(s->dflag),
tcg_const_i32(val));
} else {
gen_stack_A0(s);
@@ -6289,20 +6347,20 @@
gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
if (!s->pe) {
/* real mode */
- gen_helper_iret_real(tcg_const_i32(s->dflag));
+ gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag));
s->cc_op = CC_OP_EFLAGS;
} else if (s->vm86) {
if (s->iopl != 3) {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
- gen_helper_iret_real(tcg_const_i32(s->dflag));
+ gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag));
s->cc_op = CC_OP_EFLAGS;
}
} else {
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_iret_protected(tcg_const_i32(s->dflag),
+ gen_helper_iret_protected(cpu_env, tcg_const_i32(s->dflag),
tcg_const_i32(s->pc - s->cs_base));
s->cc_op = CC_OP_EFLAGS;
}
@@ -6390,7 +6448,7 @@
break;
case 0x190 ... 0x19f: /* setcc Gv */
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
gen_setcc(s, b);
gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
break;
@@ -6400,7 +6458,7 @@
TCGv t0;
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
t0 = tcg_temp_local_new();
@@ -6440,7 +6498,7 @@
} else {
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- gen_helper_read_eflags(cpu_T[0]);
+ gen_helper_read_eflags(cpu_T[0], cpu_env);
gen_push_T0(s);
}
break;
@@ -6452,28 +6510,46 @@
gen_pop_T0(s);
if (s->cpl == 0) {
if (s->dflag) {
- gen_helper_write_eflags(cpu_T[0],
- tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK)));
+ gen_helper_write_eflags(cpu_env, cpu_T[0],
+ tcg_const_i32((TF_MASK | AC_MASK |
+ ID_MASK | NT_MASK |
+ IF_MASK |
+ IOPL_MASK)));
} else {
- gen_helper_write_eflags(cpu_T[0],
- tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff));
+ gen_helper_write_eflags(cpu_env, cpu_T[0],
+ tcg_const_i32((TF_MASK | AC_MASK |
+ ID_MASK | NT_MASK |
+ IF_MASK | IOPL_MASK)
+ & 0xffff));
}
} else {
if (s->cpl <= s->iopl) {
if (s->dflag) {
- gen_helper_write_eflags(cpu_T[0],
- tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK)));
+ gen_helper_write_eflags(cpu_env, cpu_T[0],
+ tcg_const_i32((TF_MASK |
+ AC_MASK |
+ ID_MASK |
+ NT_MASK |
+ IF_MASK)));
} else {
- gen_helper_write_eflags(cpu_T[0],
- tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff));
+ gen_helper_write_eflags(cpu_env, cpu_T[0],
+ tcg_const_i32((TF_MASK |
+ AC_MASK |
+ ID_MASK |
+ NT_MASK |
+ IF_MASK)
+ & 0xffff));
}
} else {
if (s->dflag) {
- gen_helper_write_eflags(cpu_T[0],
- tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK)));
+ gen_helper_write_eflags(cpu_env, cpu_T[0],
+ tcg_const_i32((TF_MASK | AC_MASK |
+ ID_MASK | NT_MASK)));
} else {
- gen_helper_write_eflags(cpu_T[0],
- tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff));
+ gen_helper_write_eflags(cpu_env, cpu_T[0],
+ tcg_const_i32((TF_MASK | AC_MASK |
+ ID_MASK | NT_MASK)
+ & 0xffff));
}
}
}
@@ -6540,7 +6616,7 @@
/* bit operations */
case 0x1ba: /* bt/bts/btr/btc Gv, im */
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
op = (modrm >> 3) & 7;
mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s);
@@ -6552,7 +6628,7 @@
gen_op_mov_TN_reg(ot, 0, rm);
}
/* load shift */
- val = ldub_code(s->pc++);
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
gen_op_movl_T1_im(val);
if (op < 4)
goto illegal_op;
@@ -6571,7 +6647,7 @@
op = 3;
do_btx:
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s);
@@ -6632,7 +6708,7 @@
TCGv t0;
ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
gen_ldst_modrm(s,modrm, ot, OR_TMP0, 0);
gen_extu(ot, cpu_T[0]);
@@ -6674,7 +6750,7 @@
goto illegal_op;
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- gen_helper_daa();
+ gen_helper_daa(cpu_env);
s->cc_op = CC_OP_EFLAGS;
break;
case 0x2f: /* das */
@@ -6682,7 +6758,7 @@
goto illegal_op;
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- gen_helper_das();
+ gen_helper_das(cpu_env);
s->cc_op = CC_OP_EFLAGS;
break;
case 0x37: /* aaa */
@@ -6690,7 +6766,7 @@
goto illegal_op;
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- gen_helper_aaa();
+ gen_helper_aaa(cpu_env);
s->cc_op = CC_OP_EFLAGS;
break;
case 0x3f: /* aas */
@@ -6698,25 +6774,25 @@
goto illegal_op;
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- gen_helper_aas();
+ gen_helper_aas(cpu_env);
s->cc_op = CC_OP_EFLAGS;
break;
case 0xd4: /* aam */
if (CODE64(s))
goto illegal_op;
- val = ldub_code(s->pc++);
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
if (val == 0) {
gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
} else {
- gen_helper_aam(tcg_const_i32(val));
+ gen_helper_aam(cpu_env, tcg_const_i32(val));
s->cc_op = CC_OP_LOGICB;
}
break;
case 0xd5: /* aad */
if (CODE64(s))
goto illegal_op;
- val = ldub_code(s->pc++);
- gen_helper_aad(tcg_const_i32(val));
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
+ gen_helper_aad(cpu_env, tcg_const_i32(val));
s->cc_op = CC_OP_LOGICB;
break;
/************************/
@@ -6742,14 +6818,14 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_fwait();
+ gen_helper_fwait(cpu_env);
}
break;
case 0xcc: /* int3 */
gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
break;
case 0xcd: /* int N */
- val = ldub_code(s->pc++);
+ val = cpu_ldub_code(cpu_single_env, s->pc++);
if (s->vm86 && s->iopl != 3) {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
@@ -6762,7 +6838,7 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_into(tcg_const_i32(s->pc - pc_start));
+ gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
break;
#ifdef WANT_ICEBP
case 0xf1: /* icebp (undocumented, exits to external debugger) */
@@ -6779,13 +6855,13 @@
case 0xfa: /* cli */
if (!s->vm86) {
if (s->cpl <= s->iopl) {
- gen_helper_cli();
+ gen_helper_cli(cpu_env);
} else {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
}
} else {
if (s->iopl == 3) {
- gen_helper_cli();
+ gen_helper_cli(cpu_env);
} else {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
}
@@ -6795,12 +6871,12 @@
if (!s->vm86) {
if (s->cpl <= s->iopl) {
gen_sti:
- gen_helper_sti();
+ gen_helper_sti(cpu_env);
/* interruptions are enabled only the first insn after sti */
/* If several instructions disable interrupts, only the
_first_ does it */
if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
- gen_helper_set_inhibit_irq();
+ gen_helper_set_inhibit_irq(cpu_env);
/* give a chance to handle pending irqs */
gen_jmp_im(s->pc - s->cs_base);
gen_eob(s);
@@ -6819,7 +6895,7 @@
if (CODE64(s))
goto illegal_op;
ot = dflag ? OT_LONG : OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = (modrm >> 3) & 7;
mod = (modrm >> 6) & 3;
if (mod == 3)
@@ -6828,10 +6904,11 @@
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
gen_jmp_im(pc_start - s->cs_base);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- if (ot == OT_WORD)
- gen_helper_boundw(cpu_A0, cpu_tmp2_i32);
- else
- gen_helper_boundl(cpu_A0, cpu_tmp2_i32);
+ if (ot == OT_WORD) {
+ gen_helper_boundw(cpu_env, cpu_A0, cpu_tmp2_i32);
+ } else {
+ gen_helper_boundl(cpu_env, cpu_A0, cpu_tmp2_i32);
+ }
break;
case 0x1c8 ... 0x1cf: /* bswap reg */
reg = (b & 7) | REX_B(s);
@@ -6919,9 +6996,9 @@
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
if (b & 2) {
- gen_helper_rdmsr();
+ gen_helper_rdmsr(cpu_env);
} else {
- gen_helper_wrmsr();
+ gen_helper_wrmsr(cpu_env);
}
}
break;
@@ -6931,7 +7008,7 @@
gen_jmp_im(pc_start - s->cs_base);
if (use_icount)
gen_io_start();
- gen_helper_rdtsc();
+ gen_helper_rdtsc(cpu_env);
if (use_icount) {
gen_io_end();
gen_jmp(s, s->pc - s->cs_base);
@@ -6941,7 +7018,7 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_rdpmc();
+ gen_helper_rdpmc(cpu_env);
break;
case 0x134: /* sysenter */
/* For Intel SYSENTER is valid on 64-bit */
@@ -6952,7 +7029,7 @@
} else {
gen_update_cc_op(s);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_sysenter();
+ gen_helper_sysenter(cpu_env);
gen_eob(s);
}
break;
@@ -6965,7 +7042,7 @@
} else {
gen_update_cc_op(s);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_sysexit(tcg_const_i32(dflag));
+ gen_helper_sysexit(cpu_env, tcg_const_i32(dflag));
gen_eob(s);
}
break;
@@ -6974,7 +7051,7 @@
/* XXX: is it usable in real mode ? */
gen_update_cc_op(s);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_syscall(tcg_const_i32(s->pc - pc_start));
+ gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
gen_eob(s);
break;
case 0x107: /* sysret */
@@ -6983,7 +7060,7 @@
} else {
gen_update_cc_op(s);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_sysret(tcg_const_i32(s->dflag));
+ gen_helper_sysret(cpu_env, tcg_const_i32(s->dflag));
/* condition codes are modified only in long mode */
if (s->lma)
s->cc_op = CC_OP_EFLAGS;
@@ -6995,7 +7072,7 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_cpuid();
+ gen_helper_cpuid(cpu_env);
break;
case 0xf4: /* hlt */
if (s->cpl != 0) {
@@ -7004,12 +7081,12 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_hlt(tcg_const_i32(s->pc - pc_start));
+ gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
s->is_jmp = DISAS_TB_JUMP;
}
break;
case 0x100:
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
op = (modrm >> 3) & 7;
switch(op) {
@@ -7033,7 +7110,7 @@
gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
gen_jmp_im(pc_start - s->cs_base);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_lldt(cpu_tmp2_i32);
+ gen_helper_lldt(cpu_env, cpu_tmp2_i32);
}
break;
case 1: /* str */
@@ -7056,7 +7133,7 @@
gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
gen_jmp_im(pc_start - s->cs_base);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_ltr(cpu_tmp2_i32);
+ gen_helper_ltr(cpu_env, cpu_tmp2_i32);
}
break;
case 4: /* verr */
@@ -7066,10 +7143,11 @@
gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- if (op == 4)
- gen_helper_verr(cpu_T[0]);
- else
- gen_helper_verw(cpu_T[0]);
+ if (op == 4) {
+ gen_helper_verr(cpu_env, cpu_T[0]);
+ } else {
+ gen_helper_verw(cpu_env, cpu_T[0]);
+ }
s->cc_op = CC_OP_EFLAGS;
break;
default:
@@ -7077,7 +7155,7 @@
}
break;
case 0x101:
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
op = (modrm >> 3) & 7;
rm = modrm & 7;
@@ -7116,7 +7194,7 @@
gen_op_andl_A0_ffff();
}
gen_add_A0_ds_seg(s);
- gen_helper_monitor(cpu_A0);
+ gen_helper_monitor(cpu_env, cpu_A0);
break;
case 1: /* mwait */
if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
@@ -7124,7 +7202,7 @@
goto illegal_op;
gen_update_cc_op(s);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_mwait(tcg_const_i32(s->pc - pc_start));
+ gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
gen_eob(s);
break;
default:
@@ -7156,7 +7234,7 @@
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
break;
} else {
- gen_helper_vmrun(tcg_const_i32(s->aflag),
+ gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag),
tcg_const_i32(s->pc - pc_start));
tcg_gen_exit_tb(0);
s->is_jmp = DISAS_TB_JUMP;
@@ -7165,7 +7243,7 @@
case 1: /* VMMCALL */
if (!(s->flags & HF_SVME_MASK))
goto illegal_op;
- gen_helper_vmmcall();
+ gen_helper_vmmcall(cpu_env);
break;
case 2: /* VMLOAD */
if (!(s->flags & HF_SVME_MASK) || !s->pe)
@@ -7174,7 +7252,7 @@
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
break;
} else {
- gen_helper_vmload(tcg_const_i32(s->aflag));
+ gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag));
}
break;
case 3: /* VMSAVE */
@@ -7184,7 +7262,7 @@
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
break;
} else {
- gen_helper_vmsave(tcg_const_i32(s->aflag));
+ gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag));
}
break;
case 4: /* STGI */
@@ -7196,7 +7274,7 @@
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
break;
} else {
- gen_helper_stgi();
+ gen_helper_stgi(cpu_env);
}
break;
case 5: /* CLGI */
@@ -7206,7 +7284,7 @@
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
break;
} else {
- gen_helper_clgi();
+ gen_helper_clgi(cpu_env);
}
break;
case 6: /* SKINIT */
@@ -7214,7 +7292,7 @@
!(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) ||
!s->pe)
goto illegal_op;
- gen_helper_skinit();
+ gen_helper_skinit(cpu_env);
break;
case 7: /* INVLPGA */
if (!(s->flags & HF_SVME_MASK) || !s->pe)
@@ -7223,7 +7301,7 @@
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
break;
} else {
- gen_helper_invlpga(tcg_const_i32(s->aflag));
+ gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag));
}
break;
default:
@@ -7264,7 +7342,7 @@
} else {
gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
- gen_helper_lmsw(cpu_T[0]);
+ gen_helper_lmsw(cpu_env, cpu_T[0]);
gen_jmp_im(s->pc - s->cs_base);
gen_eob(s);
}
@@ -7278,7 +7356,7 @@
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
- gen_helper_invlpg(cpu_A0);
+ gen_helper_invlpg(cpu_env, cpu_A0);
gen_jmp_im(s->pc - s->cs_base);
gen_eob(s);
}
@@ -7313,7 +7391,7 @@
gen_jmp_im(pc_start - s->cs_base);
if (use_icount)
gen_io_start();
- gen_helper_rdtscp();
+ gen_helper_rdtscp(cpu_env);
if (use_icount) {
gen_io_end();
gen_jmp(s, s->pc - s->cs_base);
@@ -7344,7 +7422,7 @@
/* d_ot is the size of destination */
d_ot = dflag + OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s);
@@ -7376,7 +7454,7 @@
t1 = tcg_temp_local_new();
t2 = tcg_temp_local_new();
ot = OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = (modrm >> 3) & 7;
mod = (modrm >> 6) & 3;
rm = modrm & 7;
@@ -7424,16 +7502,17 @@
if (!s->pe || s->vm86)
goto illegal_op;
ot = dflag ? OT_LONG : OT_WORD;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
t0 = tcg_temp_local_new();
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- if (b == 0x102)
- gen_helper_lar(t0, cpu_T[0]);
- else
- gen_helper_lsl(t0, cpu_T[0]);
+ if (b == 0x102) {
+ gen_helper_lar(t0, cpu_env, cpu_T[0]);
+ } else {
+ gen_helper_lsl(t0, cpu_env, cpu_T[0]);
+ }
tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
label1 = gen_new_label();
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
@@ -7444,7 +7523,7 @@
}
break;
case 0x118:
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
op = (modrm >> 3) & 7;
switch(op) {
@@ -7463,7 +7542,7 @@
}
break;
case 0x119 ... 0x11f: /* nop (multi byte) */
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
gen_nop_modrm(s, modrm);
break;
case 0x120: /* mov reg, crN */
@@ -7471,7 +7550,7 @@
if (s->cpl != 0) {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
if ((modrm & 0xc0) != 0xc0)
goto illegal_op;
rm = (modrm & 7) | REX_B(s);
@@ -7495,11 +7574,12 @@
gen_jmp_im(pc_start - s->cs_base);
if (b & 2) {
gen_op_mov_TN_reg(ot, 0, rm);
- gen_helper_write_crN(tcg_const_i32(reg), cpu_T[0]);
+ gen_helper_write_crN(cpu_env, tcg_const_i32(reg),
+ cpu_T[0]);
gen_jmp_im(s->pc - s->cs_base);
gen_eob(s);
} else {
- gen_helper_read_crN(cpu_T[0], tcg_const_i32(reg));
+ gen_helper_read_crN(cpu_T[0], cpu_env, tcg_const_i32(reg));
gen_op_mov_reg_T0(ot, rm);
}
break;
@@ -7513,7 +7593,7 @@
if (s->cpl != 0) {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
if ((modrm & 0xc0) != 0xc0)
goto illegal_op;
rm = (modrm & 7) | REX_B(s);
@@ -7528,7 +7608,7 @@
if (b & 2) {
gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
gen_op_mov_TN_reg(ot, 0, rm);
- gen_helper_movl_drN_T0(tcg_const_i32(reg), cpu_T[0]);
+ gen_helper_movl_drN_T0(cpu_env, tcg_const_i32(reg), cpu_T[0]);
gen_jmp_im(s->pc - s->cs_base);
gen_eob(s);
} else {
@@ -7543,7 +7623,7 @@
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
- gen_helper_clts();
+ gen_helper_clts(cpu_env);
/* abort block because static cpu state changed */
gen_jmp_im(s->pc - s->cs_base);
gen_eob(s);
@@ -7554,7 +7634,7 @@
if (!(s->cpuid_features & CPUID_SSE2))
goto illegal_op;
ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
if (mod == 3)
goto illegal_op;
@@ -7563,7 +7643,7 @@
gen_ldst_modrm(s, modrm, ot, reg, 1);
break;
case 0x1ae:
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
op = (modrm >> 3) & 7;
switch(op) {
@@ -7579,7 +7659,7 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_fxsave(cpu_A0, tcg_const_i32((s->dflag == 2)));
+ gen_helper_fxsave(cpu_env, cpu_A0, tcg_const_i32((s->dflag == 2)));
break;
case 1: /* fxrstor */
if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
@@ -7593,7 +7673,8 @@
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_helper_fxrstor(cpu_A0, tcg_const_i32((s->dflag == 2)));
+ gen_helper_fxrstor(cpu_env, cpu_A0,
+ tcg_const_i32((s->dflag == 2)));
break;
case 2: /* ldmxcsr */
case 3: /* stmxcsr */
@@ -7608,7 +7689,7 @@
if (op == 2) {
gen_op_ld_T0_A0(OT_LONG + s->mem_index);
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
- gen_helper_ldmxcsr(cpu_tmp2_i32);
+ gen_helper_ldmxcsr(cpu_env, cpu_tmp2_i32);
} else {
tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
gen_op_st_T0_A0(OT_LONG + s->mem_index);
@@ -7637,7 +7718,7 @@
}
break;
case 0x10d: /* 3DNow! prefetch(w) */
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
mod = (modrm >> 6) & 3;
if (mod == 3)
goto illegal_op;
@@ -7650,7 +7731,7 @@
goto illegal_op;
gen_update_cc_op(s);
gen_jmp_im(s->pc - s->cs_base);
- gen_helper_rsm();
+ gen_helper_rsm(cpu_env);
gen_eob(s);
break;
case 0x1b8: /* SSE4.2 popcnt */
@@ -7660,7 +7741,7 @@
if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
goto illegal_op;
- modrm = ldub_code(s->pc++);
+ modrm = cpu_ldub_code(cpu_single_env, s->pc++);
reg = ((modrm >> 3) & 7);
if (s->prefix & PREFIX_DATA)
@@ -7671,7 +7752,7 @@
ot = OT_QUAD;
gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
- gen_helper_popcnt(cpu_T[0], cpu_T[0], tcg_const_i32(ot));
+ gen_helper_popcnt(cpu_T[0], cpu_env, cpu_T[0], tcg_const_i32(ot));
gen_op_mov_reg_T0(ot, reg);
s->cc_op = CC_OP_EFLAGS;
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 5742229..6fe4168 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -27,6 +27,7 @@
#include "gdbstub.h"
#include <kvm.h>
#include "kvm_ppc.h"
+#include "qmp-commands.h"
//#define PPC_DUMP_CPU
//#define PPC_DEBUG_SPR
@@ -10345,6 +10346,31 @@
}
}
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+ CpuDefinitionInfoList *cpu_list = NULL;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ppc_defs); i++) {
+ CpuDefinitionInfoList *entry;
+ CpuDefinitionInfo *info;
+
+ if (!ppc_cpu_usable(&ppc_defs[i])) {
+ continue;
+ }
+
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strdup(ppc_defs[i].name);
+
+ entry = g_malloc0(sizeof(*entry));
+ entry->value = info;
+ entry->next = cpu_list;
+ cpu_list = entry;
+ }
+
+ return cpu_list;
+}
+
/* CPUClass::reset() */
static void ppc_cpu_reset(CPUState *s)
{
diff --git a/ui/vnc.c b/ui/vnc.c
index 312ad7f..385e345 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3061,7 +3061,7 @@
if (strncmp(display, "unix:", 5) == 0)
vs->lsock = unix_connect(display+5);
else
- vs->lsock = inet_connect(display, true, NULL);
+ vs->lsock = inet_connect(display, true, NULL, NULL);
if (-1 == vs->lsock) {
g_free(vs->display);
vs->display = NULL;
diff --git a/vl.c b/vl.c
index 91076f0..d01256a 100644
--- a/vl.c
+++ b/vl.c
@@ -1213,6 +1213,37 @@
return NULL;
}
+MachineInfoList *qmp_query_machines(Error **errp)
+{
+ MachineInfoList *mach_list = NULL;
+ QEMUMachine *m;
+
+ for (m = first_machine; m; m = m->next) {
+ MachineInfoList *entry;
+ MachineInfo *info;
+
+ info = g_malloc0(sizeof(*info));
+ if (m->is_default) {
+ info->has_is_default = true;
+ info->is_default = true;
+ }
+
+ if (m->alias) {
+ info->has_alias = true;
+ info->alias = g_strdup(m->alias);
+ }
+
+ info->name = g_strdup(m->name);
+
+ entry = g_malloc0(sizeof(*entry));
+ entry->value = info;
+ entry->next = mach_list;
+ mach_list = entry;
+ }
+
+ return mach_list;
+}
+
/***********************************************************/
/* main execution loop */
@@ -1298,6 +1329,7 @@
static int powerdown_requested;
static int debug_requested;
static int suspend_requested;
+static int wakeup_requested;
static NotifierList suspend_notifiers =
NOTIFIER_LIST_INITIALIZER(suspend_notifiers);
static NotifierList wakeup_notifiers =
@@ -1352,6 +1384,13 @@
return r;
}
+static int qemu_wakeup_requested(void)
+{
+ int r = wakeup_requested;
+ wakeup_requested = 0;
+ return r;
+}
+
int qemu_powerdown_requested(void)
{
int r = powerdown_requested;
@@ -1457,9 +1496,8 @@
return;
}
runstate_set(RUN_STATE_RUNNING);
- monitor_protocol_event(QEVENT_WAKEUP, NULL);
notifier_list_notify(&wakeup_notifiers, &reason);
- reset_requested = 1;
+ wakeup_requested = 1;
qemu_notify_event();
}
@@ -1539,6 +1577,13 @@
runstate_set(RUN_STATE_PAUSED);
}
}
+ if (qemu_wakeup_requested()) {
+ pause_all_vcpus();
+ cpu_synchronize_all_states();
+ qemu_system_reset(VMRESET_SILENT);
+ resume_all_vcpus();
+ monitor_protocol_event(QEVENT_WAKEUP, NULL);
+ }
if (qemu_powerdown_requested()) {
monitor_protocol_event(QEVENT_POWERDOWN, NULL);
qemu_irq_raise(qemu_system_powerdown);