diff options
138 files changed, 1143 insertions, 811 deletions
diff --git a/.gitignore b/.gitignore index fd6e6c38c7..e9bbc006d3 100644 --- a/.gitignore +++ b/.gitignore @@ -65,6 +65,8 @@ /scsi/qemu-pr-helper /vhost-user-scsi /vhost-user-blk +/vhost-user-gpu +/vhost-user-input /fsdev/virtfs-proxy-helper *.tmp *.[1-9] @@ -131,6 +133,7 @@ /docs/interop/qemu-qmp-ref.info* /docs/interop/qemu-qmp-ref.txt /docs/version.texi +/contrib/vhost-user-gpu/50-qemu-gpu.json *.tps .stgit-* .git-submodule-status diff --git a/MAINTAINERS b/MAINTAINERS index 743a92666a..ef6c01084b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1274,6 +1274,7 @@ Machine core M: Eduardo Habkost <ehabkost@redhat.com> M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com> S: Supported +F: hw/core/cpu.c F: hw/core/machine-qmp-cmds.c F: hw/core/machine.c F: hw/core/null-machine.c @@ -1281,10 +1282,9 @@ F: hw/core/numa.c F: hw/cpu/cluster.c F: qapi/machine.json F: qapi/machine-target.json -F: qom/cpu.c F: include/hw/boards.h +F: include/hw/core/cpu.h F: include/hw/cpu/cluster.h -F: include/qom/cpu.h F: include/sysemu/numa.h T: git https://github.com/ehabkost/qemu.git machine-next @@ -2048,12 +2048,10 @@ F: hw/core/qdev* F: include/hw/qdev* F: include/monitor/qdev.h F: include/qom/ -X: include/qom/cpu.h F: qapi/qom.json F: qapi/qdev.json F: qdev-monitor.c F: qom/ -X: qom/cpu.c F: tests/check-qom-interface.c F: tests/check-qom-proplist.c F: tests/test-qdev-global-props.c @@ -84,8 +84,7 @@ endif include $(SRC_PATH)/rules.mak -# notempy and lor are defined in rules.mak -CONFIG_TOOLS := $(call notempty,$(TOOLS)) +# lor is defined in rules.mak CONFIG_BLOCK := $(call lor,$(CONFIG_SOFTMMU),$(CONFIG_TOOLS)) # Create QEMU_PKGVERSION and FULL_VERSION strings @@ -681,7 +680,7 @@ clean: recurse-clean ! -path ./roms/edk2/BaseTools/Source/Python/UPT/Dll/sqlite3.dll \ -exec rm {} + rm -f $(edk2-decompressed) - rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga$(EXESUF) TAGS cscope.* *.pod *~ */*~ + rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) TAGS cscope.* *.pod *~ */*~ rm -f fsdev/*.pod scsi/*.pod rm -f qemu-img-cmds.h rm -f ui/shader/*-vert.h ui/shader/*-frag.h @@ -809,7 +808,7 @@ ifdef CONFIG_POSIX $(INSTALL_DATA) docs/interop/qemu-qmp-ref.7 "$(DESTDIR)$(mandir)/man7" $(INSTALL_DATA) docs/qemu-block-drivers.7 "$(DESTDIR)$(mandir)/man7" $(INSTALL_DATA) docs/qemu-cpu-models.7 "$(DESTDIR)$(mandir)/man7" -ifneq ($(TOOLS),) +ifeq ($(CONFIG_TOOLS),y) $(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1" $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man8" $(INSTALL_DATA) qemu-nbd.8 "$(DESTDIR)$(mandir)/man8" @@ -845,7 +844,7 @@ install: all $(if $(BUILD_DOCS),install-doc) install-datadir install-localstated $(if $(INSTALL_BLOBS),$(edk2-decompressed)) \ recurse-install ifneq ($(TOOLS),) - $(call install-prog,$(subst qemu-ga,qemu-ga$(EXESUF),$(TOOLS)),$(DESTDIR)$(bindir)) + $(call install-prog,$(TOOLS),$(DESTDIR)$(bindir)) endif ifneq ($(CONFIG_MODULES),) $(INSTALL_DIR) "$(DESTDIR)$(qemu_moddir)" @@ -1158,7 +1157,7 @@ endif @echo '' @echo 'Test targets:' @echo ' check - Run all tests (check-help for details)' - @echo ' docker - Help about targets running tests inside Docker containers' + @echo ' docker - Help about targets running tests inside containers' @echo ' vm-help - Help about targets running tests inside VM' @echo '' @echo 'Documentation targets:' diff --git a/accel/tcg/user-exec-stub.c b/accel/tcg/user-exec-stub.c index 4bf00b8496..f6d8c8fb6f 100644 --- a/accel/tcg/user-exec-stub.c +++ b/accel/tcg/user-exec-stub.c @@ -1,5 +1,5 @@ #include "qemu/osdep.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "sysemu/replay.h" #include "sysemu/sysemu.h" diff --git a/arch_init.c b/arch_init.c index 74b0708634..0a1531124c 100644 --- a/arch_init.c +++ b/arch_init.c @@ -106,14 +106,3 @@ int xen_available(void) return 0; #endif } - - -TargetInfo *qmp_query_target(Error **errp) -{ - TargetInfo *info = g_malloc0(sizeof(*info)); - - info->arch = qapi_enum_parse(&SysEmuTarget_lookup, TARGET_NAME, -1, - &error_abort); - - return info; -} diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 7ca5d97af3..03f03407b0 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -150,7 +150,7 @@ static void tcp_chr_accept(QIONetListener *listener, void *opaque); static int tcp_chr_read_poll(void *opaque); -static void tcp_chr_disconnect(Chardev *chr); +static void tcp_chr_disconnect_locked(Chardev *chr); /* Called with chr_write_lock held. */ static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len) @@ -174,7 +174,7 @@ static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len) if (ret < 0 && errno != EAGAIN) { if (tcp_chr_read_poll(chr) <= 0) { - tcp_chr_disconnect(chr); + tcp_chr_disconnect_locked(chr); return len; } /* else let the read handler finish it properly */ } @@ -469,8 +469,9 @@ static void update_disconnected_filename(SocketChardev *s) /* NB may be called even if tcp_chr_connect has not been * reached, due to TLS or telnet initialization failure, * so can *not* assume s->state == TCP_CHARDEV_STATE_CONNECTED + * This must be called with chr->chr_write_lock held. */ -static void tcp_chr_disconnect(Chardev *chr) +static void tcp_chr_disconnect_locked(Chardev *chr) { SocketChardev *s = SOCKET_CHARDEV(chr); bool emit_close = s->state == TCP_CHARDEV_STATE_CONNECTED; @@ -490,6 +491,13 @@ static void tcp_chr_disconnect(Chardev *chr) } } +static void tcp_chr_disconnect(Chardev *chr) +{ + qemu_mutex_lock(&chr->chr_write_lock); + tcp_chr_disconnect_locked(chr); + qemu_mutex_unlock(&chr->chr_write_lock); +} + static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) { Chardev *chr = CHARDEV(opaque); @@ -1131,8 +1139,10 @@ static gboolean socket_reconnect_timeout(gpointer opaque) Chardev *chr = CHARDEV(opaque); SocketChardev *s = SOCKET_CHARDEV(opaque); + qemu_mutex_lock(&chr->chr_write_lock); g_source_unref(s->reconnect_timer); s->reconnect_timer = NULL; + qemu_mutex_unlock(&chr->chr_write_lock); if (chr->be_open) { return false; @@ -3022,15 +3022,15 @@ fi ########################################## # SDL probe -# Look for sdl configuration program (pkg-config or sdl-config). Try -# sdl-config even without cross prefix, and favour pkg-config over sdl-config. +# Look for sdl configuration program (pkg-config or sdl2-config). Try +# sdl2-config even without cross prefix, and favour pkg-config over sdl2-config. sdl_probe () { if $pkg_config sdl2 --exists; then sdlconfig="$pkg_config sdl2" sdlversion=$($sdlconfig --modversion 2>/dev/null) - elif has ${sdl_config}; then + elif has "$sdl2_config"; then sdlconfig="$sdl2_config" sdlversion=$($sdlconfig --version) else @@ -3041,7 +3041,7 @@ sdl_probe () # no need to do the rest return fi - if test -n "$cross_prefix" && test "$(basename "$sdlconfig")" = sdl-config; then + if test -n "$cross_prefix" && test "$(basename "$sdlconfig")" = sdl2-config; then echo warning: using "\"$sdlconfig\"" to detect cross-compiled sdl >&2 fi @@ -3636,7 +3636,7 @@ fi ########################################## # glib support probe -glib_req_ver=2.40 +glib_req_ver=2.48 glib_modules=gthread-2.0 if test "$modules" = yes; then glib_modules="$glib_modules gmodule-export-2.0" @@ -6129,7 +6129,7 @@ if [ "$guest_agent" != "no" ]; then if [ "$softmmu" = no -a "$want_tools" = no ] ; then guest_agent=no elif [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" -o "$mingw32" = "yes" ] ; then - tools="qemu-ga $tools" + tools="qemu-ga\$(EXESUF) $tools" guest_agent=yes elif [ "$guest_agent" != yes ]; then guest_agent=no @@ -6384,9 +6384,6 @@ if test "$vnc" = "yes" ; then echo "VNC JPEG support $vnc_jpeg" echo "VNC PNG support $vnc_png" fi -if test -n "$sparc_cpu"; then - echo "Target Sparc Arch $sparc_cpu" -fi echo "xen support $xen" if test "$xen" = "yes" ; then echo "xen ctrl version $xen_ctrl_version" @@ -6617,6 +6614,9 @@ fi if test "$profiler" = "yes" ; then echo "CONFIG_PROFILER=y" >> $config_host_mak fi +if test "$want_tools" = "yes" ; then + echo "CONFIG_TOOLS=y" >> $config_host_mak +fi if test "$slirp" != "no"; then echo "CONFIG_SLIRP=y" >> $config_host_mak echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak @@ -7363,11 +7363,6 @@ if test "$sparse" = "yes" ; then echo "HOST_CC := REAL_CC=\"\$(HOST_CC)\" cgcc" >> $config_host_mak echo "QEMU_CFLAGS += -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-non-pointer-null" >> $config_host_mak fi -if test "$cross_prefix" != ""; then - echo "AUTOCONF_HOST := --host=${cross_prefix%-}" >> $config_host_mak -else - echo "AUTOCONF_HOST := " >> $config_host_mak -fi echo "LDFLAGS=$LDFLAGS" >> $config_host_mak echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak @@ -8034,7 +8029,6 @@ preserve_env PKG_CONFIG preserve_env PKG_CONFIG_LIBDIR preserve_env PKG_CONFIG_PATH preserve_env PYTHON -preserve_env SDL_CONFIG preserve_env SDL2_CONFIG preserve_env SMBD preserve_env STRIP diff --git a/cpus-common.c b/cpus-common.c index 023cfebfa3..af3385a296 100644 --- a/cpus-common.c +++ b/cpus-common.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "qemu/main-loop.h" #include "exec/cpu-common.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "sysemu/cpus.h" static QemuMutex qemu_cpu_list_lock; diff --git a/crypto/afsplit.c b/crypto/afsplit.c index 328d68c96b..b1a5a20899 100644 --- a/crypto/afsplit.c +++ b/crypto/afsplit.c @@ -58,7 +58,7 @@ static int qcrypto_afsplit_hash(QCryptoHashAlgorithm hash, } for (i = 0; i < hashcount; i++) { - uint8_t *out = NULL; + g_autofree uint8_t *out = NULL; size_t outlen = 0; uint32_t iv = cpu_to_be32(i); struct iovec in[] = { @@ -79,7 +79,6 @@ static int qcrypto_afsplit_hash(QCryptoHashAlgorithm hash, assert(outlen == digestlen); memcpy(block + (i * digestlen), out, (i == (hashcount - 1)) ? finallen : digestlen); - g_free(out); } return 0; @@ -93,13 +92,12 @@ int qcrypto_afsplit_encode(QCryptoHashAlgorithm hash, uint8_t *out, Error **errp) { - uint8_t *block = g_new0(uint8_t, blocklen); + g_autofree uint8_t *block = g_new0(uint8_t, blocklen); size_t i; - int ret = -1; for (i = 0; i < (stripes - 1); i++) { if (qcrypto_random_bytes(out + (i * blocklen), blocklen, errp) < 0) { - goto cleanup; + return -1; } qcrypto_afsplit_xor(blocklen, @@ -108,18 +106,14 @@ int qcrypto_afsplit_encode(QCryptoHashAlgorithm hash, block); if (qcrypto_afsplit_hash(hash, blocklen, block, errp) < 0) { - goto cleanup; + return -1; } } qcrypto_afsplit_xor(blocklen, in, block, out + (i * blocklen)); - ret = 0; - - cleanup: - g_free(block); - return ret; + return 0; } @@ -130,9 +124,8 @@ int qcrypto_afsplit_decode(QCryptoHashAlgorithm hash, uint8_t *out, Error **errp) { - uint8_t *block = g_new0(uint8_t, blocklen); + g_autofree uint8_t *block = g_new0(uint8_t, blocklen); size_t i; - int ret = -1; for (i = 0; i < (stripes - 1); i++) { qcrypto_afsplit_xor(blocklen, @@ -141,7 +134,7 @@ int qcrypto_afsplit_decode(QCryptoHashAlgorithm hash, block); if (qcrypto_afsplit_hash(hash, blocklen, block, errp) < 0) { - goto cleanup; + return -1; } } @@ -149,10 +142,5 @@ int qcrypto_afsplit_decode(QCryptoHashAlgorithm hash, in + (i * blocklen), block, out); - - ret = 0; - - cleanup: - g_free(block); - return ret; + return 0; } diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 409ab50f20..743949adbf 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -425,14 +425,13 @@ qcrypto_block_luks_load_key(QCryptoBlock *block, Error **errp) { QCryptoBlockLUKS *luks = block->opaque; - uint8_t *splitkey; + g_autofree uint8_t *splitkey = NULL; size_t splitkeylen; - uint8_t *possiblekey; - int ret = -1; + g_autofree uint8_t *possiblekey = NULL; ssize_t rv; - QCryptoCipher *cipher = NULL; + g_autoptr(QCryptoCipher) cipher = NULL; uint8_t keydigest[QCRYPTO_BLOCK_LUKS_DIGEST_LEN]; - QCryptoIVGen *ivgen = NULL; + g_autoptr(QCryptoIVGen) ivgen = NULL; size_t niv; if (slot->active != QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED) { @@ -456,7 +455,7 @@ qcrypto_block_luks_load_key(QCryptoBlock *block, slot->iterations, possiblekey, masterkeylen, errp) < 0) { - goto cleanup; + return -1; } /* @@ -472,7 +471,7 @@ qcrypto_block_luks_load_key(QCryptoBlock *block, opaque, errp); if (rv < 0) { - goto cleanup; + return -1; } @@ -482,7 +481,7 @@ qcrypto_block_luks_load_key(QCryptoBlock *block, possiblekey, masterkeylen, errp); if (!cipher) { - goto cleanup; + return -1; } niv = qcrypto_cipher_get_iv_len(cipheralg, @@ -493,7 +492,7 @@ qcrypto_block_luks_load_key(QCryptoBlock *block, possiblekey, masterkeylen, errp); if (!ivgen) { - goto cleanup; + return -1; } @@ -512,7 +511,7 @@ qcrypto_block_luks_load_key(QCryptoBlock *block, splitkey, splitkeylen, errp) < 0) { - goto cleanup; + return -1; } /* @@ -525,7 +524,7 @@ qcrypto_block_luks_load_key(QCryptoBlock *block, splitkey, masterkey, errp) < 0) { - goto cleanup; + return -1; } @@ -544,26 +543,18 @@ qcrypto_block_luks_load_key(QCryptoBlock *block, luks->header.master_key_iterations, keydigest, G_N_ELEMENTS(keydigest), errp) < 0) { - goto cleanup; + return -1; } if (memcmp(keydigest, luks->header.master_key_digest, QCRYPTO_BLOCK_LUKS_DIGEST_LEN) == 0) { /* Success, we got the right master key */ - ret = 1; - goto cleanup; + return 1; } /* Fail, user's password was not valid for this key slot, * tell caller to try another slot */ - ret = 0; - - cleanup: - qcrypto_ivgen_free(ivgen); - qcrypto_cipher_free(cipher); - g_free(splitkey); - g_free(possiblekey); - return ret; + return 0; } @@ -644,7 +635,7 @@ qcrypto_block_luks_open(QCryptoBlock *block, int ret = 0; size_t i; ssize_t rv; - uint8_t *masterkey = NULL; + g_autofree uint8_t *masterkey = NULL; size_t masterkeylen; char *ivgen_name, *ivhash_name; QCryptoCipherMode ciphermode; @@ -653,7 +644,7 @@ qcrypto_block_luks_open(QCryptoBlock *block, QCryptoCipherAlgorithm ivcipheralg; QCryptoHashAlgorithm hash; QCryptoHashAlgorithm ivhash; - char *password = NULL; + g_autofree char *password = NULL; if (!(flags & QCRYPTO_BLOCK_OPEN_NO_IO)) { if (!options->u.luks.key_secret) { @@ -856,17 +847,12 @@ qcrypto_block_luks_open(QCryptoBlock *block, luks->ivgen_hash_alg = ivhash; luks->hash_alg = hash; - g_free(masterkey); - g_free(password); - return 0; fail: - g_free(masterkey); qcrypto_block_free_cipher(block); qcrypto_ivgen_free(block->ivgen); g_free(luks); - g_free(password); return ret; } @@ -891,20 +877,20 @@ qcrypto_block_luks_create(QCryptoBlock *block, QCryptoBlockLUKS *luks; QCryptoBlockCreateOptionsLUKS luks_opts; Error *local_err = NULL; - uint8_t *masterkey = NULL; - uint8_t *slotkey = NULL; - uint8_t *splitkey = NULL; + g_autofree uint8_t *masterkey = NULL; + g_autofree uint8_t *slotkey = NULL; + g_autofree uint8_t *splitkey = NULL; size_t splitkeylen = 0; size_t i; - QCryptoCipher *cipher = NULL; - QCryptoIVGen *ivgen = NULL; - char *password; + g_autoptr(QCryptoCipher) cipher = NULL; + g_autoptr(QCryptoIVGen) ivgen = NULL; + g_autofree char *password = NULL; const char *cipher_alg; const char *cipher_mode; const char *ivgen_alg; const char *ivgen_hash_alg = NULL; const char *hash_alg; - char *cipher_mode_spec = NULL; + g_autofree char *cipher_mode_spec = NULL; QCryptoCipherAlgorithm ivcipheralg = 0; uint64_t iters; @@ -1311,15 +1297,7 @@ qcrypto_block_luks_create(QCryptoBlock *block, luks->hash_alg = luks_opts.hash_alg; memset(masterkey, 0, luks->header.key_bytes); - g_free(masterkey); memset(slotkey, 0, luks->header.key_bytes); - g_free(slotkey); - g_free(splitkey); - g_free(password); - g_free(cipher_mode_spec); - - qcrypto_ivgen_free(ivgen); - qcrypto_cipher_free(cipher); return 0; @@ -1327,17 +1305,9 @@ qcrypto_block_luks_create(QCryptoBlock *block, if (masterkey) { memset(masterkey, 0, luks->header.key_bytes); } - g_free(masterkey); if (slotkey) { memset(slotkey, 0, luks->header.key_bytes); } - g_free(slotkey); - g_free(splitkey); - g_free(password); - g_free(cipher_mode_spec); - - qcrypto_ivgen_free(ivgen); - qcrypto_cipher_free(cipher); qcrypto_block_free_cipher(block); qcrypto_ivgen_free(block->ivgen); diff --git a/crypto/block.c b/crypto/block.c index ee96759f7d..325752871c 100644 --- a/crypto/block.c +++ b/crypto/block.c @@ -299,15 +299,13 @@ static int do_qcrypto_block_cipher_encdec(QCryptoCipher *cipher, QCryptoCipherEncDecFunc func, Error **errp) { - uint8_t *iv; + g_autofree uint8_t *iv = niv ? g_new0(uint8_t, niv) : NULL; int ret = -1; uint64_t startsector = offset / sectorsize; assert(QEMU_IS_ALIGNED(offset, sectorsize)); assert(QEMU_IS_ALIGNED(len, sectorsize)); - iv = niv ? g_new0(uint8_t, niv) : NULL; - while (len > 0) { size_t nbytes; if (niv) { @@ -320,19 +318,19 @@ static int do_qcrypto_block_cipher_encdec(QCryptoCipher *cipher, } if (ret < 0) { - goto cleanup; + return -1; } if (qcrypto_cipher_setiv(cipher, iv, niv, errp) < 0) { - goto cleanup; + return -1; } } nbytes = len > sectorsize ? sectorsize : len; if (func(cipher, buf, buf, nbytes, errp) < 0) { - goto cleanup; + return -1; } startsector++; @@ -340,10 +338,7 @@ static int do_qcrypto_block_cipher_encdec(QCryptoCipher *cipher, len -= nbytes; } - ret = 0; - cleanup: - g_free(iv); - return ret; + return 0; } diff --git a/crypto/hmac-glib.c b/crypto/hmac-glib.c index 7df627329d..509bbc74c2 100644 --- a/crypto/hmac-glib.c +++ b/crypto/hmac-glib.c @@ -21,12 +21,7 @@ static int qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = { [QCRYPTO_HASH_ALG_MD5] = G_CHECKSUM_MD5, [QCRYPTO_HASH_ALG_SHA1] = G_CHECKSUM_SHA1, [QCRYPTO_HASH_ALG_SHA256] = G_CHECKSUM_SHA256, -/* Support for HMAC SHA-512 in GLib 2.42 */ -#if GLIB_CHECK_VERSION(2, 42, 0) [QCRYPTO_HASH_ALG_SHA512] = G_CHECKSUM_SHA512, -#else - [QCRYPTO_HASH_ALG_SHA512] = -1, -#endif [QCRYPTO_HASH_ALG_SHA224] = -1, [QCRYPTO_HASH_ALG_SHA384] = -1, [QCRYPTO_HASH_ALG_RIPEMD160] = -1, diff --git a/crypto/pbkdf.c b/crypto/pbkdf.c index b7c7c4a59b..3775ddc6c5 100644 --- a/crypto/pbkdf.c +++ b/crypto/pbkdf.c @@ -69,12 +69,10 @@ uint64_t qcrypto_pbkdf2_count_iters(QCryptoHashAlgorithm hash, Error **errp) { uint64_t ret = -1; - uint8_t *out; + g_autofree uint8_t *out = g_new(uint8_t, nout); uint64_t iterations = (1 << 15); unsigned long long delta_ms, start_ms, end_ms; - out = g_new(uint8_t, nout); - while (1) { if (qcrypto_pbkdf2_get_thread_cpu(&start_ms, errp) < 0) { goto cleanup; @@ -108,6 +106,5 @@ uint64_t qcrypto_pbkdf2_count_iters(QCryptoHashAlgorithm hash, cleanup: memset(out, 0, nout); - g_free(out); return ret; } diff --git a/crypto/secret.c b/crypto/secret.c index a75d50ae0c..1cf0ad0ce8 100644 --- a/crypto/secret.c +++ b/crypto/secret.c @@ -72,10 +72,12 @@ static void qcrypto_secret_decrypt(QCryptoSecret *secret, size_t *outputlen, Error **errp) { - uint8_t *key = NULL, *ciphertext = NULL, *iv = NULL; + g_autofree uint8_t *key = NULL; + g_autofree uint8_t *ciphertext = NULL; + g_autofree uint8_t *iv = NULL; size_t keylen, ciphertextlen, ivlen; - QCryptoCipher *aes = NULL; - uint8_t *plaintext = NULL; + g_autoptr(QCryptoCipher) aes = NULL; + g_autofree uint8_t *plaintext = NULL; *output = NULL; *outputlen = 0; @@ -83,27 +85,27 @@ static void qcrypto_secret_decrypt(QCryptoSecret *secret, if (qcrypto_secret_lookup(secret->keyid, &key, &keylen, errp) < 0) { - goto cleanup; + return; } if (keylen != 32) { error_setg(errp, "Key should be 32 bytes in length"); - goto cleanup; + return; } if (!secret->iv) { error_setg(errp, "IV is required to decrypt secret"); - goto cleanup; + return; } iv = qbase64_decode(secret->iv, -1, &ivlen, errp); if (!iv) { - goto cleanup; + return; } if (ivlen != 16) { error_setg(errp, "IV should be 16 bytes in length not %zu", ivlen); - goto cleanup; + return; } aes = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_256, @@ -111,11 +113,11 @@ static void qcrypto_secret_decrypt(QCryptoSecret *secret, key, keylen, errp); if (!aes) { - goto cleanup; + return; } if (qcrypto_cipher_setiv(aes, iv, ivlen, errp) < 0) { - goto cleanup; + return; } if (secret->format == QCRYPTO_SECRET_FORMAT_BASE64) { @@ -124,7 +126,7 @@ static void qcrypto_secret_decrypt(QCryptoSecret *secret, &ciphertextlen, errp); if (!ciphertext) { - goto cleanup; + return; } plaintext = g_new0(uint8_t, ciphertextlen + 1); } else { @@ -136,8 +138,7 @@ static void qcrypto_secret_decrypt(QCryptoSecret *secret, plaintext, ciphertextlen, errp) < 0) { - plaintext = NULL; - goto cleanup; + return; } if (plaintext[ciphertextlen - 1] > 16 || @@ -145,9 +146,7 @@ static void qcrypto_secret_decrypt(QCryptoSecret *secret, error_setg(errp, "Incorrect number of padding bytes (%d) " "found on decrypted data", (int)plaintext[ciphertextlen - 1]); - g_free(plaintext); - plaintext = NULL; - goto cleanup; + return; } /* Even though plaintext may contain arbitrary NUL @@ -156,14 +155,8 @@ static void qcrypto_secret_decrypt(QCryptoSecret *secret, ciphertextlen -= plaintext[ciphertextlen - 1]; plaintext[ciphertextlen] = '\0'; - *output = plaintext; + *output = g_steal_pointer(&plaintext); *outputlen = ciphertextlen; - - cleanup: - g_free(ciphertext); - g_free(iv); - g_free(key); - qcrypto_cipher_free(aes); } diff --git a/crypto/tlscredsanon.c b/crypto/tlscredsanon.c index d2adc7c131..a235f60146 100644 --- a/crypto/tlscredsanon.c +++ b/crypto/tlscredsanon.c @@ -34,9 +34,8 @@ static int qcrypto_tls_creds_anon_load(QCryptoTLSCredsAnon *creds, Error **errp) { - char *dhparams = NULL; + g_autofree char *dhparams = NULL; int ret; - int rv = -1; trace_qcrypto_tls_creds_anon_load(creds, creds->parent_obj.dir ? creds->parent_obj.dir : "<nodir>"); @@ -45,20 +44,20 @@ qcrypto_tls_creds_anon_load(QCryptoTLSCredsAnon *creds, if (qcrypto_tls_creds_get_path(&creds->parent_obj, QCRYPTO_TLS_CREDS_DH_PARAMS, false, &dhparams, errp) < 0) { - goto cleanup; + return -1; } ret = gnutls_anon_allocate_server_credentials(&creds->data.server); if (ret < 0) { error_setg(errp, "Cannot allocate credentials: %s", gnutls_strerror(ret)); - goto cleanup; + return -1; } if (qcrypto_tls_creds_get_dh_params_file(&creds->parent_obj, dhparams, &creds->parent_obj.dh_params, errp) < 0) { - goto cleanup; + return -1; } gnutls_anon_set_server_dh_params(creds->data.server, @@ -68,14 +67,11 @@ qcrypto_tls_creds_anon_load(QCryptoTLSCredsAnon *creds, if (ret < 0) { error_setg(errp, "Cannot allocate credentials: %s", gnutls_strerror(ret)); - goto cleanup; + return -1; } } - rv = 0; - cleanup: - g_free(dhparams); - return rv; + return 0; } diff --git a/crypto/tlscredspsk.c b/crypto/tlscredspsk.c index 4b6cf636ce..15d12e2448 100644 --- a/crypto/tlscredspsk.c +++ b/crypto/tlscredspsk.c @@ -69,7 +69,8 @@ static int qcrypto_tls_creds_psk_load(QCryptoTLSCredsPSK *creds, Error **errp) { - char *pskfile = NULL, *dhparams = NULL; + g_autofree char *pskfile = NULL; + g_autofree char *dhparams = NULL; const char *username; int ret; int rv = -1; @@ -139,8 +140,6 @@ qcrypto_tls_creds_psk_load(QCryptoTLSCredsPSK *creds, rv = 0; cleanup: g_free(key.data); - g_free(pskfile); - g_free(dhparams); return rv; } diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c index 56dcef3673..01fc304e5d 100644 --- a/crypto/tlscredsx509.c +++ b/crypto/tlscredsx509.c @@ -378,7 +378,7 @@ qcrypto_tls_creds_load_cert(QCryptoTLSCredsX509 *creds, { gnutls_datum_t data; gnutls_x509_crt_t cert = NULL; - char *buf = NULL; + g_autofree char *buf = NULL; gsize buflen; GError *gerr; int ret = -1; @@ -420,7 +420,6 @@ qcrypto_tls_creds_load_cert(QCryptoTLSCredsX509 *creds, gnutls_x509_crt_deinit(cert); cert = NULL; } - g_free(buf); return cert; } @@ -434,9 +433,8 @@ qcrypto_tls_creds_load_ca_cert_list(QCryptoTLSCredsX509 *creds, Error **errp) { gnutls_datum_t data; - char *buf = NULL; + g_autofree char *buf = NULL; gsize buflen; - int ret = -1; GError *gerr = NULL; *ncerts = 0; @@ -446,7 +444,7 @@ qcrypto_tls_creds_load_ca_cert_list(QCryptoTLSCredsX509 *creds, error_setg(errp, "Cannot load CA cert list %s: %s", certFile, gerr->message); g_error_free(gerr); - goto cleanup; + return -1; } data.data = (unsigned char *)buf; @@ -457,15 +455,11 @@ qcrypto_tls_creds_load_ca_cert_list(QCryptoTLSCredsX509 *creds, error_setg(errp, "Unable to import CA certificate list %s", certFile); - goto cleanup; + return -1; } *ncerts = certMax; - ret = 0; - - cleanup: - g_free(buf); - return ret; + return 0; } diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst index 220059679a..f7668ae389 100644 --- a/docs/devel/migration.rst +++ b/docs/devel/migration.rst @@ -314,7 +314,7 @@ For example: a) Add a new property using ``DEFINE_PROP_BOOL`` - e.g. support-foo and default it to true. - b) Add an entry to the ``HW_COMPAT_`` for the previous version that sets + b) Add an entry to the ``hw_compat_`` for the previous version that sets the property to false. c) Add a static bool support_foo function that tests the property. d) Add a subsection with a .needed set to the support_foo function diff --git a/docs/interop/firmware.json b/docs/interop/firmware.json index ff8c2ce5f2..8ffb7856d2 100644 --- a/docs/interop/firmware.json +++ b/docs/interop/firmware.json @@ -13,7 +13,7 @@ # = Firmware ## -{ 'include' : 'common.json' } +{ 'include' : 'machine.json' } { 'include' : 'block-core.json' } ## @@ -939,7 +939,7 @@ void cpu_exec_unrealizefn(CPUState *cpu) Property cpu_common_props[] = { #ifndef CONFIG_USER_ONLY /* Create a memory property for softmmu CPU object, - * so users can wire up its memory. (This can't go in qom/cpu.c + * so users can wire up its memory. (This can't go in hw/core/cpu.c * because that file is compiled only once for both user-mode * and system builds.) The default if no link is set up is to use * the system address space. diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c index a83567e6aa..6e8293aac9 100644 --- a/hw/acpi/cpu_hotplug.c +++ b/hw/acpi/cpu_hotplug.c @@ -12,7 +12,7 @@ #include "qemu/osdep.h" #include "hw/acpi/cpu_hotplug.h" #include "qapi/error.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/i386/pc.h" #include "qemu/error-report.h" diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 2ca52bf045..2034dd749e 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -31,7 +31,7 @@ #include "hw/pci/pci.h" #include "migration/vmstate.h" #include "qemu/timer.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "sysemu/reset.h" #include "sysemu/runstate.h" #include "hw/acpi/acpi.h" diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 1c907d2a7d..5742c3df87 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -44,7 +44,7 @@ #include "hw/xen/xen.h" #include "migration/qemu-file-types.h" #include "migration/vmstate.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "trace.h" #define GPE_BASE 0xafe0 diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index 956ebe32c8..245817d23e 100644 --- a/hw/arm/smmu-common.c +++ b/hw/arm/smmu-common.c @@ -20,7 +20,7 @@ #include "exec/address-spaces.h" #include "trace.h" #include "exec/target_page.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/qdev-properties.h" #include "qapi/error.h" #include "qemu/jhash.h" diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index fa9afd2b7e..a8b2d97fe9 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -30,7 +30,7 @@ #include "qapi/error.h" #include "qemu/bitmap.h" #include "trace.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "target/arm/cpu.h" #include "hw/acpi/acpi-defs.h" #include "hw/acpi/acpi.h" diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs index b49f880a0c..fd0550d1d9 100644 --- a/hw/core/Makefile.objs +++ b/hw/core/Makefile.objs @@ -8,6 +8,7 @@ common-obj-y += irq.o common-obj-y += hotplug.o common-obj-$(CONFIG_SOFTMMU) += nmi.o common-obj-$(CONFIG_SOFTMMU) += vm-change-state-handler.o +common-obj-y += cpu.o common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o common-obj-$(CONFIG_XILINX_AXI) += stream.o diff --git a/qom/cpu.c b/hw/core/cpu.c index aeb34f8c67..0035845511 100644 --- a/qom/cpu.c +++ b/hw/core/cpu.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "sysemu/hw_accel.h" #include "qemu/notify.h" #include "qemu/log.h" diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c index 06d8d6466e..4b1fc86a06 100644 --- a/hw/core/generic-loader.c +++ b/hw/core/generic-loader.c @@ -31,7 +31,7 @@ */ #include "qemu/osdep.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/sysbus.h" #include "sysemu/dma.h" #include "sysemu/reset.h" diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c index 526fbd5ced..15cf7c62e3 100644 --- a/hw/core/machine-qmp-cmds.c +++ b/hw/core/machine-qmp-cmds.c @@ -249,6 +249,16 @@ CurrentMachineParams *qmp_query_current_machine(Error **errp) return params; } +TargetInfo *qmp_query_target(Error **errp) +{ + TargetInfo *info = g_malloc0(sizeof(*info)); + + info->arch = qapi_enum_parse(&SysEmuTarget_lookup, TARGET_NAME, -1, + &error_abort); + + return info; +} + HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp) { MachineState *ms = MACHINE(qdev_get_machine()); diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c index 30b1991b52..1aa0a9a01a 100644 --- a/hw/core/null-machine.c +++ b/hw/core/null-machine.c @@ -16,7 +16,7 @@ #include "hw/boards.h" #include "sysemu/sysemu.h" #include "exec/address-spaces.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" static void machine_none_init(MachineState *mch) { diff --git a/hw/core/numa.c b/hw/core/numa.c index 7a63ddc4c6..4f7e4628a0 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -34,7 +34,7 @@ #include "qapi/opts-visitor.h" #include "qapi/qapi-visit-machine.h" #include "sysemu/qtest.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/mem/pc-dimm.h" #include "migration/vmstate.h" #include "hw/boards.h" diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c index cd1e165faf..6872a3a00a 100644 --- a/hw/cpu/a9mpcore.c +++ b/hw/cpu/a9mpcore.c @@ -14,7 +14,7 @@ #include "hw/cpu/a9mpcore.h" #include "hw/irq.h" #include "hw/qdev-properties.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" static void a9mp_priv_set_irq(void *opaque, int irq, int level) { diff --git a/hw/cpu/cluster.c b/hw/cpu/cluster.c index 74d8d43c00..349a883261 100644 --- a/hw/cpu/cluster.c +++ b/hw/cpu/cluster.c @@ -21,7 +21,7 @@ #include "qemu/osdep.h" #include "hw/cpu/cluster.h" #include "hw/qdev-properties.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "qapi/error.h" #include "qemu/module.h" #include "qemu/cutils.h" diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs index a64998fc7b..0f11d55b14 100644 --- a/hw/display/Makefile.objs +++ b/hw/display/Makefile.objs @@ -31,13 +31,13 @@ obj-$(CONFIG_MILKYMIST_TMU2) += milkymist-tmu2.o milkymist-tmu2.o-cflags := $(X11_CFLAGS) $(OPENGL_CFLAGS) milkymist-tmu2.o-libs := $(X11_LIBS) $(OPENGL_LIBS) -obj-$(CONFIG_OMAP) += omap_dss.o +common-obj-$(CONFIG_OMAP) += omap_dss.o obj-$(CONFIG_OMAP) += omap_lcdc.o -obj-$(CONFIG_PXA2XX) += pxa2xx_lcd.o -obj-$(CONFIG_RASPI) += bcm2835_fb.o -obj-$(CONFIG_SM501) += sm501.o -obj-$(CONFIG_TCX) += tcx.o -obj-$(CONFIG_CG3) += cg3.o +common-obj-$(CONFIG_PXA2XX) += pxa2xx_lcd.o +common-obj-$(CONFIG_RASPI) += bcm2835_fb.o +common-obj-$(CONFIG_SM501) += sm501.o +common-obj-$(CONFIG_TCX) += tcx.o +common-obj-$(CONFIG_CG3) += cg3.o obj-$(CONFIG_VGA) += vga.o @@ -53,7 +53,7 @@ virtio-gpu.o-cflags := $(VIRGL_CFLAGS) virtio-gpu.o-libs += $(VIRGL_LIBS) virtio-gpu-3d.o-cflags := $(VIRGL_CFLAGS) virtio-gpu-3d.o-libs += $(VIRGL_LIBS) -obj-$(CONFIG_DPCD) += dpcd.o -obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx_dp.o +common-obj-$(CONFIG_DPCD) += dpcd.o +common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx_dp.o -obj-$(CONFIG_ATI_VGA) += ati.o ati_2d.o ati_dbg.o +common-obj-$(CONFIG_ATI_VGA) += ati.o ati_2d.o ati_dbg.o diff --git a/hw/display/ati.c b/hw/display/ati.c index 35f49a591b..8f940eee22 100644 --- a/hw/display/ati.c +++ b/hw/display/ati.c @@ -50,6 +50,7 @@ static void ati_vga_switch_mode(ATIVGAState *s) s->mode = EXT_MODE; if (s->regs.crtc_gen_cntl & CRTC2_EN) { /* CRT controller enabled, use CRTC values */ + /* FIXME Should these be the same as VGA CRTC regs? */ uint32_t offs = s->regs.crtc_offset & 0x07ffffff; int stride = (s->regs.crtc_pitch & 0x7ff) * 8; int bpp = 0; @@ -89,7 +90,9 @@ static void ati_vga_switch_mode(ATIVGAState *s) DPRINTF("Switching to %dx%d %d %d @ %x\n", h, v, stride, bpp, offs); vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE); vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_DISABLED); - s->vga.big_endian_fb = false; + s->vga.big_endian_fb = (s->regs.config_cntl & APER_0_ENDIAN || + s->regs.config_cntl & APER_1_ENDIAN ? + true : false); /* reset VBE regs then set up mode */ s->vga.vbe_regs[VBE_DISPI_INDEX_XRES] = h; s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] = v; @@ -101,16 +104,23 @@ static void ati_vga_switch_mode(ATIVGAState *s) (s->regs.dac_cntl & DAC_8BIT_EN ? VBE_DISPI_8BIT_DAC : 0)); /* now set offset and stride after enable as that resets these */ if (stride) { + int bypp = DIV_ROUND_UP(bpp, BITS_PER_BYTE); + vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_VIRT_WIDTH); vbe_ioport_write_data(&s->vga, 0, stride); - if (offs % stride == 0) { - vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_Y_OFFSET); - vbe_ioport_write_data(&s->vga, 0, offs / stride); - } else { - /* FIXME what to do with this? */ - error_report("VGA offset is not multiple of pitch, " - "expect bad picture"); + stride *= bypp; + if (offs % stride) { + DPRINTF("CRTC offset is not multiple of pitch\n"); + vbe_ioport_write_index(&s->vga, 0, + VBE_DISPI_INDEX_X_OFFSET); + vbe_ioport_write_data(&s->vga, 0, offs % stride / bypp); } + vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_Y_OFFSET); + vbe_ioport_write_data(&s->vga, 0, offs / stride); + DPRINTF("VBE offset (%d,%d), vbe_start_addr=%x\n", + s->vga.vbe_regs[VBE_DISPI_INDEX_X_OFFSET], + s->vga.vbe_regs[VBE_DISPI_INDEX_Y_OFFSET], + s->vga.vbe_start_addr); } } } else { @@ -132,9 +142,8 @@ static void ati_cursor_define(ATIVGAState *s) return; /* Do not update cursor if locked or rendered by guest */ } /* FIXME handle cur_hv_offs correctly */ - src = s->vga.vram_ptr + (s->regs.crtc_offset & 0x07ffffff) + - s->regs.cur_offset - (s->regs.cur_hv_offs >> 16) - - (s->regs.cur_hv_offs & 0xffff) * 16; + src = s->vga.vram_ptr + s->regs.cur_offset - + (s->regs.cur_hv_offs >> 16) - (s->regs.cur_hv_offs & 0xffff) * 16; for (i = 0; i < 64; i++) { for (j = 0; j < 8; j++, idx++) { data[idx] = src[i * 16 + j]; @@ -190,8 +199,7 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y) return; } /* FIXME handle cur_hv_offs correctly */ - src = s->vga.vram_ptr + (s->regs.crtc_offset & 0x07ffffff) + - s->cursor_offset + (scr_y - vga->hw_cursor_y) * 16; + src = s->vga.vram_ptr + s->cursor_offset + (scr_y - vga->hw_cursor_y) * 16; dp = &dp[vga->hw_cursor_x]; h = ((s->regs.crtc_h_total_disp >> 16) + 1) * 8; for (i = 0; i < 8; i++) { @@ -207,7 +215,7 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y) } } else { color = (xbits & BIT(7) ? s->regs.cur_color1 : - s->regs.cur_color0) << 8 | 0xff; + s->regs.cur_color0) | 0xff000000; } if (vga->hw_cursor_x + i * 8 + j >= h) { return; /* end of screen, don't span to next line */ @@ -235,6 +243,21 @@ static uint64_t ati_i2c(bitbang_i2c_interface *i2c, uint64_t data, int base) return data; } +static void ati_vga_update_irq(ATIVGAState *s) +{ + pci_set_irq(&s->dev, !!(s->regs.gen_int_status & s->regs.gen_int_cntl)); +} + +static void ati_vga_vblank_irq(void *opaque) +{ + ATIVGAState *s = opaque; + + timer_mod(&s->vblank_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + NANOSECONDS_PER_SECOND / 60); + s->regs.gen_int_status |= CRTC_VBLANK_INT; + ati_vga_update_irq(s); +} + static inline uint64_t ati_reg_read_offs(uint32_t reg, int offs, unsigned int size) { @@ -275,6 +298,12 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size) addr - (BIOS_0_SCRATCH + i * 4), size); break; } + case GEN_INT_CNTL: + val = s->regs.gen_int_cntl; + break; + case GEN_INT_STATUS: + val = s->regs.gen_int_status; + break; case CRTC_GEN_CNTL ... CRTC_GEN_CNTL + 3: val = ati_reg_read_offs(s->regs.crtc_gen_cntl, addr - CRTC_GEN_CNTL, size); @@ -304,9 +333,27 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size) case PALETTE_DATA: val = vga_ioport_read(&s->vga, VGA_PEL_D); break; + case CNFG_CNTL: + val = s->regs.config_cntl; + break; case CNFG_MEMSIZE: val = s->vga.vram_size; break; + case CONFIG_APER_0_BASE: + case CONFIG_APER_1_BASE: + val = pci_default_read_config(&s->dev, + PCI_BASE_ADDRESS_0, size) & 0xfffffff0; + break; + case CONFIG_APER_SIZE: + val = s->vga.vram_size; + break; + case CONFIG_REG_1_BASE: + val = pci_default_read_config(&s->dev, + PCI_BASE_ADDRESS_2, size) & 0xfffffff0; + break; + case CONFIG_REG_APER_SIZE: + val = memory_region_size(&s->mm); + break; case MC_STATUS: val = 5; break; @@ -486,6 +533,21 @@ static void ati_mm_write(void *opaque, hwaddr addr, addr - (BIOS_0_SCRATCH + i * 4), data, size); break; } + case GEN_INT_CNTL: + s->regs.gen_int_cntl = data; + if (data & CRTC_VBLANK_INT) { + ati_vga_vblank_irq(s); + } else { + timer_del(&s->vblank_timer); + ati_vga_update_irq(s); + } + break; + case GEN_INT_STATUS: + data &= (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF ? + 0x000f040fUL : 0xfc080effUL); + s->regs.gen_int_status &= ~data; + ati_vga_update_irq(s); + break; case CRTC_GEN_CNTL ... CRTC_GEN_CNTL + 3: { uint32_t val = s->regs.crtc_gen_cntl; @@ -549,12 +611,15 @@ static void ati_mm_write(void *opaque, hwaddr addr, addr - GPIO_MONID, data, size); /* * Rage128p accesses DDC used to get EDID via these bits. - * Only touch i2c when write overlaps 3rd byte because some - * drivers access this reg via multiple partial writes and - * without this spurious bits would be sent. + * Because some drivers access this via multiple byte writes + * we have to be careful when we send bits to avoid spurious + * changes in bitbang_i2c state. So only do it when mask is set + * and either the enable bits are changed or output bits changed + * while enabled. */ if ((s->regs.gpio_monid & BIT(25)) && - addr <= GPIO_MONID + 2 && addr + size > GPIO_MONID + 2) { + ((addr <= GPIO_MONID + 2 && addr + size > GPIO_MONID + 2) || + (addr == GPIO_MONID && (s->regs.gpio_monid & 0x60000)))) { s->regs.gpio_monid = ati_i2c(&s->bbi2c, s->regs.gpio_monid, 1); } } @@ -580,6 +645,9 @@ static void ati_mm_write(void *opaque, hwaddr addr, data >>= 8; vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff); break; + case CNFG_CNTL: + s->regs.config_cntl = data; + break; case CRTC_H_TOTAL_DISP: s->regs.crtc_h_total_disp = data & 0x07ff07ff; break; @@ -870,12 +938,19 @@ static void ati_vga_realize(PCIDevice *dev, Error **errp) pci_register_bar(dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &vga->vram); pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io); pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mm); + + /* most interrupts are not yet emulated but MacOS needs at least VBlank */ + dev->config[PCI_INTERRUPT_PIN] = 1; + timer_init_ns(&s->vblank_timer, QEMU_CLOCK_VIRTUAL, ati_vga_vblank_irq, s); } static void ati_vga_reset(DeviceState *dev) { ATIVGAState *s = ATI_VGA(dev); + timer_del(&s->vblank_timer); + ati_vga_update_irq(s); + /* reset vga */ vga_common_reset(&s->vga); s->mode = VGA_MODE; @@ -885,6 +960,7 @@ static void ati_vga_exit(PCIDevice *dev) { ATIVGAState *s = ATI_VGA(dev); + timer_del(&s->vblank_timer); graphic_console_close(s->vga.con); } diff --git a/hw/display/ati_dbg.c b/hw/display/ati_dbg.c index 88b3a11315..0ebbd36f14 100644 --- a/hw/display/ati_dbg.c +++ b/hw/display/ati_dbg.c @@ -16,6 +16,7 @@ static struct ati_regdesc ati_reg_names[] = { {"BUS_CNTL", 0x0030}, {"BUS_CNTL1", 0x0034}, {"GEN_INT_CNTL", 0x0040}, + {"GEN_INT_STATUS", 0x0044}, {"CRTC_GEN_CNTL", 0x0050}, {"CRTC_EXT_CNTL", 0x0054}, {"DAC_CNTL", 0x0058}, @@ -23,11 +24,20 @@ static struct ati_regdesc ati_reg_names[] = { {"GPIO_DVI_DDC", 0x0064}, {"GPIO_MONID", 0x0068}, {"I2C_CNTL_1", 0x0094}, + {"AMCGPIO_MASK_MIR", 0x009c}, + {"AMCGPIO_A_MIR", 0x00a0}, + {"AMCGPIO_Y_MIR", 0x00a4}, + {"AMCGPIO_EN_MIR", 0x00a8}, {"PALETTE_INDEX", 0x00b0}, {"PALETTE_DATA", 0x00b4}, {"CNFG_CNTL", 0x00e0}, {"GEN_RESET_CNTL", 0x00f0}, {"CNFG_MEMSIZE", 0x00f8}, + {"CONFIG_APER_0_BASE", 0x0100}, + {"CONFIG_APER_1_BASE", 0x0104}, + {"CONFIG_APER_SIZE", 0x0108}, + {"CONFIG_REG_1_BASE", 0x010c}, + {"CONFIG_REG_APER_SIZE", 0x0110}, {"MEM_CNTL", 0x0140}, {"MC_FB_LOCATION", 0x0148}, {"MC_AGP_LOCATION", 0x014C}, diff --git a/hw/display/ati_int.h b/hw/display/ati_int.h index 31a1927b3e..2a16708e4f 100644 --- a/hw/display/ati_int.h +++ b/hw/display/ati_int.h @@ -9,6 +9,7 @@ #ifndef ATI_INT_H #define ATI_INT_H +#include "qemu/timer.h" #include "hw/pci/pci.h" #include "hw/i2c/bitbang_i2c.h" #include "vga_int.h" @@ -33,12 +34,15 @@ typedef struct ATIVGARegs { uint32_t mm_index; uint32_t bios_scratch[8]; + uint32_t gen_int_cntl; + uint32_t gen_int_status; uint32_t crtc_gen_cntl; uint32_t crtc_ext_cntl; uint32_t dac_cntl; uint32_t gpio_vga_ddc; uint32_t gpio_dvi_ddc; uint32_t gpio_monid; + uint32_t config_cntl; uint32_t crtc_h_total_disp; uint32_t crtc_h_sync_strt_wid; uint32_t crtc_v_total_disp; @@ -88,6 +92,7 @@ typedef struct ATIVGAState { uint16_t cursor_size; uint32_t cursor_offset; QEMUCursor *cursor; + QEMUTimer vblank_timer; bitbang_i2c_interface bbi2c; MemoryRegion io; MemoryRegion mm; diff --git a/hw/display/ati_regs.h b/hw/display/ati_regs.h index d7155c93d5..ebd37ee30d 100644 --- a/hw/display/ati_regs.h +++ b/hw/display/ati_regs.h @@ -34,6 +34,7 @@ #define BUS_CNTL 0x0030 #define BUS_CNTL1 0x0034 #define GEN_INT_CNTL 0x0040 +#define GEN_INT_STATUS 0x0044 #define CRTC_GEN_CNTL 0x0050 #define CRTC_EXT_CNTL 0x0054 #define DAC_CNTL 0x0058 @@ -41,11 +42,20 @@ #define GPIO_DVI_DDC 0x0064 #define GPIO_MONID 0x0068 #define I2C_CNTL_1 0x0094 +#define AMCGPIO_MASK_MIR 0x009c +#define AMCGPIO_A_MIR 0x00a0 +#define AMCGPIO_Y_MIR 0x00a4 +#define AMCGPIO_EN_MIR 0x00a8 #define PALETTE_INDEX 0x00b0 #define PALETTE_DATA 0x00b4 #define CNFG_CNTL 0x00e0 #define GEN_RESET_CNTL 0x00f0 #define CNFG_MEMSIZE 0x00f8 +#define CONFIG_APER_0_BASE 0x0100 +#define CONFIG_APER_1_BASE 0x0104 +#define CONFIG_APER_SIZE 0x0108 +#define CONFIG_REG_1_BASE 0x010c +#define CONFIG_REG_APER_SIZE 0x0110 #define MEM_CNTL 0x0140 #define MC_FB_LOCATION 0x0148 #define MC_AGP_LOCATION 0x014C @@ -307,7 +317,14 @@ #define XPLL_FB_DIV_MASK 0x0000FF00 #define X_MPLL_REF_DIV_MASK 0x000000FF +/* GEN_INT_CNTL) */ +#define CRTC_VBLANK_INT 0x00000001 +#define CRTC_VLINE_INT 0x00000002 +#define CRTC_VSYNC_INT 0x00000004 + /* Config control values (CONFIG_CNTL) */ +#define APER_0_ENDIAN 0x00000003 +#define APER_1_ENDIAN 0x0000000c #define CFG_VGA_IO_DIS 0x00000400 /* CRTC control values (CRTC_GEN_CNTL) */ diff --git a/hw/display/sm501.c b/hw/display/sm501.c index d9e5762e36..1f33c87e65 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -28,7 +28,6 @@ #include "qapi/error.h" #include "qemu/log.h" #include "qemu/module.h" -#include "cpu.h" #include "hw/char/serial.h" #include "ui/console.h" #include "hw/sysbus.h" diff --git a/hw/dma/omap_dma.c b/hw/dma/omap_dma.c index eab83c5c3a..6677237d42 100644 --- a/hw/dma/omap_dma.c +++ b/hw/dma/omap_dma.c @@ -1531,8 +1531,8 @@ static void omap_dma_write(void *opaque, hwaddr addr, case 0x404 ... 0x4fe: if (s->model <= omap_dma_3_1) break; + /* fall through */ case 0x400: - /* Fall through. */ if (omap_dma_sys_write(s, addr, value)) break; return; diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 5b0ec1b89e..034e413fd0 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -27,7 +27,7 @@ #include "qemu/bitmap.h" #include "qemu/error-report.h" #include "hw/pci/pci.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "target/i386/cpu.h" #include "hw/misc/pvpanic.h" #include "hw/timer/hpet.h" diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 697c33606a..c14ed86439 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -76,7 +76,7 @@ #include "qapi/error.h" #include "qapi/qapi-visit-common.h" #include "qapi/visitor.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/nmi.h" #include "hw/usb.h" #include "hw/i386/intel_iommu.h" diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index a70cf0aafc..2362675149 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -312,7 +312,7 @@ else { * pc_compat_*() functions that run on machine-init time and * change global QEMU state are deprecated. Please don't create * one, and implement any pc-*-2.4 (and newer) compat code in - * HW_COMPAT_*, PC_COMPAT_*, or * pc_*_machine_options(). + * hw_compat_*, pc_compat_*, or * pc_*_machine_options(). */ static void pc_compat_2_3_fn(MachineState *machine) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 7af591daac..1d7da7baa2 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -23,7 +23,7 @@ #include "hw/sysbus.h" #include "gic_internal.h" #include "qapi/error.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "qemu/log.h" #include "qemu/module.h" #include "trace.h" diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c index 8f5f4c8e94..f0c551d43f 100644 --- a/hw/intc/arm_gicv3_common.c +++ b/hw/intc/arm_gicv3_common.c @@ -24,7 +24,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu/module.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/intc/arm_gicv3_common.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c index 573428eca1..87da9ff99c 100644 --- a/hw/ipmi/ipmi_bmc_extern.c +++ b/hw/ipmi/ipmi_bmc_extern.c @@ -177,8 +177,7 @@ static void addchar(IPMIBmcExtern *ibe, unsigned char ch) ibe->outbuf[ibe->outlen] = VM_ESCAPE_CHAR; ibe->outlen++; ch |= 0x10; - /* No break */ - + /* fall through */ default: ibe->outbuf[ibe->outlen] = ch; ibe->outlen++; diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index eec9eb31c1..17c292e306 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -49,7 +49,7 @@ #include "exec/address-spaces.h" #include "sysemu/runstate.h" #include "sysemu/sysemu.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/nvram/fw_cfg.h" #include "qemu/cutils.h" diff --git a/hw/misc/imx6_src.c b/hw/misc/imx6_src.c index 8ab18967b5..dd99cc7acf 100644 --- a/hw/misc/imx6_src.c +++ b/hw/misc/imx6_src.c @@ -16,7 +16,7 @@ #include "qemu/main-loop.h" #include "qemu/module.h" #include "arm-powerctl.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #ifndef DEBUG_IMX6_SRC #define DEBUG_IMX6_SRC 0 diff --git a/hw/net/e1000.c b/hw/net/e1000.c index 8ae4e08f1e..a73f8d404e 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -1608,7 +1608,7 @@ static const VMStateDescription vmstate_e1000 = { /* * EEPROM contents documented in Tables 5-2 and 5-3, pp. 98-102. - * Note: A valid DevId will be inserted during pci_e1000_init(). + * Note: A valid DevId will be inserted during pci_e1000_realize(). */ static const uint16_t e1000_eeprom_template[64] = { 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 64fc2255cc..baedadf20b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -49,7 +49,7 @@ #include "mmu-hash64.h" #include "mmu-book3s-v3.h" #include "cpu-models.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/boards.h" #include "hw/ppc/ppc.h" diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index 163a6cd25b..0e4c19523a 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -314,7 +314,7 @@ rtas_event_log_to_source(SpaprMachineState *spapr, int log_type) g_assert(source->enabled); break; } - /* fall back to epow for legacy hotplug interrupt source */ + /* fall through back to epow for legacy hotplug interrupt source */ case RTAS_LOG_TYPE_EPOW: source = spapr_event_sources_get_source(spapr->event_sources, EVENT_CLASS_EPOW); diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c index 75f1867174..4c634c83b1 100644 --- a/hw/timer/a9gtimer.c +++ b/hw/timer/a9gtimer.c @@ -31,7 +31,7 @@ #include "qemu/bitops.h" #include "qemu/log.h" #include "qemu/module.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #ifndef A9_GTIMER_ERR_DEBUG #define A9_GTIMER_ERR_DEBUG 0 diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c index 983e61847e..9f63abef10 100644 --- a/hw/timer/arm_mptimer.c +++ b/hw/timer/arm_mptimer.c @@ -29,7 +29,7 @@ #include "qapi/error.h" #include "qemu/main-loop.h" #include "qemu/module.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define PTIMER_POLICY \ (PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD | \ diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 9ca7b87a80..56ab2f457f 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -1838,6 +1838,9 @@ static int ehci_state_fetchqtd(EHCIQueue *q) ehci_set_state(q->ehci, q->async, EST_EXECUTING); break; } + } else if (q->dev == NULL) { + ehci_trace_guest_bug(q->ehci, "no device attached to queue"); + ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); } else { p = ehci_alloc_packet(q); p->qtdaddr = q->qtdaddr; diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index f698224c8a..f578264948 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -2543,6 +2543,9 @@ static void xhci_process_commands(XHCIState *xhci) case CR_GET_PORT_BANDWIDTH: event.ccode = xhci_get_port_bandwidth(xhci, trb.parameter); break; + case CR_NOOP: + event.ccode = CC_SUCCESS; + break; case CR_VENDOR_NEC_FIRMWARE_REVISION: if (xhci->nec_quirks) { event.type = 48; /* NEC reply */ diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index fc9fe0c00f..e0f5ca6f81 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -819,8 +819,8 @@ static void usbredir_handle_interrupt_in_data(USBRedirDevice *dev, USBPacket *p, uint8_t ep) { /* Input interrupt endpoint, buffered packet input */ - struct buf_packet *intp; - int status, len; + struct buf_packet *intp, *intp_to_free; + int status, len, sum; if (!dev->endpoint[EP2I(ep)].interrupt_started && !dev->endpoint[EP2I(ep)].interrupt_error) { @@ -839,9 +839,17 @@ static void usbredir_handle_interrupt_in_data(USBRedirDevice *dev, dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0; } - intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq); + /* check for completed interrupt message (with all fragments) */ + sum = 0; + QTAILQ_FOREACH(intp, &dev->endpoint[EP2I(ep)].bufpq, next) { + sum += intp->len; + if (intp->len < dev->endpoint[EP2I(ep)].max_packet_size || + sum >= p->iov.size) + break; + } + if (intp == NULL) { - DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep); + DPRINTF2("interrupt-token-in ep %02X, no intp, buffered %d\n", ep, sum); /* Check interrupt_error for stream errors */ status = dev->endpoint[EP2I(ep)].interrupt_error; dev->endpoint[EP2I(ep)].interrupt_error = 0; @@ -852,18 +860,42 @@ static void usbredir_handle_interrupt_in_data(USBRedirDevice *dev, } return; } - DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep, - intp->status, intp->len); - status = intp->status; - len = intp->len; - if (len > p->iov.size) { - ERROR("received int data is larger then packet ep %02X\n", ep); - len = p->iov.size; - status = usb_redir_babble; + /* copy of completed interrupt message */ + sum = 0; + status = usb_redir_success; + intp_to_free = NULL; + QTAILQ_FOREACH(intp, &dev->endpoint[EP2I(ep)].bufpq, next) { + if (intp_to_free) { + bufp_free(dev, intp_to_free, ep); + } + DPRINTF("interrupt-token-in ep %02X fragment status %d len %d\n", ep, + intp->status, intp->len); + + sum += intp->len; + len = intp->len; + if (status == usb_redir_success) { + status = intp->status; + } + if (sum > p->iov.size) { + ERROR("received int data is larger then packet ep %02X\n", ep); + len -= (sum - p->iov.size); + sum = p->iov.size; + status = usb_redir_babble; + } + + usb_packet_copy(p, intp->data, len); + + intp_to_free = intp; + if (intp->len < dev->endpoint[EP2I(ep)].max_packet_size || + sum >= p->iov.size) + break; + } + if (intp_to_free) { + bufp_free(dev, intp_to_free, ep); } - usb_packet_copy(p, intp->data, len); - bufp_free(dev, intp, ep); + DPRINTF("interrupt-token-in ep %02X summary status %d len %d\n", ep, + status, sum); usbredir_handle_status(dev, p, status); } @@ -1499,6 +1531,11 @@ static void usbredir_check_bulk_receiving(USBRedirDevice *dev) for (i = EP2I(USB_DIR_IN); i < MAX_ENDPOINTS; i++) { dev->endpoint[i].bulk_receiving_enabled = 0; } + + if (dev->interface_info.interface_count == NO_INTERFACE_INFO) { + return; + } + for (i = 0; i < dev->interface_info.interface_count; i++) { quirks = usb_get_quirks(dev->device_info.vendor_id, dev->device_info.product_id, @@ -2036,22 +2073,17 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id, } if (ep & USB_DIR_IN) { - bool q_was_empty; - if (dev->endpoint[EP2I(ep)].interrupt_started == 0) { DPRINTF("received int packet while not started ep %02X\n", ep); free(data); return; } - q_was_empty = QTAILQ_EMPTY(&dev->endpoint[EP2I(ep)].bufpq); - /* bufp_alloc also adds the packet to the ep queue */ bufp_alloc(dev, data, data_len, interrupt_packet->status, ep, data); - if (q_was_empty) { - usb_wakeup(usb_ep_get(&dev->dev, USB_TOKEN_IN, ep & 0x0f), 0); - } + /* insufficient data solved with USB_RET_NAK */ + usb_wakeup(usb_ep_get(&dev->dev, USB_TOKEN_IN, ep & 0x0f), 0); } else { /* * We report output interrupt packets as completed directly upon diff --git a/include/crypto/block.h b/include/crypto/block.h index fe12899831..d49d2c2da9 100644 --- a/include/crypto/block.h +++ b/include/crypto/block.h @@ -268,4 +268,6 @@ uint64_t qcrypto_block_get_sector_size(QCryptoBlock *block); */ void qcrypto_block_free(QCryptoBlock *block); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoBlock, qcrypto_block_free) + #endif /* QCRYPTO_BLOCK_H */ diff --git a/include/crypto/cipher.h b/include/crypto/cipher.h index cac90b410c..5928e5ecc7 100644 --- a/include/crypto/cipher.h +++ b/include/crypto/cipher.h @@ -170,6 +170,8 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg, */ void qcrypto_cipher_free(QCryptoCipher *cipher); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoCipher, qcrypto_cipher_free) + /** * qcrypto_cipher_encrypt: * @cipher: the cipher object diff --git a/include/crypto/hmac.h b/include/crypto/hmac.h index aa3c97a2ff..ad4d778416 100644 --- a/include/crypto/hmac.h +++ b/include/crypto/hmac.h @@ -65,6 +65,8 @@ QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg, */ void qcrypto_hmac_free(QCryptoHmac *hmac); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoHmac, qcrypto_hmac_free) + /** * qcrypto_hmac_bytesv: * @hmac: the hmac object diff --git a/include/crypto/ivgen.h b/include/crypto/ivgen.h index 9b4a62f7bb..e41521519c 100644 --- a/include/crypto/ivgen.h +++ b/include/crypto/ivgen.h @@ -203,4 +203,6 @@ QCryptoHashAlgorithm qcrypto_ivgen_get_hash(QCryptoIVGen *ivgen); */ void qcrypto_ivgen_free(QCryptoIVGen *ivgen); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoIVGen, qcrypto_ivgen_free) + #endif /* QCRYPTO_IVGEN_H */ diff --git a/include/crypto/tlssession.h b/include/crypto/tlssession.h index 816300cdcc..e01e1a9dc2 100644 --- a/include/crypto/tlssession.h +++ b/include/crypto/tlssession.h @@ -160,6 +160,8 @@ QCryptoTLSSession *qcrypto_tls_session_new(QCryptoTLSCreds *creds, */ void qcrypto_tls_session_free(QCryptoTLSSession *sess); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoTLSSession, qcrypto_tls_session_free) + /** * qcrypto_tls_session_check_credentials: * @sess: the TLS session object diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 536ea58f81..8323094648 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -22,7 +22,7 @@ #include "exec/cpu-common.h" #include "exec/memory.h" #include "qemu/thread.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "qemu/rcu.h" #define EXCP_INTERRUPT 0x10000 /* async interruption */ diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 57a9a4ffd9..189709b6de 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -32,7 +32,7 @@ #include "exec/hwaddr.h" #endif #include "exec/memattrs.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "cpu-param.h" diff --git a/include/exec/log.h b/include/exec/log.h index de067f173b..e2cfd436e6 100644 --- a/include/exec/log.h +++ b/include/exec/log.h @@ -2,7 +2,7 @@ #define QEMU_EXEC_LOG_H #include "qemu/log.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "disas/disas.h" /* cpu_dump_state() logging functions: */ diff --git a/include/glib-compat.h b/include/glib-compat.h index 1291628e09..0b0ec76299 100644 --- a/include/glib-compat.h +++ b/include/glib-compat.h @@ -19,12 +19,12 @@ /* Ask for warnings for anything that was marked deprecated in * the defined version, or before. It is a candidate for rewrite. */ -#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_40 +#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_48 /* Ask for warnings if code tries to use function that did not * exist in the defined version. These risk breaking builds */ -#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_40 +#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_48 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" @@ -63,26 +63,6 @@ * without generating warnings. */ -static inline gboolean g_strv_contains_qemu(const gchar *const *strv, - const gchar *str) -{ -#if GLIB_CHECK_VERSION(2, 44, 0) - return g_strv_contains(strv, str); -#else - g_return_val_if_fail(strv != NULL, FALSE); - g_return_val_if_fail(str != NULL, FALSE); - - for (; *strv != NULL; strv++) { - if (g_str_equal(str, *strv)) { - return TRUE; - } - } - - return FALSE; -#endif -} -#define g_strv_contains(a, b) g_strv_contains_qemu(a, b) - #if defined(_WIN32) && !GLIB_CHECK_VERSION(2, 50, 0) /* * g_poll has a problem on Windows when using @@ -92,24 +72,6 @@ static inline gboolean g_strv_contains_qemu(const gchar *const *strv, gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout); #endif - -#ifndef g_assert_cmpmem -#define g_assert_cmpmem(m1, l1, m2, l2) \ - do { \ - gconstpointer __m1 = m1, __m2 = m2; \ - int __l1 = l1, __l2 = l2; \ - if (__l1 != __l2) { \ - g_assertion_message_cmpnum( \ - G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ - #l1 " (len(" #m1 ")) == " #l2 " (len(" #m2 "))", __l1, "==", \ - __l2, 'i'); \ - } else if (memcmp(__m1, __m2, __l1) != 0) { \ - g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ - "assertion failed (" #m1 " == " #m2 ")"); \ - } \ - } while (0) -#endif - #pragma GCC diagnostic pop #endif diff --git a/include/hw/boards.h b/include/hw/boards.h index 60d69217b4..ced86109ec 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -9,7 +9,7 @@ #include "qapi/qapi-types-machine.h" #include "qemu/module.h" #include "qom/object.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" /** * memory_region_allocate_system_memory - Allocate a board's main memory diff --git a/include/qom/cpu.h b/include/hw/core/cpu.h index 77fca95a40..77fca95a40 100644 --- a/include/qom/cpu.h +++ b/include/hw/core/cpu.h diff --git a/include/hw/ppc/openpic.h b/include/hw/ppc/openpic.h index ec16897bfb..db0d29e6c2 100644 --- a/include/hw/ppc/openpic.h +++ b/include/hw/ppc/openpic.h @@ -2,7 +2,7 @@ #define OPENPIC_H #include "hw/sysbus.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define MAX_CPU 32 #define MAX_MSI 8 diff --git a/include/qemu/module.h b/include/qemu/module.h index db3065381d..65ba596e46 100644 --- a/include/qemu/module.h +++ b/include/qemu/module.h @@ -65,6 +65,6 @@ void register_module_init(void (*fn)(void), module_init_type type); void register_dso_module_init(void (*fn)(void), module_init_type type); void module_call_init(module_init_type type); -void module_load_one(const char *prefix, const char *lib_name); +bool module_load_one(const char *prefix, const char *lib_name); #endif diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h index d2ddfb5ad0..0ec2372477 100644 --- a/include/sysemu/hw_accel.h +++ b/include/sysemu/hw_accel.h @@ -11,7 +11,7 @@ #ifndef QEMU_HW_ACCEL_H #define QEMU_HW_ACCEL_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "sysemu/hax.h" #include "sysemu/kvm.h" #include "sysemu/whpx.h" diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index c8ea412f62..909bcd77cf 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -15,7 +15,7 @@ #define QEMU_KVM_H #include "qemu/queue.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "exec/memattrs.h" #ifdef NEED_CPU_H @@ -136,6 +136,7 @@ static gpointer qio_task_thread_worker(gpointer opaque) qio_task_thread_result, task, NULL); g_source_attach(task->thread->completion, task->thread->context); + g_source_unref(task->thread->completion); trace_qio_task_thread_source_attach(task, task->thread->completion); qemu_cond_signal(&task->thread_cond); @@ -217,7 +217,6 @@ struct FlatRange { bool romd_mode; bool readonly; bool nonvolatile; - int has_coalesced_range; }; #define FOR_EACH_FLAT_RANGE(var, view) \ @@ -654,7 +653,6 @@ static void render_memory_region(FlatView *view, fr.romd_mode = mr->romd_mode; fr.readonly = readonly; fr.nonvolatile = nonvolatile; - fr.has_coalesced_range = 0; /* Render the region itself into any gaps left by the current view. */ for (i = 0; i < view->nr && int128_nz(remain); ++i) { @@ -855,46 +853,55 @@ static void address_space_update_ioeventfds(AddressSpace *as) flatview_unref(view); } -static void flat_range_coalesced_io_del(FlatRange *fr, AddressSpace *as) +/* + * Notify the memory listeners about the coalesced IO change events of + * range `cmr'. Only the part that has intersection of the specified + * FlatRange will be sent. + */ +static void flat_range_coalesced_io_notify(FlatRange *fr, AddressSpace *as, + CoalescedMemoryRange *cmr, bool add) { - if (!fr->has_coalesced_range) { + AddrRange tmp; + + tmp = addrrange_shift(cmr->addr, + int128_sub(fr->addr.start, + int128_make64(fr->offset_in_region))); + if (!addrrange_intersects(tmp, fr->addr)) { return; } + tmp = addrrange_intersection(tmp, fr->addr); - if (--fr->has_coalesced_range > 0) { - return; + if (add) { + MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, coalesced_io_add, + int128_get64(tmp.start), + int128_get64(tmp.size)); + } else { + MEMORY_LISTENER_UPDATE_REGION(fr, as, Reverse, coalesced_io_del, + int128_get64(tmp.start), + int128_get64(tmp.size)); } +} - MEMORY_LISTENER_UPDATE_REGION(fr, as, Reverse, coalesced_io_del, - int128_get64(fr->addr.start), - int128_get64(fr->addr.size)); +static void flat_range_coalesced_io_del(FlatRange *fr, AddressSpace *as) +{ + CoalescedMemoryRange *cmr; + + QTAILQ_FOREACH(cmr, &fr->mr->coalesced, link) { + flat_range_coalesced_io_notify(fr, as, cmr, false); + } } static void flat_range_coalesced_io_add(FlatRange *fr, AddressSpace *as) { MemoryRegion *mr = fr->mr; CoalescedMemoryRange *cmr; - AddrRange tmp; if (QTAILQ_EMPTY(&mr->coalesced)) { return; } - if (fr->has_coalesced_range++) { - return; - } - QTAILQ_FOREACH(cmr, &mr->coalesced, link) { - tmp = addrrange_shift(cmr->addr, - int128_sub(fr->addr.start, - int128_make64(fr->offset_in_region))); - if (!addrrange_intersects(tmp, fr->addr)) { - continue; - } - tmp = addrrange_intersection(tmp, fr->addr); - MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, coalesced_io_add, - int128_get64(tmp.start), - int128_get64(tmp.size)); + flat_range_coalesced_io_notify(fr, as, cmr, true); } } @@ -2236,27 +2243,26 @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp qemu_ram_resize(mr->ram_block, newsize, errp); } -static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as) +/* + * Call proper memory listeners about the change on the newly + * added/removed CoalescedMemoryRange. + */ +static void memory_region_update_coalesced_range(MemoryRegion *mr, + CoalescedMemoryRange *cmr, + bool add) { + AddressSpace *as; FlatView *view; FlatRange *fr; - view = address_space_get_flatview(as); - FOR_EACH_FLAT_RANGE(fr, view) { - if (fr->mr == mr) { - flat_range_coalesced_io_del(fr, as); - flat_range_coalesced_io_add(fr, as); - } - } - flatview_unref(view); -} - -static void memory_region_update_coalesced_range(MemoryRegion *mr) -{ - AddressSpace *as; - QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { - memory_region_update_coalesced_range_as(mr, as); + view = address_space_get_flatview(as); + FOR_EACH_FLAT_RANGE(fr, view) { + if (fr->mr == mr) { + flat_range_coalesced_io_notify(fr, as, cmr, add); + } + } + flatview_unref(view); } } @@ -2274,14 +2280,17 @@ void memory_region_add_coalescing(MemoryRegion *mr, cmr->addr = addrrange_make(int128_make64(offset), int128_make64(size)); QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link); - memory_region_update_coalesced_range(mr); + memory_region_update_coalesced_range(mr, cmr, true); memory_region_set_flush_coalesced(mr); } void memory_region_clear_coalescing(MemoryRegion *mr) { CoalescedMemoryRange *cmr; - bool updated = false; + + if (QTAILQ_EMPTY(&mr->coalesced)) { + return; + } qemu_flush_coalesced_mmio_buffer(); mr->flush_coalesced_mmio = false; @@ -2289,12 +2298,8 @@ void memory_region_clear_coalescing(MemoryRegion *mr) while (!QTAILQ_EMPTY(&mr->coalesced)) { cmr = QTAILQ_FIRST(&mr->coalesced); QTAILQ_REMOVE(&mr->coalesced, cmr, link); + memory_region_update_coalesced_range(mr, cmr, false); g_free(cmr); - updated = true; - } - - if (updated) { - memory_region_update_coalesced_range(mr); } } diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index e4d4043a3b..b2551c16d1 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -25,7 +25,6 @@ #include "qemu/timer.h" #include "qemu/sockets.h" #include "monitor/monitor-internal.h" -#include "monitor/qdev.h" #include "qapi/error.h" #include "qapi/clone-visitor.h" #include "qapi/opts-visitor.h" @@ -35,7 +34,6 @@ #include "qapi/qapi-commands-migration.h" #include "qapi/qapi-commands-misc.h" #include "qapi/qapi-commands-net.h" -#include "qapi/qapi-commands-qdev.h" #include "qapi/qapi-commands-rocker.h" #include "qapi/qapi-commands-run-state.h" #include "qapi/qapi-commands-tpm.h" @@ -2167,23 +2165,6 @@ void hmp_migrate(Monitor *mon, const QDict *qdict) } } -void hmp_device_add(Monitor *mon, const QDict *qdict) -{ - Error *err = NULL; - - qmp_device_add((QDict *)qdict, NULL, &err); - hmp_handle_error(mon, &err); -} - -void hmp_device_del(Monitor *mon, const QDict *qdict) -{ - const char *id = qdict_get_str(qdict, "id"); - Error *err = NULL; - - qmp_device_del(id, &err); - hmp_handle_error(mon, &err); -} - void hmp_netdev_add(Monitor *mon, const QDict *qdict) { Error *err = NULL; diff --git a/monitor/qmp.c b/monitor/qmp.c index e1b196217d..9d9e5d8b27 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -97,7 +97,7 @@ void qmp_send_response(MonitorQMP *mon, const QDict *rsp) } /* - * Emit QMP response @rsp with ID @id to @mon. + * Emit QMP response @rsp to @mon. * Null @rsp can only happen for commands with QCO_NO_SUCCESS_RESP. * Nothing is emitted then. */ diff --git a/qapi/common.json b/qapi/common.json index 3d4e8de1e0..7b9cbcd97b 100644 --- a/qapi/common.json +++ b/qapi/common.json @@ -144,28 +144,3 @@ ## { 'enum': 'PCIELinkWidth', 'data': [ '1', '2', '4', '8', '12', '16', '32' ] } - -## -# @SysEmuTarget: -# -# The comprehensive enumeration of QEMU system emulation ("softmmu") -# targets. Run "./configure --help" in the project root directory, and -# look for the *-softmmu targets near the "--target-list" option. The -# individual target constants are not documented here, for the time -# being. -# -# Notes: The resulting QMP strings can be appended to the "qemu-system-" -# prefix to produce the corresponding QEMU executable name. This -# is true even for "qemu-system-x86_64". -# -# ppcemb: dropped in 3.1 -# -# Since: 3.0 -## -{ 'enum' : 'SysEmuTarget', - 'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32', - 'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64', - 'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc', - 'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4', - 'sh4eb', 'sparc', 'sparc64', 'tricore', 'unicore32', - 'x86_64', 'xtensa', 'xtensaeb' ] } diff --git a/qapi/machine.json b/qapi/machine.json index 6db8a7e2ec..de5c742d72 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -7,7 +7,30 @@ # = Machines ## -{ 'include': 'common.json' } +## +# @SysEmuTarget: +# +# The comprehensive enumeration of QEMU system emulation ("softmmu") +# targets. Run "./configure --help" in the project root directory, and +# look for the *-softmmu targets near the "--target-list" option. The +# individual target constants are not documented here, for the time +# being. +# +# Notes: The resulting QMP strings can be appended to the "qemu-system-" +# prefix to produce the corresponding QEMU executable name. This +# is true even for "qemu-system-x86_64". +# +# ppcemb: dropped in 3.1 +# +# Since: 3.0 +## +{ 'enum' : 'SysEmuTarget', + 'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32', + 'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64', + 'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc', + 'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4', + 'sh4eb', 'sparc', 'sparc64', 'tricore', 'unicore32', + 'x86_64', 'xtensa', 'xtensaeb' ] } ## # @CpuInfoArch: @@ -369,6 +392,29 @@ { 'command': 'query-current-machine', 'returns': 'CurrentMachineParams' } ## +# @TargetInfo: +# +# Information describing the QEMU target. +# +# @arch: the target architecture +# +# Since: 1.2.0 +## +{ 'struct': 'TargetInfo', + 'data': { 'arch': 'SysEmuTarget' } } + +## +# @query-target: +# +# Return information about the target for this QEMU +# +# Returns: TargetInfo +# +# Since: 1.2.0 +## +{ 'command': 'query-target', 'returns': 'TargetInfo' } + +## # @NumaOptionsType: # # @node: NUMA nodes configuration diff --git a/qapi/misc.json b/qapi/misc.json index a7fba7230c..6bd11f50e6 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -1342,29 +1342,6 @@ { 'command': 'query-fdsets', 'returns': ['FdsetInfo'] } ## -# @TargetInfo: -# -# Information describing the QEMU target. -# -# @arch: the target architecture -# -# Since: 1.2.0 -## -{ 'struct': 'TargetInfo', - 'data': { 'arch': 'SysEmuTarget' } } - -## -# @query-target: -# -# Return information about the target for this QEMU -# -# Returns: TargetInfo -# -# Since: 1.2.0 -## -{ 'command': 'query-target', 'returns': 'TargetInfo' } - -## # @AcpiTableOptions: # # Specify an ACPI table on the command line to load. diff --git a/qapi/ui.json b/qapi/ui.json index 59e412139a..e04525d8b4 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -1025,7 +1025,8 @@ # ## { 'enum': 'GrabToggleKeys', - 'data': [ 'ctrl-ctrl', 'alt-alt', 'meta-meta', 'scrolllock', 'ctrl-scrolllock' ] } + 'data': [ 'ctrl-ctrl', 'alt-alt', 'shift-shift','meta-meta', 'scrolllock', + 'ctrl-scrolllock' ] } ## # @DisplayGTK: diff --git a/qdev-monitor.c b/qdev-monitor.c index a0003bf2a9..8fe5c2cad2 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -19,6 +19,7 @@ #include "qemu/osdep.h" #include "hw/sysbus.h" +#include "monitor/hmp.h" #include "monitor/monitor.h" #include "monitor/qdev.h" #include "sysemu/arch_init.h" @@ -844,6 +845,23 @@ void qmp_device_del(const char *id, Error **errp) } } +void hmp_device_add(Monitor *mon, const QDict *qdict) +{ + Error *err = NULL; + + qmp_device_add((QDict *)qdict, NULL, &err); + hmp_handle_error(mon, &err); +} + +void hmp_device_del(Monitor *mon, const QDict *qdict) +{ + const char *id = qdict_get_str(qdict, "id"); + Error *err = NULL; + + qmp_device_del(id, &err); + hmp_handle_error(mon, &err); +} + BlockBackend *blk_by_qdev_id(const char *id, Error **errp) { DeviceState *dev; diff --git a/qemu-options.hx b/qemu-options.hx index a308e5f5aa..ea0638e92d 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1436,12 +1436,15 @@ STEXI ETEXI DEF("usb", 0, QEMU_OPTION_usb, - "-usb enable the USB driver (if it is not used by default yet)\n", + "-usb enable on-board USB host controller (if not enabled by default)\n", QEMU_ARCH_ALL) STEXI @item -usb @findex -usb -Enable the USB driver (if it is not used by default yet). +Enable USB emulation on machine types with an on-board USB host controller (if +not enabled by default). Note that on-board USB host controllers may not +support USB 3.0. In this case @option{-device qemu-xhci} can be used instead +on machines with PCI. ETEXI DEF("usbdevice", HAS_ARG, QEMU_OPTION_usbdevice, diff --git a/qobject/json-parser.c b/qobject/json-parser.c index 7d23e12e33..d083810d37 100644 --- a/qobject/json-parser.c +++ b/qobject/json-parser.c @@ -519,8 +519,8 @@ static QObject *parse_literal(JSONParserContext *ctxt) } assert(ret == -ERANGE); } - /* fall through to JSON_FLOAT */ } + /* fall through to JSON_FLOAT */ case JSON_FLOAT: /* FIXME dependent on locale; a pervasive issue in QEMU */ /* FIXME our lexer matches RFC 8259 in forbidding Inf or NaN, diff --git a/qom/Makefile.objs b/qom/Makefile.objs index aae478fc21..f9d77350ac 100644 --- a/qom/Makefile.objs +++ b/qom/Makefile.objs @@ -1,5 +1,4 @@ qom-obj-y = object.o container.o qom-qobject.o qom-obj-y += object_interfaces.o -common-obj-y = cpu.o common-obj-$(CONFIG_SOFTMMU) += qom-hmp-cmds.o qom-qmp-cmds.o @@ -661,6 +661,15 @@ static void qtest_process_command(CharBackend *chr, gchar **words) qtest_send_prefix(chr); qtest_sendf(chr, "OK %"PRIi64"\n", (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); + } else if (strcmp(words[0], "module_load") == 0) { + g_assert(words[1] && words[2]); + + qtest_send_prefix(chr); + if (module_load_one(words[1], words[2])) { + qtest_sendf(chr, "OK\n"); + } else { + qtest_sendf(chr, "FAIL\n"); + } } else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) { int64_t ns; int ret; diff --git a/scripts/minikconf.py b/scripts/minikconf.py index 3109a81db7..40ae1989e1 100644 --- a/scripts/minikconf.py +++ b/scripts/minikconf.py @@ -702,8 +702,8 @@ if __name__ == '__main__': config = data.compute_config() for key in sorted(config.keys()): - if key not in external_vars: - print ('CONFIG_%s=%s' % (key, ('y' if config[key] else 'n'))) + if key not in external_vars and config[key]: + print ('CONFIG_%s=y' % key) deps = open(argv[2], 'w') for fname in data.previously_included: diff --git a/target/alpha/cpu-qom.h b/target/alpha/cpu-qom.h index bae4945344..6f0a0adb9e 100644 --- a/target/alpha/cpu-qom.h +++ b/target/alpha/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_ALPHA_CPU_QOM_H #define QEMU_ALPHA_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_ALPHA_CPU "alpha-cpu" diff --git a/target/arm/cpu-qom.h b/target/arm/cpu-qom.h index 2049fa9612..7f5b244bde 100644 --- a/target/arm/cpu-qom.h +++ b/target/arm/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_ARM_CPU_QOM_H #define QEMU_ARM_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" struct arm_boot_info; diff --git a/target/cris/cpu-qom.h b/target/cris/cpu-qom.h index 7556e9f97e..308c1f95bd 100644 --- a/target/cris/cpu-qom.h +++ b/target/cris/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_CRIS_CPU_QOM_H #define QEMU_CRIS_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_CRIS_CPU "cris-cpu" diff --git a/target/hppa/cpu-qom.h b/target/hppa/cpu-qom.h index 9084e4701d..6367dc4793 100644 --- a/target/hppa/cpu-qom.h +++ b/target/hppa/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_HPPA_CPU_QOM_H #define QEMU_HPPA_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_HPPA_CPU "hppa-cpu" diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c index 89241c31e7..462747baf8 100644 --- a/target/hppa/int_helper.c +++ b/target/hppa/int_helper.c @@ -22,7 +22,7 @@ #include "qemu/log.h" #include "cpu.h" #include "exec/helper-proto.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #ifndef CONFIG_USER_ONLY static void eval_interrupt(HPPACPU *cpu) diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c index b12c5b5054..5a465db0dd 100644 --- a/target/hppa/mem_helper.c +++ b/target/hppa/mem_helper.c @@ -21,7 +21,7 @@ #include "cpu.h" #include "exec/exec-all.h" #include "exec/helper-proto.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "trace.h" #ifdef CONFIG_USER_ONLY diff --git a/target/i386/cpu-qom.h b/target/i386/cpu-qom.h index 1a52f02a4c..0efab2fc67 100644 --- a/target/i386/cpu-qom.h +++ b/target/i386/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_I386_CPU_QOM_H #define QEMU_I386_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "qemu/notify.h" #ifdef TARGET_X86_64 diff --git a/target/lm32/cpu-qom.h b/target/lm32/cpu-qom.h index b423d2564b..dc9ac9ac9f 100644 --- a/target/lm32/cpu-qom.h +++ b/target/lm32/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_LM32_CPU_QOM_H #define QEMU_LM32_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_LM32_CPU "lm32-cpu" diff --git a/target/m68k/cpu-qom.h b/target/m68k/cpu-qom.h index 0c157251a2..b56da8a213 100644 --- a/target/m68k/cpu-qom.h +++ b/target/m68k/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_M68K_CPU_QOM_H #define QEMU_M68K_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_M68K_CPU "m68k-cpu" diff --git a/target/microblaze/cpu-qom.h b/target/microblaze/cpu-qom.h index 1a61db77d0..49b07cc697 100644 --- a/target/microblaze/cpu-qom.h +++ b/target/microblaze/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_MICROBLAZE_CPU_QOM_H #define QEMU_MICROBLAZE_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_MICROBLAZE_CPU "microblaze-cpu" diff --git a/target/mips/cpu-qom.h b/target/mips/cpu-qom.h index ee58606afe..a430c0fe4b 100644 --- a/target/mips/cpu-qom.h +++ b/target/mips/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_MIPS_CPU_QOM_H #define QEMU_MIPS_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #ifdef TARGET_MIPS64 #define TYPE_MIPS_CPU "mips64-cpu" diff --git a/target/moxie/cpu.h b/target/moxie/cpu.h index 91ef2dc25e..01dca548e5 100644 --- a/target/moxie/cpu.h +++ b/target/moxie/cpu.h @@ -46,7 +46,7 @@ typedef struct CPUMoxieState { struct {} end_reset_fields; } CPUMoxieState; -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_MOXIE_CPU "moxie-cpu" diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h index 5d44b76389..361b06ffeb 100644 --- a/target/nios2/cpu.h +++ b/target/nios2/cpu.h @@ -22,7 +22,7 @@ #define NIOS2_CPU_H #include "exec/cpu-defs.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" typedef struct CPUNios2State CPUNios2State; #if !defined(CONFIG_USER_ONLY) diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h index 61ade1d4f0..561f0f7fad 100644 --- a/target/openrisc/cpu.h +++ b/target/openrisc/cpu.h @@ -21,7 +21,7 @@ #define OPENRISC_CPU_H #include "exec/cpu-defs.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" /* cpu_openrisc_map_address_* in CPUOpenRISCTLBContext need this decl. */ struct OpenRISCCPU; diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h index 5769fb78a9..7ffdb0a706 100644 --- a/target/ppc/cpu-qom.h +++ b/target/ppc/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_PPC_CPU_QOM_H #define QEMU_PPC_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #ifdef TARGET_PPC64 #define TYPE_POWERPC_CPU "powerpc64-cpu" diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c index 55f7a7f16a..86c667b094 100644 --- a/target/ppc/mmu_helper.c +++ b/target/ppc/mmu_helper.c @@ -100,7 +100,7 @@ static int pp_check(int key, int pp, int nx) case 0x1: case 0x2: access |= PAGE_WRITE; - /* No break here */ + /* fall through */ case 0x3: access |= PAGE_READ; break; @@ -708,7 +708,7 @@ static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, if (pr != 0) { goto check_perms; } - /* No break here */ + /* fall through */ case 0x3: /* All accesses granted */ ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; @@ -722,7 +722,7 @@ static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, ret = -2; break; } - /* No break here */ + /* fall through */ case 0x1: check_perms: /* Check from TLB entry */ diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 240b31e2eb..18d91d0920 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -20,7 +20,7 @@ #ifndef RISCV_CPU_H #define RISCV_CPU_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "exec/cpu-defs.h" #include "fpu/softfloat-types.h" diff --git a/target/s390x/cpu-qom.h b/target/s390x/cpu-qom.h index b46217dc31..b809ec8418 100644 --- a/target/s390x/cpu-qom.h +++ b/target/s390x/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_S390_CPU_QOM_H #define QEMU_S390_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_S390_CPU "s390x-cpu" diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h index 3d9de25f7c..79202c0980 100644 --- a/target/s390x/cpu.h +++ b/target/s390x/cpu.h @@ -332,6 +332,13 @@ static inline int cpu_mmu_index(CPUS390XState *env, bool ifetch) return MMU_REAL_IDX; } + if (ifetch) { + if ((env->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME) { + return MMU_HOME_IDX; + } + return MMU_PRIMARY_IDX; + } + switch (env->psw.mask & PSW_MASK_ASC) { case PSW_ASC_PRIMARY: return MMU_PRIMARY_IDX; diff --git a/target/s390x/cpu_models.h b/target/s390x/cpu_models.h index 174a99e561..88bd01a616 100644 --- a/target/s390x/cpu_models.h +++ b/target/s390x/cpu_models.h @@ -15,7 +15,7 @@ #include "cpu_features.h" #include "gen-features.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" /* static CPU definition */ struct S390CPUDef { diff --git a/target/s390x/helper.c b/target/s390x/helper.c index 1350ad319a..948c0398d4 100644 --- a/target/s390x/helper.c +++ b/target/s390x/helper.c @@ -58,6 +58,11 @@ hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, vaddr vaddr) vaddr &= 0x7fffffff; } + /* We want to read the code (e.g., see what we are single-stepping).*/ + if (asc != PSW_ASC_HOME) { + asc = PSW_ASC_PRIMARY; + } + if (mmu_translate(env, vaddr, MMU_INST_FETCH, asc, &raddr, &prot, false)) { return -1; } diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 29d9eaa5b7..91ba2e03d9 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -1815,6 +1815,11 @@ void HELPER(sske)(CPUS390XState *env, uint64_t r1, uint64_t r2) key = (uint8_t) r1; skeyclass->set_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key); + /* + * As we can only flush by virtual address and not all the entries + * that point to a physical address we have to flush the whole TLB. + */ + tlb_flush_all_cpus_synced(env_cpu(env)); } /* reset reference bit extended */ @@ -1843,6 +1848,11 @@ uint32_t HELPER(rrbe)(CPUS390XState *env, uint64_t r2) if (skeyclass->set_skeys(ss, r2 / TARGET_PAGE_SIZE, 1, &key)) { return 0; } + /* + * As we can only flush by virtual address and not all the entries + * that point to a physical address we have to flush the whole TLB. + */ + tlb_flush_all_cpus_synced(env_cpu(env)); /* * cc diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c index 7a563110f0..7e6b0d0508 100644 --- a/target/s390x/mmu_helper.c +++ b/target/s390x/mmu_helper.c @@ -335,6 +335,75 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, return r; } +static void mmu_handle_skey(target_ulong addr, int rw, int *flags) +{ + static S390SKeysClass *skeyclass; + static S390SKeysState *ss; + uint8_t key; + int rc; + + if (unlikely(addr >= ram_size)) { + return; + } + + if (unlikely(!ss)) { + ss = s390_get_skeys_device(); + skeyclass = S390_SKEYS_GET_CLASS(ss); + } + + /* + * Whenever we create a new TLB entry, we set the storage key reference + * bit. In case we allow write accesses, we set the storage key change + * bit. Whenever the guest changes the storage key, we have to flush the + * TLBs of all CPUs (the whole TLB or all affected entries), so that the + * next reference/change will result in an MMU fault and make us properly + * update the storage key here. + * + * Note 1: "record of references ... is not necessarily accurate", + * "change bit may be set in case no storing has occurred". + * -> We can set reference/change bits even on exceptions. + * Note 2: certain accesses seem to ignore storage keys. For example, + * DAT translation does not set reference bits for table accesses. + * + * TODO: key-controlled protection. Only CPU accesses make use of the + * PSW key. CSS accesses are different - we have to pass in the key. + * + * TODO: we have races between getting and setting the key. + */ + rc = skeyclass->get_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key); + if (rc) { + trace_get_skeys_nonzero(rc); + return; + } + + switch (rw) { + case MMU_DATA_LOAD: + case MMU_INST_FETCH: + /* + * The TLB entry has to remain write-protected on read-faults if + * the storage key does not indicate a change already. Otherwise + * we might miss setting the change bit on write accesses. + */ + if (!(key & SK_C)) { + *flags &= ~PAGE_WRITE; + } + break; + case MMU_DATA_STORE: + key |= SK_C; + break; + default: + g_assert_not_reached(); + } + + /* Any store/fetch sets the reference bit */ + key |= SK_R; + + rc = skeyclass->set_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key); + if (rc) { + trace_set_skeys_nonzero(rc); + } +} + /** * Translate a virtual (logical) address into a physical (absolute) address. * @param vaddr the virtual address @@ -348,15 +417,9 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc, target_ulong *raddr, int *flags, bool exc) { - static S390SKeysState *ss; - static S390SKeysClass *skeyclass; - int r = -1; - uint8_t key; + uint64_t asce; + int r; - if (unlikely(!ss)) { - ss = s390_get_skeys_device(); - skeyclass = S390_SKEYS_GET_CLASS(ss); - } *flags = PAGE_READ | PAGE_WRITE | PAGE_EXEC; if (is_low_address(vaddr & TARGET_PAGE_MASK) && lowprot_enabled(env, asc)) { @@ -381,36 +444,21 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc, if (!(env->psw.mask & PSW_MASK_DAT)) { *raddr = vaddr; - r = 0; - goto out; + goto nodat; } switch (asc) { case PSW_ASC_PRIMARY: PTE_DPRINTF("%s: asc=primary\n", __func__); - r = mmu_translate_asce(env, vaddr, asc, env->cregs[1], raddr, flags, - rw, exc); + asce = env->cregs[1]; break; case PSW_ASC_HOME: PTE_DPRINTF("%s: asc=home\n", __func__); - r = mmu_translate_asce(env, vaddr, asc, env->cregs[13], raddr, flags, - rw, exc); + asce = env->cregs[13]; break; case PSW_ASC_SECONDARY: PTE_DPRINTF("%s: asc=secondary\n", __func__); - /* - * Instruction: Primary - * Data: Secondary - */ - if (rw == MMU_INST_FETCH) { - r = mmu_translate_asce(env, vaddr, PSW_ASC_PRIMARY, env->cregs[1], - raddr, flags, rw, exc); - *flags &= ~(PAGE_READ | PAGE_WRITE); - } else { - r = mmu_translate_asce(env, vaddr, PSW_ASC_SECONDARY, env->cregs[7], - raddr, flags, rw, exc); - *flags &= ~(PAGE_EXEC); - } + asce = env->cregs[7]; break; case PSW_ASC_ACCREG: default: @@ -418,31 +466,18 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc, break; } - out: + /* perform the DAT translation */ + r = mmu_translate_asce(env, vaddr, asc, asce, raddr, flags, rw, exc); + if (r) { + return r; + } + +nodat: /* Convert real address -> absolute address */ *raddr = mmu_real2abs(env, *raddr); - if (r == 0 && *raddr < ram_size) { - if (skeyclass->get_skeys(ss, *raddr / TARGET_PAGE_SIZE, 1, &key)) { - trace_get_skeys_nonzero(r); - return 0; - } - - if (*flags & PAGE_READ) { - key |= SK_R; - } - - if (*flags & PAGE_WRITE) { - key |= SK_C; - } - - if (skeyclass->set_skeys(ss, *raddr / TARGET_PAGE_SIZE, 1, &key)) { - trace_set_skeys_nonzero(r); - return 0; - } - } - - return r; + mmu_handle_skey(*raddr, rw, flags); + return 0; } /** @@ -559,6 +594,6 @@ int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw, *addr = mmu_real2abs(env, raddr & TARGET_PAGE_MASK); - /* TODO: storage key handling */ + mmu_handle_skey(*addr, rw, flags); return 0; } diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c index 41d5cf869f..0caddb3958 100644 --- a/target/s390x/translate_vx.inc.c +++ b/target/s390x/translate_vx.inc.c @@ -213,7 +213,7 @@ static void get_vec_element_ptr_i64(TCGv_ptr ptr, uint8_t reg, TCGv_i64 enr, vec_full_reg_offset(v3), ptr, 16, 16, data, fn) #define gen_gvec_3i(v1, v2, v3, c, gen) \ tcg_gen_gvec_3i(vec_full_reg_offset(v1), vec_full_reg_offset(v2), \ - vec_full_reg_offset(v3), c, 16, 16, gen) + vec_full_reg_offset(v3), 16, 16, c, gen) #define gen_gvec_4(v1, v2, v3, v4, gen) \ tcg_gen_gvec_4(vec_full_reg_offset(v1), vec_full_reg_offset(v2), \ vec_full_reg_offset(v3), vec_full_reg_offset(v4), \ diff --git a/target/sh4/cpu-qom.h b/target/sh4/cpu-qom.h index 0f9fb4dd31..0c56d055ba 100644 --- a/target/sh4/cpu-qom.h +++ b/target/sh4/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_SUPERH_CPU_QOM_H #define QEMU_SUPERH_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_SUPERH_CPU "superh-cpu" diff --git a/target/sparc/cpu-qom.h b/target/sparc/cpu-qom.h index af6d57a9e0..7442e2768e 100644 --- a/target/sparc/cpu-qom.h +++ b/target/sparc/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_SPARC_CPU_QOM_H #define QEMU_SPARC_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #ifdef TARGET_SPARC64 #define TYPE_SPARC_CPU "sparc64-cpu" diff --git a/target/tilegx/cpu.h b/target/tilegx/cpu.h index 6fcec06a9b..9cbec247d2 100644 --- a/target/tilegx/cpu.h +++ b/target/tilegx/cpu.h @@ -94,7 +94,7 @@ typedef struct CPUTLGState { struct {} end_reset_fields; } CPUTLGState; -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_TILEGX_CPU "tilegx-cpu" diff --git a/target/tricore/cpu-qom.h b/target/tricore/cpu-qom.h index 93c9d77fe3..7c1e130b4e 100644 --- a/target/tricore/cpu-qom.h +++ b/target/tricore/cpu-qom.h @@ -18,7 +18,7 @@ #ifndef QEMU_TRICORE_CPU_QOM_H #define QEMU_TRICORE_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_TRICORE_CPU "tricore-cpu" diff --git a/target/tricore/helper.h b/target/tricore/helper.h index b64780c37d..78176aa17a 100644 --- a/target/tricore/helper.h +++ b/target/tricore/helper.h @@ -153,3 +153,4 @@ DEF_HELPER_2(psw_write, void, env, i32) DEF_HELPER_1(psw_read, i32, env) /* Exceptions */ DEF_HELPER_3(raise_exception_sync, noreturn, env, i32, i32) +DEF_HELPER_2(qemu_excp, noreturn, env, i32) diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c index 9476d10d00..32c2bc1699 100644 --- a/target/tricore/op_helper.c +++ b/target/tricore/op_helper.c @@ -107,6 +107,13 @@ static void raise_exception_sync_helper(CPUTriCoreState *env, uint32_t class, raise_exception_sync_internal(env, class, tin, pc, 0); } +void helper_qemu_excp(CPUTriCoreState *env, uint32_t excp) +{ + CPUState *cs = env_cpu(env); + cs->exception_index = excp; + cpu_loop_exit(cs); +} + /* Addressing mode helper */ static uint16_t reverse16(uint16_t val) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index dc2a65f3f9..4f10407477 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -30,6 +30,7 @@ #include "exec/helper-gen.h" #include "tricore-opcodes.h" +#include "exec/translator.h" #include "exec/log.h" /* @@ -64,25 +65,16 @@ static const char *regnames_d[] = { }; typedef struct DisasContext { - struct TranslationBlock *tb; - target_ulong pc, saved_pc, next_pc; + DisasContextBase base; + CPUTriCoreState *env; + target_ulong pc_succ_insn; uint32_t opcode; - int singlestep_enabled; /* Routine used to access memory */ int mem_idx; uint32_t hflags, saved_hflags; - int bstate; } DisasContext; enum { - - BS_NONE = 0, - BS_STOP = 1, - BS_BRANCH = 2, - BS_EXCP = 3, -}; - -enum { MODE_LL = 0, MODE_LU = 1, MODE_UL = 2, @@ -378,13 +370,13 @@ static void gen_swapmsk(DisasContext *ctx, int reg, TCGv ea) These makros also specify in which ISA version the csfr was introduced. */ #define R(ADDRESS, REG, FEATURE) \ case ADDRESS: \ - if (tricore_feature(env, FEATURE)) { \ + if (tricore_feature(ctx->env, FEATURE)) { \ tcg_gen_ld_tl(ret, cpu_env, offsetof(CPUTriCoreState, REG)); \ } \ break; #define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE) #define E(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE) -static inline void gen_mfcr(CPUTriCoreState *env, TCGv ret, int32_t offset) +static inline void gen_mfcr(DisasContext *ctx, TCGv ret, int32_t offset) { /* since we're caching PSW make this a special case */ if (offset == 0xfe04) { @@ -403,7 +395,7 @@ static inline void gen_mfcr(CPUTriCoreState *env, TCGv ret, int32_t offset) since no execption occurs */ #define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE) \ case ADDRESS: \ - if (tricore_feature(env, FEATURE)) { \ + if (tricore_feature(ctx->env, FEATURE)) { \ tcg_gen_st_tl(r1, cpu_env, offsetof(CPUTriCoreState, REG)); \ } \ break; @@ -412,7 +404,7 @@ static inline void gen_mfcr(CPUTriCoreState *env, TCGv ret, int32_t offset) watchdog device, we handle endinit protected registers like all-access registers for now. */ #define E(ADDRESS, REG, FEATURE) A(ADDRESS, REG, FEATURE) -static inline void gen_mtcr(CPUTriCoreState *env, DisasContext *ctx, TCGv r1, +static inline void gen_mtcr(DisasContext *ctx, TCGv r1, int32_t offset) { if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) { @@ -1102,7 +1094,7 @@ gen_maddrs_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n) static inline void gen_madd32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n, - uint32_t up_shift, CPUTriCoreState *env) + uint32_t up_shift) { TCGv temp = tcg_temp_new(); TCGv temp2 = tcg_temp_new(); @@ -1263,7 +1255,7 @@ gen_m16adds64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2, static inline void gen_madd64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2, - TCGv arg3, uint32_t n, CPUTriCoreState *env) + TCGv arg3, uint32_t n) { TCGv_i64 t1 = tcg_temp_new_i64(); TCGv_i64 t2 = tcg_temp_new_i64(); @@ -1961,7 +1953,7 @@ gen_msubrs_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n) static inline void gen_msub32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n, - uint32_t up_shift, CPUTriCoreState *env) + uint32_t up_shift) { TCGv temp = tcg_temp_new(); TCGv temp2 = tcg_temp_new(); @@ -2116,7 +2108,7 @@ gen_m16subs64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2, static inline void gen_msub64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2, - TCGv arg3, uint32_t n, CPUTriCoreState *env) + TCGv arg3, uint32_t n) { TCGv_i64 t1 = tcg_temp_new_i64(); TCGv_i64 t2 = tcg_temp_new_i64(); @@ -3162,11 +3154,11 @@ static inline void gen_unpack(TCGv rl, TCGv rh, TCGv r1) } static inline void -gen_dvinit_b(CPUTriCoreState *env, TCGv rl, TCGv rh, TCGv r1, TCGv r2) +gen_dvinit_b(DisasContext *ctx, TCGv rl, TCGv rh, TCGv r1, TCGv r2) { TCGv_i64 ret = tcg_temp_new_i64(); - if (!tricore_feature(env, TRICORE_FEATURE_131)) { + if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) { gen_helper_dvinit_b_13(ret, cpu_env, r1, r2); } else { gen_helper_dvinit_b_131(ret, cpu_env, r1, r2); @@ -3177,11 +3169,11 @@ gen_dvinit_b(CPUTriCoreState *env, TCGv rl, TCGv rh, TCGv r1, TCGv r2) } static inline void -gen_dvinit_h(CPUTriCoreState *env, TCGv rl, TCGv rh, TCGv r1, TCGv r2) +gen_dvinit_h(DisasContext *ctx, TCGv rl, TCGv rh, TCGv r1, TCGv r2) { TCGv_i64 ret = tcg_temp_new_i64(); - if (!tricore_feature(env, TRICORE_FEATURE_131)) { + if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) { gen_helper_dvinit_h_13(ret, cpu_env, r1, r2); } else { gen_helper_dvinit_h_131(ret, cpu_env, r1, r2); @@ -3230,12 +3222,12 @@ static inline void gen_save_pc(target_ulong pc) static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) { - if (unlikely(ctx->singlestep_enabled)) { + if (unlikely(ctx->base.singlestep_enabled)) { return false; } #ifndef CONFIG_USER_ONLY - return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); + return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); #else return true; #endif @@ -3246,10 +3238,10 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) if (use_goto_tb(ctx, dest)) { tcg_gen_goto_tb(n); gen_save_pc(dest); - tcg_gen_exit_tb(ctx->tb, n); + tcg_gen_exit_tb(ctx->base.tb, n); } else { gen_save_pc(dest); - if (ctx->singlestep_enabled) { + if (ctx->base.singlestep_enabled) { /* raise exception debug */ } tcg_gen_exit_tb(NULL, 0); @@ -3261,24 +3253,33 @@ static void generate_trap(DisasContext *ctx, int class, int tin) TCGv_i32 classtemp = tcg_const_i32(class); TCGv_i32 tintemp = tcg_const_i32(tin); - gen_save_pc(ctx->pc); + gen_save_pc(ctx->base.pc_next); gen_helper_raise_exception_sync(cpu_env, classtemp, tintemp); - ctx->bstate = BS_EXCP; + ctx->base.is_jmp = DISAS_NORETURN; tcg_temp_free(classtemp); tcg_temp_free(tintemp); } +static void generate_qemu_excp(DisasContext *ctx, int excp) +{ + TCGv_i32 tmp = tcg_const_i32(excp); + gen_save_pc(ctx->base.pc_next); + gen_helper_qemu_excp(cpu_env, tmp); + ctx->base.is_jmp = DISAS_NORETURN; + tcg_temp_free(tmp); +} + static inline void gen_branch_cond(DisasContext *ctx, TCGCond cond, TCGv r1, TCGv r2, int16_t address) { TCGLabel *jumpLabel = gen_new_label(); tcg_gen_brcond_tl(cond, r1, r2, jumpLabel); - gen_goto_tb(ctx, 1, ctx->next_pc); + gen_goto_tb(ctx, 1, ctx->pc_succ_insn); gen_set_label(jumpLabel); - gen_goto_tb(ctx, 0, ctx->pc + address * 2); + gen_goto_tb(ctx, 0, ctx->base.pc_next + address * 2); } static inline void gen_branch_condi(DisasContext *ctx, TCGCond cond, TCGv r1, @@ -3295,9 +3296,9 @@ static void gen_loop(DisasContext *ctx, int r1, int32_t offset) tcg_gen_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1); tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr_a[r1], -1, l1); - gen_goto_tb(ctx, 1, ctx->pc + offset); + gen_goto_tb(ctx, 1, ctx->base.pc_next + offset); gen_set_label(l1); - gen_goto_tb(ctx, 0, ctx->next_pc); + gen_goto_tb(ctx, 0, ctx->pc_succ_insn); } static void gen_fcall_save_ctx(DisasContext *ctx) @@ -3306,7 +3307,7 @@ static void gen_fcall_save_ctx(DisasContext *ctx) tcg_gen_addi_tl(temp, cpu_gpr_a[10], -4); tcg_gen_qemu_st_tl(cpu_gpr_a[11], temp, ctx->mem_idx, MO_LESL); - tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc); + tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn); tcg_gen_mov_tl(cpu_gpr_a[10], temp); tcg_temp_free(temp); @@ -3321,7 +3322,7 @@ static void gen_fret(DisasContext *ctx) tcg_gen_addi_tl(cpu_gpr_a[10], cpu_gpr_a[10], 4); tcg_gen_mov_tl(cpu_PC, temp); tcg_gen_exit_tb(NULL, 0); - ctx->bstate = BS_BRANCH; + ctx->base.is_jmp = DISAS_NORETURN; tcg_temp_free(temp); } @@ -3336,12 +3337,12 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, /* SB-format jumps */ case OPC1_16_SB_J: case OPC1_32_B_J: - gen_goto_tb(ctx, 0, ctx->pc + offset * 2); + gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2); break; case OPC1_32_B_CALL: case OPC1_16_SB_CALL: - gen_helper_1arg(call, ctx->next_pc); - gen_goto_tb(ctx, 0, ctx->pc + offset * 2); + gen_helper_1arg(call, ctx->pc_succ_insn); + gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2); break; case OPC1_16_SB_JZ: gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], 0, offset); @@ -3433,26 +3434,26 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, break; /* B-format */ case OPC1_32_B_CALLA: - gen_helper_1arg(call, ctx->next_pc); + gen_helper_1arg(call, ctx->pc_succ_insn); gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset)); break; case OPC1_32_B_FCALL: gen_fcall_save_ctx(ctx); - gen_goto_tb(ctx, 0, ctx->pc + offset * 2); + gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2); break; case OPC1_32_B_FCALLA: gen_fcall_save_ctx(ctx); gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset)); break; case OPC1_32_B_JLA: - tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc); + tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn); /* fall through */ case OPC1_32_B_JA: gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset)); break; case OPC1_32_B_JL: - tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc); - gen_goto_tb(ctx, 0, ctx->pc + offset * 2); + tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn); + gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2); break; /* BOL format */ case OPCM_32_BRC_EQ_NEQ: @@ -3551,7 +3552,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, gen_loop(ctx, r2, offset * 2); } else { /* OPC2_32_BRR_LOOPU */ - gen_goto_tb(ctx, 0, ctx->pc + offset * 2); + gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2); } break; case OPCM_32_BRR_JNE: @@ -3585,7 +3586,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, default: generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } - ctx->bstate = BS_BRANCH; + ctx->base.is_jmp = DISAS_NORETURN; } @@ -3593,7 +3594,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, * Functions for decoding instructions */ -static void decode_src_opc(CPUTriCoreState *env, DisasContext *ctx, int op1) +static void decode_src_opc(DisasContext *ctx, int op1) { int r1; int32_t const4; @@ -3655,7 +3656,7 @@ static void decode_src_opc(CPUTriCoreState *env, DisasContext *ctx, int op1) tcg_gen_movi_tl(cpu_gpr_a[r1], const4); break; case OPC1_16_SRC_MOV_E: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { tcg_gen_movi_tl(cpu_gpr_d[r1], const4); tcg_gen_sari_tl(cpu_gpr_d[r1+1], cpu_gpr_d[r1], 31); } else { @@ -3919,7 +3920,7 @@ static void decode_sro_opc(DisasContext *ctx, int op1) } } -static void decode_sr_system(CPUTriCoreState *env, DisasContext *ctx) +static void decode_sr_system(DisasContext *ctx) { uint32_t op2; op2 = MASK_OP_SR_OP2(ctx->opcode); @@ -3933,7 +3934,7 @@ static void decode_sr_system(CPUTriCoreState *env, DisasContext *ctx) case OPC2_16_SR_RFE: gen_helper_rfe(cpu_env); tcg_gen_exit_tb(NULL, 0); - ctx->bstate = BS_BRANCH; + ctx->base.is_jmp = DISAS_NORETURN; break; case OPC2_16_SR_DEBUG: /* raise EXCP_DEBUG */ @@ -3946,7 +3947,7 @@ static void decode_sr_system(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_sr_accu(CPUTriCoreState *env, DisasContext *ctx) +static void decode_sr_accu(DisasContext *ctx) { uint32_t op2; uint32_t r1; @@ -3990,7 +3991,7 @@ static void decode_sr_accu(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx) +static void decode_16Bit_opc(DisasContext *ctx) { int op1; int r1, r2; @@ -4021,7 +4022,7 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx) case OPC1_16_SRC_MOV_E: case OPC1_16_SRC_SH: case OPC1_16_SRC_SHA: - decode_src_opc(env, ctx, op1); + decode_src_opc(ctx, op1); break; /* SRR-format */ case OPC1_16_SRR_ADD: @@ -4106,7 +4107,7 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx) break; case OPC1_16_SBC_JEQ2: case OPC1_16_SBC_JNE2: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { address = MASK_OP_SBC_DISP4(ctx->opcode); const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode); gen_compute_branch(ctx, op1, 0, 0, const16, address); @@ -4124,7 +4125,7 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx) /* SBR-format */ case OPC1_16_SBR_JEQ2: case OPC1_16_SBR_JNE2: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { r1 = MASK_OP_SBR_S2(ctx->opcode); address = MASK_OP_SBR_DISP4(ctx->opcode); gen_compute_branch(ctx, op1, r1, 0, 0, address); @@ -4204,10 +4205,10 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx) break; /* SR-format */ case OPCM_16_SR_SYSTEM: - decode_sr_system(env, ctx); + decode_sr_system(ctx); break; case OPCM_16_SR_ACCU: - decode_sr_accu(env, ctx); + decode_sr_accu(ctx); break; case OPC1_16_SR_JI: r1 = MASK_OP_SR_S1D(ctx->opcode); @@ -4227,7 +4228,7 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx) */ /* ABS-format */ -static void decode_abs_ldw(CPUTriCoreState *env, DisasContext *ctx) +static void decode_abs_ldw(DisasContext *ctx) { int32_t op2; int32_t r1; @@ -4262,7 +4263,7 @@ static void decode_abs_ldw(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_abs_ldb(CPUTriCoreState *env, DisasContext *ctx) +static void decode_abs_ldb(DisasContext *ctx) { int32_t op2; int32_t r1; @@ -4295,7 +4296,7 @@ static void decode_abs_ldb(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_abs_ldst_swap(CPUTriCoreState *env, DisasContext *ctx) +static void decode_abs_ldst_swap(DisasContext *ctx) { int32_t op2; int32_t r1; @@ -4322,7 +4323,7 @@ static void decode_abs_ldst_swap(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_abs_ldst_context(CPUTriCoreState *env, DisasContext *ctx) +static void decode_abs_ldst_context(DisasContext *ctx) { uint32_t op2; int32_t off18; @@ -4348,7 +4349,7 @@ static void decode_abs_ldst_context(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_abs_store(CPUTriCoreState *env, DisasContext *ctx) +static void decode_abs_store(DisasContext *ctx) { int32_t op2; int32_t r1; @@ -4382,7 +4383,7 @@ static void decode_abs_store(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_abs_storeb_h(CPUTriCoreState *env, DisasContext *ctx) +static void decode_abs_storeb_h(DisasContext *ctx) { int32_t op2; int32_t r1; @@ -4410,7 +4411,7 @@ static void decode_abs_storeb_h(CPUTriCoreState *env, DisasContext *ctx) /* Bit-format */ -static void decode_bit_andacc(CPUTriCoreState *env, DisasContext *ctx) +static void decode_bit_andacc(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -4451,7 +4452,7 @@ static void decode_bit_andacc(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_bit_logical_t(CPUTriCoreState *env, DisasContext *ctx) +static void decode_bit_logical_t(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -4485,7 +4486,7 @@ static void decode_bit_logical_t(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_bit_insert(CPUTriCoreState *env, DisasContext *ctx) +static void decode_bit_insert(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -4508,7 +4509,7 @@ static void decode_bit_insert(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_bit_logical_t2(CPUTriCoreState *env, DisasContext *ctx) +static void decode_bit_logical_t2(DisasContext *ctx) { uint32_t op2; @@ -4544,7 +4545,7 @@ static void decode_bit_logical_t2(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_bit_orand(CPUTriCoreState *env, DisasContext *ctx) +static void decode_bit_orand(DisasContext *ctx) { uint32_t op2; @@ -4585,7 +4586,7 @@ static void decode_bit_orand(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_bit_sh_logic1(CPUTriCoreState *env, DisasContext *ctx) +static void decode_bit_sh_logic1(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -4626,7 +4627,7 @@ static void decode_bit_sh_logic1(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_bit_sh_logic2(CPUTriCoreState *env, DisasContext *ctx) +static void decode_bit_sh_logic2(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -4670,8 +4671,7 @@ static void decode_bit_sh_logic2(CPUTriCoreState *env, DisasContext *ctx) /* BO-format */ -static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env, - DisasContext *ctx) +static void decode_bo_addrmode_post_pre_base(DisasContext *ctx) { uint32_t op2; uint32_t off10; @@ -4705,13 +4705,13 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env, break; case OPC2_32_BO_CACHEI_WI_SHORTOFF: case OPC2_32_BO_CACHEI_W_SHORTOFF: - if (!tricore_feature(env, TRICORE_FEATURE_131)) { + if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC2_32_BO_CACHEI_W_POSTINC: case OPC2_32_BO_CACHEI_WI_POSTINC: - if (tricore_feature(env, TRICORE_FEATURE_131)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_131)) { tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); @@ -4719,7 +4719,7 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env, break; case OPC2_32_BO_CACHEI_W_PREINC: case OPC2_32_BO_CACHEI_WI_PREINC: - if (tricore_feature(env, TRICORE_FEATURE_131)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_131)) { tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); @@ -4830,8 +4830,7 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env, } } -static void decode_bo_addrmode_bitreverse_circular(CPUTriCoreState *env, - DisasContext *ctx) +static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx) { uint32_t op2; uint32_t off10; @@ -4941,8 +4940,7 @@ static void decode_bo_addrmode_bitreverse_circular(CPUTriCoreState *env, tcg_temp_free(temp3); } -static void decode_bo_addrmode_ld_post_pre_base(CPUTriCoreState *env, - DisasContext *ctx) +static void decode_bo_addrmode_ld_post_pre_base(DisasContext *ctx) { uint32_t op2; uint32_t off10; @@ -5076,8 +5074,7 @@ static void decode_bo_addrmode_ld_post_pre_base(CPUTriCoreState *env, } } -static void decode_bo_addrmode_ld_bitreverse_circular(CPUTriCoreState *env, - DisasContext *ctx) +static void decode_bo_addrmode_ld_bitreverse_circular(DisasContext *ctx) { uint32_t op2; uint32_t off10; @@ -5195,8 +5192,7 @@ static void decode_bo_addrmode_ld_bitreverse_circular(CPUTriCoreState *env, tcg_temp_free(temp3); } -static void decode_bo_addrmode_stctx_post_pre_base(CPUTriCoreState *env, - DisasContext *ctx) +static void decode_bo_addrmode_stctx_post_pre_base(DisasContext *ctx) { uint32_t op2; uint32_t off10; @@ -5288,8 +5284,7 @@ static void decode_bo_addrmode_stctx_post_pre_base(CPUTriCoreState *env, tcg_temp_free(temp2); } -static void decode_bo_addrmode_ldmst_bitreverse_circular(CPUTriCoreState *env, - DisasContext *ctx) +static void decode_bo_addrmode_ldmst_bitreverse_circular(DisasContext *ctx) { uint32_t op2; uint32_t off10; @@ -5351,7 +5346,7 @@ static void decode_bo_addrmode_ldmst_bitreverse_circular(CPUTriCoreState *env, tcg_temp_free(temp3); } -static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1) +static void decode_bol_opc(DisasContext *ctx, int32_t op1) { int r1, r2; int32_t address; @@ -5378,7 +5373,7 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1) tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], address); break; case OPC1_32_BOL_ST_A_LONGOFF: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], address, MO_LEUL); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); @@ -5388,42 +5383,42 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1) gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUL); break; case OPC1_32_BOL_LD_B_LONGOFF: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC1_32_BOL_LD_BU_LONGOFF: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_UB); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC1_32_BOL_LD_H_LONGOFF: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC1_32_BOL_LD_HU_LONGOFF: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUW); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC1_32_BOL_ST_B_LONGOFF: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC1_32_BOL_ST_H_LONGOFF: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); @@ -5435,7 +5430,7 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1) } /* RC format */ -static void decode_rc_logical_shift(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rc_logical_shift(DisasContext *ctx) { uint32_t op2; int r1, r2; @@ -5502,7 +5497,7 @@ static void decode_rc_logical_shift(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_rc_accumulator(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rc_accumulator(DisasContext *ctx) { uint32_t op2; int r1, r2; @@ -5702,7 +5697,7 @@ static void decode_rc_accumulator(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_rc_serviceroutine(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rc_serviceroutine(DisasContext *ctx) { uint32_t op2; uint32_t const9; @@ -5722,7 +5717,7 @@ static void decode_rc_serviceroutine(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rc_mul(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rc_mul(DisasContext *ctx) { uint32_t op2; int r1, r2; @@ -5760,7 +5755,7 @@ static void decode_rc_mul(CPUTriCoreState *env, DisasContext *ctx) } /* RCPW format */ -static void decode_rcpw_insert(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rcpw_insert(DisasContext *ctx) { uint32_t op2; int r1, r2; @@ -5799,7 +5794,7 @@ static void decode_rcpw_insert(CPUTriCoreState *env, DisasContext *ctx) /* RCRW format */ -static void decode_rcrw_insert(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rcrw_insert(DisasContext *ctx) { uint32_t op2; int r1, r3, r4; @@ -5844,7 +5839,7 @@ static void decode_rcrw_insert(CPUTriCoreState *env, DisasContext *ctx) /* RCR format */ -static void decode_rcr_cond_select(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rcr_cond_select(DisasContext *ctx) { uint32_t op2; int r1, r3, r4; @@ -5888,7 +5883,7 @@ static void decode_rcr_cond_select(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rcr_madd(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rcr_madd(DisasContext *ctx) { uint32_t op2; int r1, r3, r4; @@ -5943,7 +5938,7 @@ static void decode_rcr_madd(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rcr_msub(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rcr_msub(DisasContext *ctx) { uint32_t op2; int r1, r3, r4; @@ -6000,7 +5995,7 @@ static void decode_rcr_msub(CPUTriCoreState *env, DisasContext *ctx) /* RLC format */ -static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx, +static void decode_rlc_opc(DisasContext *ctx, uint32_t op1) { int32_t const16; @@ -6022,13 +6017,13 @@ static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx, break; case OPC1_32_RLC_MFCR: const16 = MASK_OP_RLC_CONST16(ctx->opcode); - gen_mfcr(env, cpu_gpr_d[r2], const16); + gen_mfcr(ctx, cpu_gpr_d[r2], const16); break; case OPC1_32_RLC_MOV: tcg_gen_movi_tl(cpu_gpr_d[r2], const16); break; case OPC1_32_RLC_MOV_64: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { CHECK_REG_PAIR(r2); tcg_gen_movi_tl(cpu_gpr_d[r2], const16); tcg_gen_movi_tl(cpu_gpr_d[r2+1], const16 >> 15); @@ -6048,7 +6043,7 @@ static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx, break; case OPC1_32_RLC_MTCR: const16 = MASK_OP_RLC_CONST16(ctx->opcode); - gen_mtcr(env, ctx, cpu_gpr_d[r1], const16); + gen_mtcr(ctx, cpu_gpr_d[r1], const16); break; default: generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); @@ -6056,7 +6051,7 @@ static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx, } /* RR format */ -static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr_accumulator(DisasContext *ctx) { uint32_t op2; int r3, r2, r1; @@ -6254,7 +6249,7 @@ static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]); break; case OPC2_32_RR_MOV_64: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { temp = tcg_temp_new(); CHECK_REG_PAIR(r3); @@ -6268,7 +6263,7 @@ static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx) } break; case OPC2_32_RR_MOVS_64: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { CHECK_REG_PAIR(r3); tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]); tcg_gen_sari_tl(cpu_gpr_d[r3 + 1], cpu_gpr_d[r2], 31); @@ -6398,7 +6393,7 @@ static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rr_logical_shift(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr_logical_shift(DisasContext *ctx) { uint32_t op2; int r3, r2, r1; @@ -6476,7 +6471,7 @@ static void decode_rr_logical_shift(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_rr_address(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr_address(DisasContext *ctx) { uint32_t op2, n; int r1, r2, r3; @@ -6544,7 +6539,7 @@ static void decode_rr_address(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rr_idirect(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr_idirect(DisasContext *ctx) { uint32_t op2; int r1; @@ -6557,11 +6552,11 @@ static void decode_rr_idirect(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1); break; case OPC2_32_RR_JLI: - tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc); + tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn); tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1); break; case OPC2_32_RR_CALLI: - gen_helper_1arg(call, ctx->next_pc); + gen_helper_1arg(call, ctx->pc_succ_insn); tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1); break; case OPC2_32_RR_FCALLI: @@ -6572,10 +6567,10 @@ static void decode_rr_idirect(CPUTriCoreState *env, DisasContext *ctx) generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } tcg_gen_exit_tb(NULL, 0); - ctx->bstate = BS_BRANCH; + ctx->base.is_jmp = DISAS_NORETURN; } -static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr_divide(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -6597,7 +6592,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) break; case OPC2_32_RR_DVINIT_B: CHECK_REG_PAIR(r3); - gen_dvinit_b(env, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], + gen_dvinit_b(ctx, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2]); break; case OPC2_32_RR_DVINIT_BU: @@ -6608,7 +6603,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_shri_tl(temp3, cpu_gpr_d[r1], 8); /* reset av */ tcg_gen_movi_tl(cpu_PSW_AV, 0); - if (!tricore_feature(env, TRICORE_FEATURE_131)) { + if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) { /* overflow = (abs(D[r3+1]) >= abs(D[r2])) */ tcg_gen_abs_tl(temp, temp3); tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]); @@ -6630,7 +6625,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) break; case OPC2_32_RR_DVINIT_H: CHECK_REG_PAIR(r3); - gen_dvinit_h(env, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], + gen_dvinit_h(ctx, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2]); break; case OPC2_32_RR_DVINIT_HU: @@ -6641,7 +6636,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_shri_tl(temp3, cpu_gpr_d[r1], 16); /* reset av */ tcg_gen_movi_tl(cpu_PSW_AV, 0); - if (!tricore_feature(env, TRICORE_FEATURE_131)) { + if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) { /* overflow = (abs(D[r3+1]) >= abs(D[r2])) */ tcg_gen_abs_tl(temp, temp3); tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]); @@ -6704,14 +6699,14 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) gen_unpack(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]); break; case OPC2_32_RR_CRC32: - if (tricore_feature(env, TRICORE_FEATURE_161)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_161)) { gen_helper_crc32(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC2_32_RR_DIV: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { GEN_HELPER_RR(divide, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2]); } else { @@ -6719,7 +6714,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) } break; case OPC2_32_RR_DIV_U: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { GEN_HELPER_RR(divide_u, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2]); } else { @@ -6762,7 +6757,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) } /* RR1 Format */ -static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr1_mul(DisasContext *ctx) { uint32_t op2; @@ -6876,7 +6871,7 @@ static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(n); } -static void decode_rr1_mulq(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr1_mulq(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -6948,7 +6943,7 @@ static void decode_rr1_mulq(CPUTriCoreState *env, DisasContext *ctx) } /* RR2 format */ -static void decode_rr2_mul(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr2_mul(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -6985,7 +6980,7 @@ static void decode_rr2_mul(CPUTriCoreState *env, DisasContext *ctx) } /* RRPW format */ -static void decode_rrpw_extract_insert(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrpw_extract_insert(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -7039,7 +7034,7 @@ static void decode_rrpw_extract_insert(CPUTriCoreState *env, DisasContext *ctx) } /* RRR format */ -static void decode_rrr_cond_select(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr_cond_select(DisasContext *ctx) { uint32_t op2; int r1, r2, r3, r4; @@ -7085,7 +7080,7 @@ static void decode_rrr_cond_select(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rrr_divide(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr_divide(DisasContext *ctx) { uint32_t op2; @@ -7165,7 +7160,7 @@ static void decode_rrr_divide(CPUTriCoreState *env, DisasContext *ctx) } /* RRR2 format */ -static void decode_rrr2_madd(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr2_madd(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4; @@ -7217,7 +7212,7 @@ static void decode_rrr2_madd(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rrr2_msub(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr2_msub(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4; @@ -7269,7 +7264,7 @@ static void decode_rrr2_msub(CPUTriCoreState *env, DisasContext *ctx) } /* RRR1 format */ -static void decode_rrr1_madd(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr1_madd(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4, n; @@ -7415,7 +7410,7 @@ static void decode_rrr1_madd(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr1_maddq_h(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4, n; @@ -7434,19 +7429,19 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx) switch (op2) { case OPC2_32_RRR1_MADD_Q_32: gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1], - cpu_gpr_d[r2], n, 32, env); + cpu_gpr_d[r2], n, 32); break; case OPC2_32_RRR1_MADD_Q_64: CHECK_REG_PAIR(r4); CHECK_REG_PAIR(r3); gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], - n, env); + n); break; case OPC2_32_RRR1_MADD_Q_32_L: tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]); gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1], - temp, n, 16, env); + temp, n, 16); break; case OPC2_32_RRR1_MADD_Q_64_L: CHECK_REG_PAIR(r4); @@ -7454,12 +7449,12 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]); gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp, - n, env); + n); break; case OPC2_32_RRR1_MADD_Q_32_U: tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16); gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1], - temp, n, 16, env); + temp, n, 16); break; case OPC2_32_RRR1_MADD_Q_64_U: CHECK_REG_PAIR(r4); @@ -7467,7 +7462,7 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16); gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp, - n, env); + n); break; case OPC2_32_RRR1_MADD_Q_32_LL: tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]); @@ -7595,7 +7590,7 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp2); } -static void decode_rrr1_maddsu_h(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr1_maddsu_h(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4, n; @@ -7753,7 +7748,7 @@ static void decode_rrr1_maddsu_h(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rrr1_msub(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr1_msub(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4, n; @@ -7899,7 +7894,7 @@ static void decode_rrr1_msub(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr1_msubq_h(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4, n; @@ -7918,19 +7913,19 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx) switch (op2) { case OPC2_32_RRR1_MSUB_Q_32: gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1], - cpu_gpr_d[r2], n, 32, env); + cpu_gpr_d[r2], n, 32); break; case OPC2_32_RRR1_MSUB_Q_64: CHECK_REG_PAIR(r4); CHECK_REG_PAIR(r3); gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], - n, env); + n); break; case OPC2_32_RRR1_MSUB_Q_32_L: tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]); gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1], - temp, n, 16, env); + temp, n, 16); break; case OPC2_32_RRR1_MSUB_Q_64_L: CHECK_REG_PAIR(r4); @@ -7938,12 +7933,12 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]); gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp, - n, env); + n); break; case OPC2_32_RRR1_MSUB_Q_32_U: tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16); gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1], - temp, n, 16, env); + temp, n, 16); break; case OPC2_32_RRR1_MSUB_Q_64_U: CHECK_REG_PAIR(r4); @@ -7951,7 +7946,7 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16); gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp, - n, env); + n); break; case OPC2_32_RRR1_MSUB_Q_32_LL: tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]); @@ -8079,7 +8074,7 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp2); } -static void decode_rrr1_msubad_h(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr1_msubad_h(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4, n; @@ -8238,7 +8233,7 @@ static void decode_rrr1_msubad_h(CPUTriCoreState *env, DisasContext *ctx) } /* RRRR format */ -static void decode_rrrr_extract_insert(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrrr_extract_insert(DisasContext *ctx) { uint32_t op2; int r1, r2, r3, r4; @@ -8295,7 +8290,7 @@ static void decode_rrrr_extract_insert(CPUTriCoreState *env, DisasContext *ctx) } /* RRRW format */ -static void decode_rrrw_extract_insert(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrrw_extract_insert(DisasContext *ctx) { uint32_t op2; int r1, r2, r3, r4; @@ -8356,7 +8351,7 @@ static void decode_rrrw_extract_insert(CPUTriCoreState *env, DisasContext *ctx) } /* SYS Format*/ -static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx) +static void decode_sys_interrupts(DisasContext *ctx) { uint32_t op2; uint32_t r1; @@ -8391,7 +8386,7 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx) case OPC2_32_SYS_RFE: gen_helper_rfe(cpu_env); tcg_gen_exit_tb(NULL, 0); - ctx->bstate = BS_BRANCH; + ctx->base.is_jmp = DISAS_NORETURN; break; case OPC2_32_SYS_RFM: if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) { @@ -8404,7 +8399,7 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx) gen_helper_rfm(cpu_env); gen_set_label(l1); tcg_gen_exit_tb(NULL, 0); - ctx->bstate = BS_BRANCH; + ctx->base.is_jmp = DISAS_NORETURN; tcg_temp_free(tmp); } else { /* generate privilege trap */ @@ -8417,7 +8412,7 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx) gen_helper_svlcx(cpu_env); break; case OPC2_32_SYS_RESTORE: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM || (ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_UM1) { tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1], 8, 1); @@ -8443,7 +8438,7 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) +static void decode_32Bit_opc(DisasContext *ctx) { int op1; int32_t r1, r2, r3; @@ -8462,22 +8457,22 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) switch (op1) { /* ABS-format */ case OPCM_32_ABS_LDW: - decode_abs_ldw(env, ctx); + decode_abs_ldw(ctx); break; case OPCM_32_ABS_LDB: - decode_abs_ldb(env, ctx); + decode_abs_ldb(ctx); break; case OPCM_32_ABS_LDMST_SWAP: - decode_abs_ldst_swap(env, ctx); + decode_abs_ldst_swap(ctx); break; case OPCM_32_ABS_LDST_CONTEXT: - decode_abs_ldst_context(env, ctx); + decode_abs_ldst_context(ctx); break; case OPCM_32_ABS_STORE: - decode_abs_store(env, ctx); + decode_abs_store(ctx); break; case OPCM_32_ABS_STOREB_H: - decode_abs_storeb_h(env, ctx); + decode_abs_storeb_h(ctx); break; case OPC1_32_ABS_STOREQ: address = MASK_OP_ABS_OFF18(ctx->opcode); @@ -8537,44 +8532,44 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) break; /* Bit-format */ case OPCM_32_BIT_ANDACC: - decode_bit_andacc(env, ctx); + decode_bit_andacc(ctx); break; case OPCM_32_BIT_LOGICAL_T1: - decode_bit_logical_t(env, ctx); + decode_bit_logical_t(ctx); break; case OPCM_32_BIT_INSERT: - decode_bit_insert(env, ctx); + decode_bit_insert(ctx); break; case OPCM_32_BIT_LOGICAL_T2: - decode_bit_logical_t2(env, ctx); + decode_bit_logical_t2(ctx); break; case OPCM_32_BIT_ORAND: - decode_bit_orand(env, ctx); + decode_bit_orand(ctx); break; case OPCM_32_BIT_SH_LOGIC1: - decode_bit_sh_logic1(env, ctx); + decode_bit_sh_logic1(ctx); break; case OPCM_32_BIT_SH_LOGIC2: - decode_bit_sh_logic2(env, ctx); + decode_bit_sh_logic2(ctx); break; /* BO Format */ case OPCM_32_BO_ADDRMODE_POST_PRE_BASE: - decode_bo_addrmode_post_pre_base(env, ctx); + decode_bo_addrmode_post_pre_base(ctx); break; case OPCM_32_BO_ADDRMODE_BITREVERSE_CIRCULAR: - decode_bo_addrmode_bitreverse_circular(env, ctx); + decode_bo_addrmode_bitreverse_circular(ctx); break; case OPCM_32_BO_ADDRMODE_LD_POST_PRE_BASE: - decode_bo_addrmode_ld_post_pre_base(env, ctx); + decode_bo_addrmode_ld_post_pre_base(ctx); break; case OPCM_32_BO_ADDRMODE_LD_BITREVERSE_CIRCULAR: - decode_bo_addrmode_ld_bitreverse_circular(env, ctx); + decode_bo_addrmode_ld_bitreverse_circular(ctx); break; case OPCM_32_BO_ADDRMODE_STCTX_POST_PRE_BASE: - decode_bo_addrmode_stctx_post_pre_base(env, ctx); + decode_bo_addrmode_stctx_post_pre_base(ctx); break; case OPCM_32_BO_ADDRMODE_LDMST_BITREVERSE_CIRCULAR: - decode_bo_addrmode_ldmst_bitreverse_circular(env, ctx); + decode_bo_addrmode_ldmst_bitreverse_circular(ctx); break; /* BOL-format */ case OPC1_32_BOL_LD_A_LONGOFF: @@ -8588,7 +8583,7 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) case OPC1_32_BOL_LD_HU_LONGOFF: case OPC1_32_BOL_ST_B_LONGOFF: case OPC1_32_BOL_ST_H_LONGOFF: - decode_bol_opc(env, ctx, op1); + decode_bol_opc(ctx, op1); break; /* BRC Format */ case OPCM_32_BRC_EQ_NEQ: @@ -8621,20 +8616,20 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) break; /* RC Format */ case OPCM_32_RC_LOGICAL_SHIFT: - decode_rc_logical_shift(env, ctx); + decode_rc_logical_shift(ctx); break; case OPCM_32_RC_ACCUMULATOR: - decode_rc_accumulator(env, ctx); + decode_rc_accumulator(ctx); break; case OPCM_32_RC_SERVICEROUTINE: - decode_rc_serviceroutine(env, ctx); + decode_rc_serviceroutine(ctx); break; case OPCM_32_RC_MUL: - decode_rc_mul(env, ctx); + decode_rc_mul(ctx); break; /* RCPW Format */ case OPCM_32_RCPW_MASK_INSERT: - decode_rcpw_insert(env, ctx); + decode_rcpw_insert(ctx); break; /* RCRR Format */ case OPC1_32_RCRR_INSERT: @@ -8659,17 +8654,17 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) break; /* RCRW Format */ case OPCM_32_RCRW_MASK_INSERT: - decode_rcrw_insert(env, ctx); + decode_rcrw_insert(ctx); break; /* RCR Format */ case OPCM_32_RCR_COND_SELECT: - decode_rcr_cond_select(env, ctx); + decode_rcr_cond_select(ctx); break; case OPCM_32_RCR_MADD: - decode_rcr_madd(env, ctx); + decode_rcr_madd(ctx); break; case OPCM_32_RCR_MSUB: - decode_rcr_msub(env, ctx); + decode_rcr_msub(ctx); break; /* RLC Format */ case OPC1_32_RLC_ADDI: @@ -8682,38 +8677,38 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) case OPC1_32_RLC_MOV_H: case OPC1_32_RLC_MOVH_A: case OPC1_32_RLC_MTCR: - decode_rlc_opc(env, ctx, op1); + decode_rlc_opc(ctx, op1); break; /* RR Format */ case OPCM_32_RR_ACCUMULATOR: - decode_rr_accumulator(env, ctx); + decode_rr_accumulator(ctx); break; case OPCM_32_RR_LOGICAL_SHIFT: - decode_rr_logical_shift(env, ctx); + decode_rr_logical_shift(ctx); break; case OPCM_32_RR_ADDRESS: - decode_rr_address(env, ctx); + decode_rr_address(ctx); break; case OPCM_32_RR_IDIRECT: - decode_rr_idirect(env, ctx); + decode_rr_idirect(ctx); break; case OPCM_32_RR_DIVIDE: - decode_rr_divide(env, ctx); + decode_rr_divide(ctx); break; /* RR1 Format */ case OPCM_32_RR1_MUL: - decode_rr1_mul(env, ctx); + decode_rr1_mul(ctx); break; case OPCM_32_RR1_MULQ: - decode_rr1_mulq(env, ctx); + decode_rr1_mulq(ctx); break; /* RR2 format */ case OPCM_32_RR2_MUL: - decode_rr2_mul(env, ctx); + decode_rr2_mul(ctx); break; /* RRPW format */ case OPCM_32_RRPW_EXTRACT_INSERT: - decode_rrpw_extract_insert(env, ctx); + decode_rrpw_extract_insert(ctx); break; case OPC1_32_RRPW_DEXTR: r1 = MASK_OP_RRPW_S1(ctx->opcode); @@ -8732,48 +8727,48 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) break; /* RRR Format */ case OPCM_32_RRR_COND_SELECT: - decode_rrr_cond_select(env, ctx); + decode_rrr_cond_select(ctx); break; case OPCM_32_RRR_DIVIDE: - decode_rrr_divide(env, ctx); + decode_rrr_divide(ctx); break; /* RRR2 Format */ case OPCM_32_RRR2_MADD: - decode_rrr2_madd(env, ctx); + decode_rrr2_madd(ctx); break; case OPCM_32_RRR2_MSUB: - decode_rrr2_msub(env, ctx); + decode_rrr2_msub(ctx); break; /* RRR1 format */ case OPCM_32_RRR1_MADD: - decode_rrr1_madd(env, ctx); + decode_rrr1_madd(ctx); break; case OPCM_32_RRR1_MADDQ_H: - decode_rrr1_maddq_h(env, ctx); + decode_rrr1_maddq_h(ctx); break; case OPCM_32_RRR1_MADDSU_H: - decode_rrr1_maddsu_h(env, ctx); + decode_rrr1_maddsu_h(ctx); break; case OPCM_32_RRR1_MSUB_H: - decode_rrr1_msub(env, ctx); + decode_rrr1_msub(ctx); break; case OPCM_32_RRR1_MSUB_Q: - decode_rrr1_msubq_h(env, ctx); + decode_rrr1_msubq_h(ctx); break; case OPCM_32_RRR1_MSUBAD_H: - decode_rrr1_msubad_h(env, ctx); + decode_rrr1_msubad_h(ctx); break; /* RRRR format */ case OPCM_32_RRRR_EXTRACT_INSERT: - decode_rrrr_extract_insert(env, ctx); + decode_rrrr_extract_insert(ctx); break; /* RRRW format */ case OPCM_32_RRRW_EXTRACT_INSERT: - decode_rrrw_extract_insert(env, ctx); + decode_rrrw_extract_insert(ctx); break; /* SYS format */ case OPCM_32_SYS_INTERRUPTS: - decode_sys_interrupts(env, ctx); + decode_sys_interrupts(ctx); break; case OPC1_32_SYS_RSTV: tcg_gen_movi_tl(cpu_PSW_V, 0); @@ -8786,70 +8781,130 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_opc(CPUTriCoreState *env, DisasContext *ctx, int *is_branch) +static bool tricore_insn_is_16bit(uint32_t insn) { - /* 16-Bit Instruction */ - if ((ctx->opcode & 0x1) == 0) { - ctx->next_pc = ctx->pc + 2; - decode_16Bit_opc(env, ctx); - /* 32-Bit Instruction */ - } else { - ctx->next_pc = ctx->pc + 4; - decode_32Bit_opc(env, ctx); - } + return (insn & 0x1) == 0; } -void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) +static void tricore_tr_init_disas_context(DisasContextBase *dcbase, + CPUState *cs) { + DisasContext *ctx = container_of(dcbase, DisasContext, base); CPUTriCoreState *env = cs->env_ptr; - DisasContext ctx; - target_ulong pc_start; - int num_insns = 0; - - pc_start = tb->pc; - ctx.pc = pc_start; - ctx.saved_pc = -1; - ctx.tb = tb; - ctx.singlestep_enabled = cs->singlestep_enabled; - ctx.bstate = BS_NONE; - ctx.mem_idx = cpu_mmu_index(env, false); - ctx.hflags = (uint32_t)tb->flags; - - tcg_clear_temp_count(); - gen_tb_start(tb); - while (ctx.bstate == BS_NONE) { - tcg_gen_insn_start(ctx.pc); - num_insns++; - - ctx.opcode = cpu_ldl_code(env, ctx.pc); - decode_opc(env, &ctx, 0); - - if (num_insns >= max_insns || tcg_op_buf_full()) { - gen_save_pc(ctx.next_pc); - tcg_gen_exit_tb(NULL, 0); - break; - } - ctx.pc = ctx.next_pc; + ctx->mem_idx = cpu_mmu_index(env, false); + ctx->hflags = (uint32_t)ctx->base.tb->flags; +} + +static void tricore_tr_tb_start(DisasContextBase *db, CPUState *cpu) +{ +} + +static void tricore_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + + tcg_gen_insn_start(ctx->base.pc_next); +} + +static bool tricore_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu, + const CPUBreakpoint *bp) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + generate_qemu_excp(ctx, EXCP_DEBUG); + /* + * The address covered by the breakpoint must be included in + * [tb->pc, tb->pc + tb->size) in order to for it to be + * properly cleared -- thus we increment the PC here so that + * the logic setting tb->size below does the right thing. + */ + ctx->base.pc_next += 4; + return true; +} + +static bool insn_crosses_page(CPUTriCoreState *env, DisasContext *ctx) +{ + /* + * Return true if the insn at ctx->base.pc_next might cross a page boundary. + * (False positives are OK, false negatives are not.) + * Our caller ensures we are only called if dc->base.pc_next is less than + * 4 bytes from the page boundary, so we cross the page if the first + * 16 bits indicate that this is a 32 bit insn. + */ + uint16_t insn = cpu_lduw_code(env, ctx->base.pc_next); + + return !tricore_insn_is_16bit(insn); +} + + +static void tricore_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + CPUTriCoreState *env = cpu->env_ptr; + uint16_t insn_lo; + bool is_16bit; + + insn_lo = cpu_lduw_code(env, ctx->base.pc_next); + is_16bit = tricore_insn_is_16bit(insn_lo); + if (is_16bit) { + ctx->opcode = insn_lo; + ctx->pc_succ_insn = ctx->base.pc_next + 2; + decode_16Bit_opc(ctx); + } else { + uint32_t insn_hi = cpu_lduw_code(env, ctx->base.pc_next + 2); + ctx->opcode = insn_hi << 16 | insn_lo; + ctx->pc_succ_insn = ctx->base.pc_next + 4; + decode_32Bit_opc(ctx); } + ctx->base.pc_next = ctx->pc_succ_insn; - gen_tb_end(tb, num_insns); - tb->size = ctx.pc - pc_start; - tb->icount = num_insns; + if (ctx->base.is_jmp == DISAS_NEXT) { + target_ulong page_start; - if (tcg_check_temp_count()) { - printf("LEAK at %08x\n", env->PC); + page_start = ctx->base.pc_first & TARGET_PAGE_MASK; + if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE + || (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE - 3 + && insn_crosses_page(env, ctx))) { + ctx->base.is_jmp = DISAS_TOO_MANY; + } } +} -#ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) - && qemu_log_in_addr_range(pc_start)) { - qemu_log_lock(); - qemu_log("IN: %s\n", lookup_symbol(pc_start)); - log_target_disas(cs, pc_start, ctx.pc - pc_start); - qemu_log("\n"); - qemu_log_unlock(); +static void tricore_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + + switch (ctx->base.is_jmp) { + case DISAS_TOO_MANY: + gen_goto_tb(ctx, 0, ctx->base.pc_next); + break; + case DISAS_NORETURN: + break; + default: + g_assert_not_reached(); } -#endif +} + +static void tricore_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu) +{ + qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); + log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size); +} + +static const TranslatorOps tricore_tr_ops = { + .init_disas_context = tricore_tr_init_disas_context, + .tb_start = tricore_tr_tb_start, + .insn_start = tricore_tr_insn_start, + .breakpoint_check = tricore_tr_breakpoint_check, + .translate_insn = tricore_tr_translate_insn, + .tb_stop = tricore_tr_tb_stop, + .disas_log = tricore_tr_disas_log, +}; + + +void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) +{ + DisasContext ctx; + translator_loop(&tricore_tr_ops, &ctx.base, cs, tb, max_insns); } void diff --git a/target/unicore32/cpu-qom.h b/target/unicore32/cpu-qom.h index bc68e78045..7dd04515cb 100644 --- a/target/unicore32/cpu-qom.h +++ b/target/unicore32/cpu-qom.h @@ -11,7 +11,7 @@ #ifndef QEMU_UC32_CPU_QOM_H #define QEMU_UC32_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_UNICORE32_CPU "unicore32-cpu" diff --git a/target/xtensa/cpu-qom.h b/target/xtensa/cpu-qom.h index 403bd95721..9ac54241bd 100644 --- a/target/xtensa/cpu-qom.h +++ b/target/xtensa/cpu-qom.h @@ -29,7 +29,7 @@ #ifndef QEMU_XTENSA_CPU_QOM_H #define QEMU_XTENSA_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_XTENSA_CPU "xtensa-cpu" diff --git a/tests/Makefile.include b/tests/Makefile.include index 6f02dfcc01..49684fd4f4 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -149,6 +149,7 @@ check-block-$(call land,$(CONFIG_POSIX),$(CONFIG_SOFTMMU)) += tests/check-block. check-qtest-generic-y += tests/qmp-test$(EXESUF) check-qtest-generic-y += tests/qmp-cmd-test$(EXESUF) +check-qtest-generic-$(CONFIG_MODULES) += tests/modules-test$(EXESUF) check-qtest-generic-y += tests/device-introspect-test$(EXESUF) check-qtest-generic-y += tests/cdrom-test$(EXESUF) @@ -524,7 +525,7 @@ tests/check-qlit$(EXESUF): tests/check-qlit.o $(test-util-obj-y) tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y) tests/check-qom-proplist$(EXESUF): tests/check-qom-proplist.o $(test-qom-obj-y) -tests/test-char$(EXESUF): tests/test-char.o $(test-util-obj-y) $(qtest-obj-y) $(test-io-obj-y) $(chardev-obj-y) +tests/test-char$(EXESUF): tests/test-char.o $(test-util-obj-y) $(qtest-obj-y) $(test-io-obj-y) $(chardev-obj-y) tests/socket-helpers.o tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(test-block-obj-y) tests/test-aio$(EXESUF): tests/test-aio.o $(test-block-obj-y) tests/test-aio-multithread$(EXESUF): tests/test-aio-multithread.o $(test-block-obj-y) diff --git a/tests/check-qjson.c b/tests/check-qjson.c index fa2afccb0a..07a773e653 100644 --- a/tests/check-qjson.c +++ b/tests/check-qjson.c @@ -767,7 +767,7 @@ static void utf8_string(void) if (*end == ' ') { end++; } - in = strndup(tail, end - tail); + in = g_strndup(tail, end - tail); str = from_json_str(in, j, NULL); g_assert(!str); g_free(in); diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include index dbd58e548c..cf535cbd19 100644 --- a/tests/docker/Makefile.include +++ b/tests/docker/Makefile.include @@ -17,7 +17,9 @@ DOCKER_TESTS := $(notdir $(shell \ DOCKER_TOOLS := travis -DOCKER_SCRIPT=$(SRC_PATH)/tests/docker/docker.py +ENGINE := auto + +DOCKER_SCRIPT=$(SRC_PATH)/tests/docker/docker.py --engine $(ENGINE) TESTS ?= % IMAGES ?= % @@ -146,7 +148,7 @@ $(foreach i,$(filter-out $(DOCKER_PARTIAL_IMAGES),$(DOCKER_IMAGES) $(DOCKER_DEPR ) docker: - @echo 'Build QEMU and run tests inside Docker containers' + @echo 'Build QEMU and run tests inside Docker or Podman containers' @echo @echo 'Available targets:' @echo @@ -193,6 +195,8 @@ endif @echo ' EXECUTABLE=<path> Include executable in image.' @echo ' EXTRA_FILES="<path> [... <path>]"' @echo ' Include extra files in image.' + @echo ' ENGINE=auto/docker/podman' + @echo ' Specify which container engine to run.' # This rule if for directly running against an arbitrary docker target. # It is called by the expanded docker targets (e.g. make @@ -212,7 +216,7 @@ docker-run: docker-qemu-src " COPYING $(EXECUTABLE) to $(IMAGE)")) $(call quiet-command, \ $(DOCKER_SCRIPT) run \ - $(if $(NOUSER),,-u $(shell id -u)) \ + $(if $(NOUSER),,--run-as-current-user) \ --security-opt seccomp=unconfined \ $(if $V,,--rm) \ $(if $(DEBUG),-ti,) \ diff --git a/tests/docker/docker.py b/tests/docker/docker.py index 53a8c9c801..ac5baab4ca 100755 --- a/tests/docker/docker.py +++ b/tests/docker/docker.py @@ -20,6 +20,7 @@ import hashlib import atexit import uuid import argparse +import enum import tempfile import re import signal @@ -38,6 +39,26 @@ FILTERED_ENV_NAMES = ['ftp_proxy', 'http_proxy', 'https_proxy'] DEVNULL = open(os.devnull, 'wb') +class EngineEnum(enum.IntEnum): + AUTO = 1 + DOCKER = 2 + PODMAN = 3 + + def __str__(self): + return self.name.lower() + + def __repr__(self): + return str(self) + + @staticmethod + def argparse(s): + try: + return EngineEnum[s.upper()] + except KeyError: + return s + + +USE_ENGINE = EngineEnum.AUTO def _text_checksum(text): """Calculate a digest string unique to the text content""" @@ -48,9 +69,14 @@ def _file_checksum(filename): return _text_checksum(open(filename, 'rb').read()) -def _guess_docker_command(): - """ Guess a working docker command or raise exception if not found""" - commands = [["docker"], ["sudo", "-n", "docker"]] +def _guess_engine_command(): + """ Guess a working engine command or raise exception if not found""" + commands = [] + + if USE_ENGINE in [EngineEnum.AUTO, EngineEnum.PODMAN]: + commands += [["podman"]] + if USE_ENGINE in [EngineEnum.AUTO, EngineEnum.DOCKER]: + commands += [["docker"], ["sudo", "-n", "docker"]] for cmd in commands: try: # docker version will return the client details in stdout @@ -61,7 +87,7 @@ def _guess_docker_command(): except OSError: pass commands_txt = "\n".join([" " + " ".join(x) for x in commands]) - raise Exception("Cannot find working docker command. Tried:\n%s" % + raise Exception("Cannot find working engine command. Tried:\n%s" % commands_txt) @@ -190,7 +216,7 @@ def _dockerfile_preprocess(df): class Docker(object): """ Running Docker commands """ def __init__(self): - self._command = _guess_docker_command() + self._command = _guess_engine_command() self._instances = [] atexit.register(self._kill_instances) signal.signal(signal.SIGTERM, self._kill_instances) @@ -333,8 +359,18 @@ class RunCommand(SubCommand): def args(self, parser): parser.add_argument("--keep", action="store_true", help="Don't remove image when command completes") + parser.add_argument("--run-as-current-user", action="store_true", + help="Run container using the current user's uid") def run(self, args, argv): + if args.run_as_current_user: + uid = os.getuid() + argv = [ "-u", str(uid) ] + argv + docker = Docker() + if docker._command[0] == "podman": + argv = [ "--uidmap", "%d:0:1" % uid, + "--uidmap", "0:1:%d" % uid, + "--uidmap", "%d:%d:64536" % (uid + 1, uid + 1)] + argv return Docker().run(argv, args.keep, quiet=args.quiet) @@ -502,6 +538,8 @@ class ProbeCommand(SubCommand): print("yes") elif docker._command[0] == "sudo": print("sudo") + elif docker._command[0] == "podman": + print("podman") except Exception: print("no") @@ -597,9 +635,13 @@ class CheckCommand(SubCommand): def main(): + global USE_ENGINE + parser = argparse.ArgumentParser(description="A Docker helper", usage="%s <subcommand> ..." % os.path.basename(sys.argv[0])) + parser.add_argument("--engine", type=EngineEnum.argparse, choices=list(EngineEnum), + help="specify which container engine to use") subparsers = parser.add_subparsers(title="subcommands", help=None) for cls in SubCommand.__subclasses__(): cmd = cls() @@ -608,6 +650,7 @@ def main(): cmd.args(subp) subp.set_defaults(cmdobj=cmd) args, argv = parser.parse_known_args() + USE_ENGINE = args.engine return args.cmdobj.run(args, argv) diff --git a/tests/libqtest.c b/tests/libqtest.c index eb971d0d11..2713b86cf7 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -811,6 +811,12 @@ bool qtest_get_irq(QTestState *s, int num) return s->irq_level[num]; } +void qtest_module_load(QTestState *s, const char *prefix, const char *libname) +{ + qtest_sendf(s, "module_load %s %s\n", prefix, libname); + qtest_rsp(s, 0); +} + static int64_t qtest_clock_rsp(QTestState *s) { gchar **words; diff --git a/tests/libqtest.h b/tests/libqtest.h index 7833148358..07ea35867c 100644 --- a/tests/libqtest.h +++ b/tests/libqtest.h @@ -262,6 +262,8 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3); char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0); +void qtest_module_load(QTestState *s, const char *prefix, const char *libname); + /** * qtest_get_irq: * @s: #QTestState instance to operate on. diff --git a/tests/migration/stress.c b/tests/migration/stress.c index 49a03aab7b..d9aa4afe92 100644 --- a/tests/migration/stress.c +++ b/tests/migration/stress.c @@ -104,9 +104,9 @@ static int get_command_arg_str(const char *name, } if (end) - *val = strndup(start, end - start); + *val = g_strndup(start, end - start); else - *val = strdup(start); + *val = g_strdup(start); return 1; } @@ -126,10 +126,10 @@ static int get_command_arg_ull(const char *name, if (errno || *end) { fprintf(stderr, "%s (%05d): ERROR: cannot parse %s value %s\n", argv0, gettid(), name, valstr); - free(valstr); + g_free(valstr); return -1; } - free(valstr); + g_free(valstr); return 0; } diff --git a/tests/modules-test.c b/tests/modules-test.c new file mode 100644 index 0000000000..f9de3afdb7 --- /dev/null +++ b/tests/modules-test.c @@ -0,0 +1,68 @@ +#include "qemu/osdep.h" +#include "libqtest.h" + +static void test_modules_load(const void *data) +{ + QTestState *qts; + const char **args = (const char **)data; + + qts = qtest_init(NULL); + qtest_module_load(qts, args[0], args[1]); + qtest_quit(qts); +} + +int main(int argc, char *argv[]) +{ + const char *modules[] = { +#ifdef CONFIG_CURL + "block-", "curl", +#endif +#ifdef CONFIG_GLUSTERFS + "block-", "gluster", +#endif +#ifdef CONFIG_LIBISCSI + "block-", "iscsi", +#endif +#ifdef CONFIG_LIBNFS + "block-", "nfs", +#endif +#ifdef CONFIG_LIBSSH + "block-", "ssh", +#endif +#ifdef CONFIG_RBD + "block-", "rbd", +#endif +#ifdef CONFIG_AUDIO_ALSA + "audio-", "alsa", +#endif +#ifdef CONFIG_AUDIO_OSS + "audio-", "oss", +#endif +#ifdef CONFIG_AUDIO_PA + "audio-", "pa", +#endif +#ifdef CONFIG_AUDIO_SDL + "audio-", "sdl", +#endif +#ifdef CONFIG_CURSES + "ui-", "curses", +#endif +#if defined(CONFIG_GTK) && defined(CONFIG_VTE) + "ui-", "gtk", +#endif +#ifdef CONFIG_SDL + "ui-", "sdl", +#endif + }; + int i; + + g_test_init(&argc, &argv, NULL); + + for (i = 0; i < G_N_ELEMENTS(modules); i += 2) { + char *testname = g_strdup_printf("/module/load/%s", modules[i + 1]); + qtest_add_data_func(testname, modules + i, test_modules_load); + g_free(testname); + } + + return g_test_run(); +} diff --git a/tests/socket-helpers.c b/tests/socket-helpers.c index 8112763f5b..19a51e887e 100644 --- a/tests/socket-helpers.c +++ b/tests/socket-helpers.c @@ -30,7 +30,16 @@ # define EAI_ADDRFAMILY 0 #endif -int socket_can_bind_connect(const char *hostname) +/* + * @hostname: a DNS name or numeric IP address + * + * Check whether it is possible to bind & connect to ports + * on the DNS name or IP address @hostname. If an IP address + * is used, it must not be a wildcard address. + * + * Returns 0 on success, -1 on error with errno set + */ +static int socket_can_bind_connect(const char *hostname, int family) { int lfd = -1, cfd = -1, afd = -1; struct addrinfo ai, *res = NULL; @@ -44,7 +53,7 @@ int socket_can_bind_connect(const char *hostname) memset(&ai, 0, sizeof(ai)); ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; - ai.ai_family = AF_UNSPEC; + ai.ai_family = family; ai.ai_socktype = SOCK_STREAM; /* lookup */ @@ -129,7 +138,7 @@ int socket_check_protocol_support(bool *has_ipv4, bool *has_ipv6) { *has_ipv4 = *has_ipv6 = false; - if (socket_can_bind_connect("127.0.0.1") < 0) { + if (socket_can_bind_connect("127.0.0.1", PF_INET) < 0) { if (errno != EADDRNOTAVAIL) { return -1; } @@ -137,7 +146,7 @@ int socket_check_protocol_support(bool *has_ipv4, bool *has_ipv6) *has_ipv4 = true; } - if (socket_can_bind_connect("::1") < 0) { + if (socket_can_bind_connect("::1", PF_INET6) < 0) { if (errno != EADDRNOTAVAIL) { return -1; } diff --git a/tests/socket-helpers.h b/tests/socket-helpers.h index 9de0e6b151..512a004811 100644 --- a/tests/socket-helpers.h +++ b/tests/socket-helpers.h @@ -21,17 +21,6 @@ #define TESTS_SOCKET_HELPERS_H /* - * @hostname: a DNS name or numeric IP address - * - * Check whether it is possible to bind & connect to ports - * on the DNS name or IP address @hostname. If an IP address - * is used, it must not be a wildcard address. - * - * Returns 0 on success, -1 on error with errno set - */ -int socket_can_bind_connect(const char *hostname); - -/* * @has_ipv4: set to true on return if IPv4 is available * @has_ipv6: set to true on return if IPv6 is available * diff --git a/tests/test-char.c b/tests/test-char.c index f9440cdcfd..b56e43c1eb 100644 --- a/tests/test-char.c +++ b/tests/test-char.c @@ -15,6 +15,7 @@ #include "io/channel-socket.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qapi-visit-sockets.h" +#include "socket-helpers.h" static bool quit; @@ -1356,11 +1357,18 @@ static void char_hotswap_test(void) int main(int argc, char **argv) { + bool has_ipv4, has_ipv6; + qemu_init_main_loop(&error_abort); socket_init(); g_test_init(&argc, &argv, NULL); + if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) { + g_printerr("socket_check_protocol_support() failed\n"); + goto end; + } + module_call_init(MODULE_INIT_QOM); qemu_add_opts(&qemu_chardev_opts); @@ -1438,10 +1446,12 @@ int main(int argc, char **argv) g_test_add_data_func("/char/socket/client/wait-conn-fdpass/" # name, \ &client6 ##name, char_socket_client_test) - SOCKET_SERVER_TEST(tcp, &tcpaddr); - SOCKET_CLIENT_TEST(tcp, &tcpaddr); - g_test_add_data_func("/char/socket/server/two-clients/tcp", &tcpaddr, - char_socket_server_two_clients_test); + if (has_ipv4) { + SOCKET_SERVER_TEST(tcp, &tcpaddr); + SOCKET_CLIENT_TEST(tcp, &tcpaddr); + g_test_add_data_func("/char/socket/server/two-clients/tcp", &tcpaddr, + char_socket_server_two_clients_test); + } #ifndef WIN32 SOCKET_SERVER_TEST(unix, &unixaddr); SOCKET_CLIENT_TEST(unix, &unixaddr); @@ -1456,5 +1466,6 @@ int main(int argc, char **argv) g_test_add_func("/char/hotswap", char_hotswap_test); g_test_add_func("/char/websocket", char_websock_test); +end: return g_test_run(); } diff --git a/tests/test-io-channel-socket.c b/tests/test-io-channel-socket.c index d2053c464c..d172f3070f 100644 --- a/tests/test-io-channel-socket.c +++ b/tests/test-io-channel-socket.c @@ -566,7 +566,8 @@ int main(int argc, char **argv) * with either IPv4 or IPv6 disabled. */ if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) { - return 1; + g_printerr("socket_check_protocol_support() failed\n"); + goto end; } if (has_ipv4) { @@ -595,5 +596,6 @@ int main(int argc, char **argv) test_io_channel_unix_listen_cleanup); #endif /* _WIN32 */ +end: return g_test_run(); } diff --git a/tests/test-util-sockets.c b/tests/test-util-sockets.c index f1ebffee5a..e2a3a8a093 100644 --- a/tests/test-util-sockets.c +++ b/tests/test-util-sockets.c @@ -242,7 +242,8 @@ int main(int argc, char **argv) * with either IPv4 or IPv6 disabled. */ if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) { - return 1; + g_printerr("socket_check_protocol_support() failed\n"); + goto end; } if (has_ipv4) { @@ -264,5 +265,6 @@ int main(int argc, char **argv) test_socket_fd_pass_num_nocli); } +end: return g_test_run(); } diff --git a/trace-events b/trace-events index aeea3c2bdb..823a4ae64e 100644 --- a/trace-events +++ b/trace-events @@ -129,7 +129,7 @@ vcpu guest_cpu_enter(void) # Targets: all vcpu guest_cpu_exit(void) -# qom/cpu.c +# hw/core/cpu.c # Reset the state of a virtual (guest) CPU # diff --git a/trace/control-vcpu.h b/trace/control-vcpu.h index a8f1035c2e..0f98ebe7b5 100644 --- a/trace/control-vcpu.h +++ b/trace/control-vcpu.h @@ -12,7 +12,7 @@ #include "control.h" #include "event-internal.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" /** * trace_event_get_vcpu_state: diff --git a/ui/cocoa.m b/ui/cocoa.m index f023d5166f..f12e21df6e 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -40,7 +40,7 @@ #include "qemu/main-loop.h" #include "qemu/module.h" #include <Carbon/Carbon.h> -#include "qom/cpu.h" +#include "hw/core/cpu.h" #ifndef MAC_OS_X_VERSION_10_5 #define MAC_OS_X_VERSION_10_5 1050 diff --git a/ui/curses.c b/ui/curses.c index a6e260eb96..ec281125ac 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -225,6 +225,8 @@ static wint_t console_getch(enum maybe_keycode *maybe_keycode) case ERR: ret = -1; break; + default: + abort(); } return ret; } diff --git a/ui/input-linux.c b/ui/input-linux.c index 59456fe765..a7b280b25b 100644 --- a/ui/input-linux.c +++ b/ui/input-linux.c @@ -113,6 +113,10 @@ static bool input_linux_check_toggle(InputLinux *il) return il->keydown[KEY_LEFTALT] && il->keydown[KEY_RIGHTALT]; + case GRAB_TOGGLE_KEYS_SHIFT_SHIFT: + return il->keydown[KEY_LEFTSHIFT] && + il->keydown[KEY_RIGHTSHIFT]; + case GRAB_TOGGLE_KEYS_META_META: return il->keydown[KEY_LEFTMETA] && il->keydown[KEY_RIGHTMETA]; diff --git a/util/module.c b/util/module.c index 142db7e911..e9fe3e5422 100644 --- a/util/module.c +++ b/util/module.c @@ -156,8 +156,10 @@ out: } #endif -void module_load_one(const char *prefix, const char *lib_name) +bool module_load_one(const char *prefix, const char *lib_name) { + bool success = false; + #ifdef CONFIG_MODULES char *fname = NULL; char *exec_dir; @@ -170,7 +172,7 @@ void module_load_one(const char *prefix, const char *lib_name) if (!g_module_supported()) { fprintf(stderr, "Module is not supported by system.\n"); - return; + return false; } if (!loaded_modules) { @@ -179,11 +181,10 @@ void module_load_one(const char *prefix, const char *lib_name) module_name = g_strdup_printf("%s%s", prefix, lib_name); - if (g_hash_table_lookup(loaded_modules, module_name)) { + if (!g_hash_table_add(loaded_modules, module_name)) { g_free(module_name); - return; + return true; } - g_hash_table_insert(loaded_modules, module_name, module_name); exec_dir = qemu_get_exec_dir(); search_dir = getenv("QEMU_MODULE_DIR"); @@ -206,13 +207,19 @@ void module_load_one(const char *prefix, const char *lib_name) fname = NULL; /* Try loading until loaded a module file */ if (!ret) { + success = true; break; } } + if (!success) { + g_hash_table_remove(loaded_modules, module_name); + } + for (i = 0; i < n_dirs; i++) { g_free(dirs[i]); } #endif + return success; } @@ -772,7 +772,7 @@ static time_t qemu_ref_timedate(QEMUClockType clock) switch (clock) { case QEMU_CLOCK_REALTIME: value -= rtc_realtime_clock_offset; - /* no break */ + /* fall through */ case QEMU_CLOCK_VIRTUAL: value += rtc_ref_start_datetime; break; |