aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS58
-rw-r--r--Makefile3
-rw-r--r--block/nbd.c71
-rw-r--r--cpu-exec.c9
-rw-r--r--disas.c10
-rw-r--r--docs/build-system.txt507
-rw-r--r--hmp-commands-info.hx32
-rw-r--r--hw/arm/armv7m.c2
-rw-r--r--hw/cris/boot.c2
-rw-r--r--hw/i386/kvm/ioapic.c10
-rw-r--r--hw/i386/multiboot.c2
-rw-r--r--hw/intc/apic.c22
-rw-r--r--hw/intc/ioapic.c20
-rw-r--r--hw/intc/ioapic_common.c55
-rw-r--r--hw/lm32/lm32_boards.c4
-rw-r--r--hw/lm32/milkymist.c2
-rw-r--r--hw/m68k/an5206.c2
-rw-r--r--hw/m68k/dummy_m68k.c2
-rw-r--r--hw/m68k/mcf5208.c2
-rw-r--r--hw/microblaze/boot.c4
-rw-r--r--hw/mips/mips_fulong2e.c2
-rw-r--r--hw/mips/mips_malta.c2
-rw-r--r--hw/mips/mips_mipssim.c2
-rw-r--r--hw/mips/mips_r4k.c2
-rw-r--r--hw/moxie/moxiesim.c4
-rw-r--r--hw/openrisc/openrisc_sim.c2
-rw-r--r--hw/ppc/e500.c2
-rw-r--r--hw/ppc/mac_newworld.c4
-rw-r--r--hw/ppc/mac_oldworld.c4
-rw-r--r--hw/ppc/ppc440_bamboo.c2
-rw-r--r--hw/ppc/prep.c2
-rw-r--r--hw/ppc/spapr.c4
-rw-r--r--hw/ppc/virtex_ml507.c2
-rw-r--r--hw/s390x/ipl.c4
-rw-r--r--hw/scsi/scsi-generic.c14
-rw-r--r--hw/scsi/vhost-scsi.c1
-rw-r--r--hw/sparc/leon3.c2
-rw-r--r--hw/sparc/sun4m.c4
-rw-r--r--hw/sparc64/sun4u.c4
-rw-r--r--hw/tricore/tricore_testboard.c2
-rw-r--r--hw/xtensa/sim.c4
-rw-r--r--hw/xtensa/xtfpga.c2
-rw-r--r--include/elf.h3
-rw-r--r--include/hw/elf_ops.h23
-rw-r--r--include/hw/i386/apic_internal.h96
-rw-r--r--include/hw/i386/ioapic_internal.h7
-rw-r--r--include/hw/i386/pc.h5
-rw-r--r--include/hw/virtio/vhost-scsi.h25
-rw-r--r--include/monitor/hmp-target.h3
-rw-r--r--include/monitor/monitor.h1
-rw-r--r--include/qemu-common.h27
-rw-r--r--include/qemu/option.h5
-rw-r--r--include/qemu/typedefs.h3
-rw-r--r--linux-user/elfload.c37
-rw-r--r--monitor.c7
-rw-r--r--qapi/opts-visitor.c4
-rw-r--r--qemu-img.c5
-rw-r--r--qemu-io-cmds.c2
-rw-r--r--qemu-nbd.c102
-rw-r--r--qemu-tech.texi73
-rwxr-xr-xscripts/checkpatch.pl4
-rwxr-xr-xscripts/get_maintainer.pl22
-rw-r--r--target-alpha/cpu.h2
-rw-r--r--target-arm/cpu.h2
-rw-r--r--target-cris/cpu.h2
-rw-r--r--target-i386/cpu.c14
-rw-r--r--target-i386/cpu.h7
-rw-r--r--target-i386/helper.c191
-rw-r--r--target-i386/monitor.c17
-rw-r--r--target-i386/seg_helper.c3
-rw-r--r--target-lm32/cpu.h2
-rw-r--r--target-m68k/cpu.h2
-rw-r--r--target-microblaze/cpu.h2
-rw-r--r--target-mips/cpu.h2
-rw-r--r--target-moxie/cpu.h2
-rw-r--r--target-openrisc/cpu.h1
-rw-r--r--target-ppc/cpu.h4
-rw-r--r--target-s390x/cpu.h1
-rw-r--r--target-sh4/cpu.h2
-rw-r--r--target-sparc/cpu.h6
-rw-r--r--target-tricore/cpu.h2
-rw-r--r--target-unicore32/cpu.h2
-rw-r--r--target-xtensa/cpu.h1
-rw-r--r--tests/test-cutils.c91
-rw-r--r--util/cutils.c25
85 files changed, 1341 insertions, 386 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 7aff1627b6..e3e34fb4b1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -77,6 +77,7 @@ S: Maintained
F: target-alpha/
F: hw/alpha/
F: tests/tcg/alpha/
+F: disas/alpha.c
ARM
M: Peter Maydell <peter.maydell@linaro.org>
@@ -84,6 +85,9 @@ S: Maintained
F: target-arm/
F: hw/arm/
F: hw/cpu/a*mpcore.c
+F: disas/arm.c
+F: disas/arm-a64.cc
+F: disas/libvixl/
CRIS
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
@@ -91,6 +95,7 @@ S: Maintained
F: target-cris/
F: hw/cris/
F: tests/tcg/cris/
+F: disas/cris.c
LM32
M: Michael Walle <michael@walle.cc>
@@ -114,6 +119,7 @@ M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
S: Maintained
F: target-microblaze/
F: hw/microblaze/
+F: disas/microblaze.c
MIPS
M: Aurelien Jarno <aurelien@aurel32.net>
@@ -122,11 +128,13 @@ S: Maintained
F: target-mips/
F: hw/mips/
F: tests/tcg/mips/
+F: disas/mips.c
Moxie
M: Anthony Green <green@moxielogic.com>
S: Maintained
F: target-moxie/
+F: disas/moxie.c
OpenRISC
M: Jia Liu <proljc@gmail.com>
@@ -141,6 +149,7 @@ L: qemu-ppc@nongnu.org
S: Maintained
F: target-ppc/
F: hw/ppc/
+F: disas/ppc.c
S390
M: Richard Henderson <rth@twiddle.net>
@@ -148,12 +157,14 @@ M: Alexander Graf <agraf@suse.de>
S: Maintained
F: target-s390x/
F: hw/s390x/
+F: disas/s390.c
SH4
M: Aurelien Jarno <aurelien@aurel32.net>
S: Odd Fixes
F: target-sh4/
F: hw/sh4/
+F: disas/sh4.c
SPARC
M: Blue Swirl <blauwirbel@gmail.com>
@@ -162,6 +173,7 @@ S: Maintained
F: target-sparc/
F: hw/sparc/
F: hw/sparc64/
+F: disas/sparc.c
UniCore32
M: Guan Xuetao <gxt@mprc.pku.edu.cn>
@@ -176,6 +188,7 @@ M: Eduardo Habkost <ehabkost@redhat.com>
S: Maintained
F: target-i386/
F: hw/i386/
+F: disas/i386.c
Xtensa
M: Max Filippov <jcmvbkbc@gmail.com>
@@ -564,6 +577,7 @@ M: Cornelia Huck <cornelia.huck@de.ibm.com>
M: Christian Borntraeger <borntraeger@de.ibm.com>
M: Alexander Graf <agraf@suse.de>
S: Supported
+F: hw/char/sclp*.[hc]
F: hw/s390x/s390-virtio-ccw.c
F: hw/s390x/css.[hc]
F: hw/s390x/sclp*.[hc]
@@ -668,6 +682,12 @@ M: Peter Maydell <peter.maydell@linaro.org>
S: Maintained
F: hw/*/omap*
+IPack
+M: Alberto Garcia <berto@igalia.com>
+S: Odd Fixes
+F: hw/char/ipoctal232.c
+F: hw/ipack/
+
PCI
M: Michael S. Tsirkin <mst@redhat.com>
S: Supported
@@ -704,6 +724,17 @@ L: qemu-ppc@nongnu.org
S: Supported
F: hw/ppc/e500*
+Character devices
+M: Paolo Bonzini <pbonzini@redhat.com>
+S: Odd Fixes
+F: hw/char/
+
+Network devices
+M: Jason Wang <jasowang@redhat.com>
+S: Odd Fixes
+F: hw/net/
+T: git git://github.com/jasowang/qemu.git net
+
SCSI
M: Paolo Bonzini <pbonzini@redhat.com>
S: Supported
@@ -888,7 +919,7 @@ F: block/qapi.c
F: qapi/block*.json
T: git git://repo.or.cz/qemu/armbru.git block-next
-Character Devices
+Character device backends
M: Paolo Bonzini <pbonzini@redhat.com>
S: Maintained
F: qemu-char.c
@@ -983,7 +1014,7 @@ F: hmp.c
F: hmp-commands.hx
T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
-Network device layer
+Network device backends
M: Jason Wang <jasowang@redhat.com>
S: Maintained
F: net/
@@ -1137,53 +1168,58 @@ M: Claudio Fontana <claudio.fontana@huawei.com>
M: Claudio Fontana <claudio.fontana@gmail.com>
S: Maintained
F: tcg/aarch64/
+F: disas/arm-a64.cc
+F: disas/libvixl/
ARM target
M: Andrzej Zaborowski <balrogg@gmail.com>
S: Maintained
F: tcg/arm/
+F: disas/arm.c
i386 target
L: qemu-devel@nongnu.org
S: Maintained
F: tcg/i386/
+F: disas/i386.c
IA64 target
M: Aurelien Jarno <aurelien@aurel32.net>
S: Maintained
F: tcg/ia64/
+F: disas/ia64.c
MIPS target
M: Aurelien Jarno <aurelien@aurel32.net>
S: Maintained
F: tcg/mips/
+F: disas/mips.c
PPC
M: Vassili Karpov (malc) <av1474@comtv.ru>
S: Maintained
F: tcg/ppc/
-
-PPC64 target
-M: Vassili Karpov (malc) <av1474@comtv.ru>
-S: Maintained
-F: tcg/ppc64/
+F: disas/ppc.c
S390 target
M: Alexander Graf <agraf@suse.de>
M: Richard Henderson <rth@twiddle.net>
S: Maintained
F: tcg/s390/
+F: disas/s390.c
SPARC target
M: Blue Swirl <blauwirbel@gmail.com>
S: Maintained
F: tcg/sparc/
+F: disas/sparc.c
TCI target
M: Stefan Weil <sw@weilnetz.de>
S: Maintained
F: tcg/tci/
F: tci.c
+F: disas/tci.c
Stable branches
---------------
@@ -1393,3 +1429,11 @@ M: Stefan Hajnoczi <stefanha@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: tests/image-fuzzer/
+
+
+Documentation
+-------------
+Build system architecture
+M: Daniel P. Berrange <berrange@redhat.com>
+S: Odd Fixes
+F: docs/build-system.txt
diff --git a/Makefile b/Makefile
index 68e2e1b3fe..e370876d1c 100644
--- a/Makefile
+++ b/Makefile
@@ -176,7 +176,6 @@ SOFTMMU_SUBDIR_RULES=$(filter %-softmmu,$(SUBDIR_RULES))
$(SOFTMMU_SUBDIR_RULES): $(block-obj-y)
$(SOFTMMU_SUBDIR_RULES): $(crypto-obj-y)
-$(SOFTMMU_SUBDIR_RULES): $(qom-obj-y)
$(SOFTMMU_SUBDIR_RULES): config-all-devices.mak
subdir-%:
@@ -201,7 +200,7 @@ subdir-dtc:dtc/libfdt dtc/tests
dtc/%:
mkdir -p $@
-$(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y)
+$(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y) $(qom-obj-y) $(crypto-aes-obj-$(CONFIG_USER_ONLY))
ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
romsubdir-%:
diff --git a/block/nbd.c b/block/nbd.c
index 217618612d..c2a87e99bb 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -43,7 +43,6 @@
typedef struct BDRVNBDState {
NbdClientSession client;
- QemuOpts *socket_opts;
} BDRVNBDState;
static int nbd_parse_uri(const char *filename, QDict *options)
@@ -190,10 +189,10 @@ out:
g_free(file);
}
-static void nbd_config(BDRVNBDState *s, QDict *options, char **export,
- Error **errp)
+static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, char **export,
+ Error **errp)
{
- Error *local_err = NULL;
+ SocketAddress *saddr;
if (qdict_haskey(options, "path") == qdict_haskey(options, "host")) {
if (qdict_haskey(options, "path")) {
@@ -201,28 +200,37 @@ static void nbd_config(BDRVNBDState *s, QDict *options, char **export,
} else {
error_setg(errp, "one of path and host must be specified.");
}
- return;
+ return NULL;
}
- s->client.is_unix = qdict_haskey(options, "path");
- s->socket_opts = qemu_opts_create(&socket_optslist, NULL, 0,
- &error_abort);
+ saddr = g_new0(SocketAddress, 1);
- qemu_opts_absorb_qdict(s->socket_opts, options, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
+ if (qdict_haskey(options, "path")) {
+ saddr->kind = SOCKET_ADDRESS_KIND_UNIX;
+ saddr->q_unix = g_new0(UnixSocketAddress, 1);
+ saddr->q_unix->path = g_strdup(qdict_get_str(options, "path"));
+ qdict_del(options, "path");
+ } else {
+ saddr->kind = SOCKET_ADDRESS_KIND_INET;
+ saddr->inet = g_new0(InetSocketAddress, 1);
+ saddr->inet->host = g_strdup(qdict_get_str(options, "host"));
+ if (!qdict_get_try_str(options, "port")) {
+ saddr->inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
+ } else {
+ saddr->inet->port = g_strdup(qdict_get_str(options, "port"));
+ }
+ qdict_del(options, "host");
+ qdict_del(options, "port");
}
- if (!qemu_opt_get(s->socket_opts, "port")) {
- qemu_opt_set_number(s->socket_opts, "port", NBD_DEFAULT_PORT,
- &error_abort);
- }
+ s->client.is_unix = saddr->kind == SOCKET_ADDRESS_KIND_UNIX;
*export = g_strdup(qdict_get_try_str(options, "export"));
if (*export) {
qdict_del(options, "export");
}
+
+ return saddr;
}
NbdClientSession *nbd_get_client_session(BlockDriverState *bs)
@@ -231,26 +239,24 @@ NbdClientSession *nbd_get_client_session(BlockDriverState *bs)
return &s->client;
}
-static int nbd_establish_connection(BlockDriverState *bs, Error **errp)
+static int nbd_establish_connection(BlockDriverState *bs,
+ SocketAddress *saddr,
+ Error **errp)
{
BDRVNBDState *s = bs->opaque;
int sock;
- if (s->client.is_unix) {
- sock = unix_connect_opts(s->socket_opts, errp, NULL, NULL);
- } else {
- sock = inet_connect_opts(s->socket_opts, errp, NULL, NULL);
- if (sock >= 0) {
- socket_set_nodelay(sock);
- }
- }
+ sock = socket_connect(saddr, errp, NULL, NULL);
- /* Failed to establish connection */
if (sock < 0) {
logout("Failed to establish connection to NBD server\n");
return -EIO;
}
+ if (!s->client.is_unix) {
+ socket_set_nodelay(sock);
+ }
+
return sock;
}
@@ -260,19 +266,19 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
BDRVNBDState *s = bs->opaque;
char *export = NULL;
int result, sock;
- Error *local_err = NULL;
+ SocketAddress *saddr;
/* Pop the config into our state object. Exit if invalid. */
- nbd_config(s, options, &export, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
+ saddr = nbd_config(s, options, &export, errp);
+ if (!saddr) {
return -EINVAL;
}
/* establish TCP connection, return error if it fails
* TODO: Configurable retry-until-timeout behaviour.
*/
- sock = nbd_establish_connection(bs, errp);
+ sock = nbd_establish_connection(bs, saddr, errp);
+ qapi_free_SocketAddress(saddr);
if (sock < 0) {
g_free(export);
return sock;
@@ -315,9 +321,6 @@ static int nbd_co_discard(BlockDriverState *bs, int64_t sector_num,
static void nbd_close(BlockDriverState *bs)
{
- BDRVNBDState *s = bs->opaque;
-
- qemu_opts_del(s->socket_opts);
nbd_client_close(bs);
}
diff --git a/cpu-exec.c b/cpu-exec.c
index 947e646ae4..8fd56a69e0 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -27,6 +27,9 @@
#include "exec/address-spaces.h"
#include "qemu/rcu.h"
#include "exec/tb-hash.h"
+#if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY)
+#include "hw/i386/apic.h"
+#endif
/* -icount align implementation. */
@@ -343,6 +346,12 @@ int cpu_exec(CPUState *cpu)
SyncClocks sc;
if (cpu->halted) {
+#if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY)
+ if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
+ apic_poll_irq(x86_cpu->apic_state);
+ cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
+ }
+#endif
if (!cpu_has_work(cpu)) {
return EXCP_HALTED;
}
diff --git a/disas.c b/disas.c
index 0ae70c22f7..45878fad2f 100644
--- a/disas.c
+++ b/disas.c
@@ -392,16 +392,6 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
return 0;
}
-static int GCC_FMT_ATTR(2, 3)
-monitor_fprintf(FILE *stream, const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- monitor_vprintf((Monitor *)stream, fmt, ap);
- va_end(ap);
- return 0;
-}
-
/* Disassembler for the monitor.
See target_disas for a description of flags. */
void monitor_disas(Monitor *mon, CPUState *cpu,
diff --git a/docs/build-system.txt b/docs/build-system.txt
new file mode 100644
index 0000000000..5ddddeaafb
--- /dev/null
+++ b/docs/build-system.txt
@@ -0,0 +1,507 @@
+ The QEMU build system architecture
+ ==================================
+
+This document aims to help developers understand the architecture of the
+QEMU build system. As with projects using GNU autotools, the QEMU build
+system has two stages, first the developer runs the "configure" script
+to determine the local build environment characteristics, then they run
+"make" to build the project. There is about where the similarities with
+GNU autotools end, so try to forget what you know about them.
+
+
+Stage 1: configure
+==================
+
+The QEMU configure script is written directly in shell, and should be
+compatible with any POSIX shell, hence it uses #!/bin/sh. An important
+implication of this is that it is important to avoid using bash-isms on
+development platforms where bash is the primary host.
+
+In contrast to autoconf scripts, QEMU's configure is expected to be
+silent while it is checking for features. It will only display output
+when an error occurs, or to show the final feature enablement summary
+on completion.
+
+Adding new checks to the configure script usually comprises the
+following tasks:
+
+ - Initialize one or more variables with the default feature state.
+
+ Ideally features should auto-detect whether they are present,
+ so try to avoid hardcoding the initial state to either enabled
+ or disabled, as that forces the user to pass a --enable-XXX
+ / --disable-XXX flag on every invocation of configure.
+
+ - Add support to the command line arg parser to handle any new
+ --enable-XXX / --disable-XXX flags required by the feature XXX.
+
+ - Add information to the help output message to report on the new
+ feature flag.
+
+ - Add code to perform the actual feature check. As noted above, try to
+ be fully dynamic in checking enablement/disablement.
+
+ - Add code to print out the feature status in the configure summary
+ upon completion.
+
+ - Add any new makefile variables to $config_host_mak on completion.
+
+
+Taking (a simplified version of) the probe for gnutls from configure,
+we have the following pieces:
+
+ # Initial variable state
+ gnutls=""
+
+ ..snip..
+
+ # Configure flag processing
+ --disable-gnutls) gnutls="no"
+ ;;
+ --enable-gnutls) gnutls="yes"
+ ;;
+
+ ..snip..
+
+ # Help output feature message
+ gnutls GNUTLS cryptography support
+
+ ..snip..
+
+ # Test for gnutls
+ if test "$gnutls" != "no"; then
+ if ! $pkg_config --exists "gnutls"; then
+ gnutls_cflags=`$pkg_config --cflags gnutls`
+ gnutls_libs=`$pkg_config --libs gnutls`
+ libs_softmmu="$gnutls_libs $libs_softmmu"
+ libs_tools="$gnutls_libs $libs_tools"
+ QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
+ gnutls="yes"
+ elif test "$gnutls" = "yes"; then
+ feature_not_found "gnutls" "Install gnutls devel"
+ else
+ gnutls="no"
+ fi
+ fi
+
+ ..snip..
+
+ # Completion feature summary
+ echo "GNUTLS support $gnutls"
+
+ ..snip..
+
+ # Define make variables
+ if test "$gnutls" = "yes" ; then
+ echo "CONFIG_GNUTLS=y" >> $config_host_mak
+ fi
+
+
+Helper functions
+----------------
+
+The configure script provides a variety of helper functions to assist
+developers in checking for system features:
+
+ - do_cc $ARGS...
+
+ Attempt to run the system C compiler passing it $ARGS...
+
+ - do_cxx $ARGS...
+
+ Attempt to run the system C++ compiler passing it $ARGS...
+
+ - compile_object $CFLAGS
+
+ Attempt to compile a test program with the system C compiler using
+ $CFLAGS. The test program must have been previously written to a file
+ called $TMPC.
+
+ - compile_prog $CFLAGS $LDFLAGS
+
+ Attempt to compile a test program with the system C compiler using
+ $CFLAGS and link it with the system linker using $LDFLAGS. The test
+ program must have been previously written to a file called $TMPC.
+
+ - has $COMMAND
+
+ Determine if $COMMAND exists in the current environment, either as a
+ shell builtin, or executable binary, returning 0 on success.
+
+ - path_of $COMMAND
+
+ Return the fully qualified path of $COMMAND, printing it to stdout,
+ and returning 0 on success.
+
+ - check_define $NAME
+
+ Determine if the macro $NAME is defined by the system C compiler
+
+ - check_include $NAME
+
+ Determine if the include $NAME file is available to the system C
+ compiler
+
+ - write_c_skeleton
+
+ Write a minimal C program main() function to the temporary file
+ indicated by $TMPC
+
+ - feature_not_found $NAME $REMEDY
+
+ Print a message to stderr that the feature $NAME was not available
+ on the system, suggesting the user try $REMEDY to address the
+ problem.
+
+ - error_exit $MESSAGE $MORE...
+
+ Print $MESSAGE to stderr, followed by $MORE... and then exit from the
+ configure script with non-zero status
+
+ - query_pkg_config $ARGS...
+
+ Run pkg-config passing it $ARGS. If QEMU is doing a static build,
+ then --static will be automatically added to $ARGS
+
+
+Stage 2: makefiles
+==================
+
+The use of GNU make is required with the QEMU build system.
+
+Although the source code is spread across multiple subdirectories, the
+build system should be considered largely non-recursive in nature, in
+contrast to common practices seen with automake. There is some recursive
+invocation of make, but this is related to the things being built,
+rather than the source directory structure.
+
+QEMU currently supports both VPATH and non-VPATH builds, so there are
+three general ways to invoke configure & perform a build.
+
+ - VPATH, build artifacts outside of QEMU source tree entirely
+
+ cd ../
+ mkdir build
+ cd build
+ ../qemu/configure
+ make
+
+ - VPATH, build artifacts in a subdir of QEMU source tree
+
+ mkdir build
+ cd build
+ ../configure
+ make
+
+ - non-VPATH, build artifacts everywhere
+
+ ./configure
+ make
+
+The QEMU maintainers generally recommend that a VPATH build is used by
+developers. Patches to QEMU are expected to ensure VPATH build still
+works.
+
+
+Module structure
+----------------
+
+There are a number of key outputs of the QEMU build system:
+
+ - Tools - qemu-img, qemu-nbd, qga (guest agent), etc
+ - System emulators - qemu-system-$ARCH
+ - Userspace emulators - qemu-$ARCH
+ - Unit tests
+
+The source code is highly modularized, split across many files to
+facilitate building of all of these components with as little duplicated
+compilation as possible. There can be considered to be two distinct
+groups of files, those which are independent of the QEMU emulation
+target and those which are dependent on the QEMU emulation target.
+
+In the target-independent set lives various general purpose helper code,
+such as error handling infrastructure, standard data structures,
+platform portability wrapper functions, etc. This code can be compiled
+once only and the .o files linked into all output binaries.
+
+In the target-dependent set lives CPU emulation, device emulation and
+much glue code. This sometimes also has to be compiled multiple times,
+once for each target being built.
+
+The utility code that is used by all binaries is built into a
+static archive called libqemuutil.a, which is then linked to all the
+binaries. In order to provide hooks that are only needed by some of the
+binaries, code in libqemuutil.a may depend on other functions that are
+not fully implemented by all QEMU binaries. To deal with this there is a
+second library called libqemustub.a which provides dummy stubs for all
+these functions. These will get lazy linked into the binary if the real
+implementation is not present. In this way, the libqemustub.a static
+library can be thought of as a portable implementation of the weak
+symbols concept. All binaries should link to both libqemuutil.a and
+libqemustub.a. e.g.
+
+ qemu-img$(EXESUF): qemu-img.o ..snip.. libqemuutil.a libqemustub.a
+
+
+Windows platform portability
+----------------------------
+
+On Windows, all binaries have the suffix '.exe', so all Makefile rules
+which create binaries must include the $(EXESUF) variable on the binary
+name. e.g.
+
+ qemu-img$(EXESUF): qemu-img.o ..snip..
+
+This expands to '.exe' on Windows, or '' on other platforms.
+
+A further complication for the system emulator binaries is that
+two separate binaries need to be generated.
+
+The main binary (e.g. qemu-system-x86_64.exe) is linked against the
+Windows console runtime subsystem. These are expected to be run from a
+command prompt window, and so will print stderr to the console that
+launched them.
+
+The second binary generated has a 'w' on the end of its name (e.g.
+qemu-system-x86_64w.exe) and is linked against the Windows graphical
+runtime subsystem. These are expected to be run directly from the
+desktop and will open up a dedicated console window for stderr output.
+
+The Makefile.target will generate the binary for the graphical subsystem
+first, and then use objcopy to relink it against the console subsystem
+to generate the second binary.
+
+
+Object variable naming
+----------------------
+
+The QEMU convention is to define variables to list different groups of
+object files. These are named with the convention $PREFIX-obj-y. For
+example the libqemuutil.a file will be linked with all objects listed
+in a variable 'util-obj-y'. So, for example, util/Makefile.obj will
+contain a set of definitions looking like
+
+ util-obj-y += bitmap.o bitops.o hbitmap.o
+ util-obj-y += fifo8.o
+ util-obj-y += acl.o
+ util-obj-y += error.o qemu-error.o
+
+When there is an object file which needs to be conditionally built based
+on some characteristic of the host system, the configure script will
+define a variable for the conditional. For example, on Windows it will
+define $(CONFIG_POSIX) with a value of 'n' and $(CONFIG_WIN32) with a
+value of 'y'. It is now possible to use the config variables when
+listing object files. For example,
+
+ util-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o
+ util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o
+
+On Windows this expands to
+
+ util-obj-y += oslib-win32.o qemu-thread-win32.o
+ util-obj-n += oslib-posix.o qemu-thread-posix.o
+
+Since libqemutil.a links in $(util-obj-y), the POSIX specific files
+listed against $(util-obj-n) are ignored on the Windows platform builds.
+
+
+CFLAGS / LDFLAGS / LIBS handling
+--------------------------------
+
+There are many different binaries being built with differing purposes,
+and some of them might even be 3rd party libraries pulled in via git
+submodules. As such the use of the global CFLAGS variable is generally
+avoided in QEMU, since it would apply to too many build targets.
+
+Flags that are needed by any QEMU code (i.e. everything *except* GIT
+submodule projects) are put in $(QEMU_CFLAGS) variable. For linker
+flags the $(LIBS) variable is sometimes used, but a couple of more
+targeted variables are preferred. $(libs_softmmu) is used for
+libraries that must be linked to system emulator targets, $(LIBS_TOOLS)
+is used for tools like qemu-img, qemu-nbd, etc and $(LIBS_QGA) is used
+for the QEMU guest agent. There is currently no specific variable for
+the userspace emulator targets as the global $(LIBS), or more targeted
+variables shown below, are sufficient.
+
+In addition to these variables, it is possible to provide cflags and
+libs against individual source code files, by defining variables of the
+form $FILENAME-cflags and $FILENAME-libs. For example, the curl block
+driver needs to link to the libcurl library, so block/Makefile defines
+some variables:
+
+ curl.o-cflags := $(CURL_CFLAGS)
+ curl.o-libs := $(CURL_LIBS)
+
+The scope is a little different between the two variables. The libs get
+used when linking any target binary that includes the curl.o object
+file, while the cflags get used when compiling the curl.c file only.
+
+
+Statically defined files
+------------------------
+
+The following key files are statically defined in the source tree, with
+the rules needed to build QEMU. Their behaviour is influenced by a
+number of dynamically created files listed later.
+
+- Makefile
+
+The main entry point used when invoking make to build all the components
+of QEMU. The default 'all' target will naturally result in the build of
+every component. The various tools and helper binaries are built
+directly via a non-recursive set of rules.
+
+Each system/userspace emulation target needs to have a slightly
+different set of make rules / variables. Thus, make will be recursively
+invoked for each of the emulation targets.
+
+The recursive invocation will end up processing the toplevel
+Makefile.target file (more on that later).
+
+
+- */Makefile.objs
+
+Since the source code is spread across multiple directories, the rules
+for each file are similarly modularized. Thus each subdirectory
+containing .c files will usually also contain a Makefile.objs file.
+These files are not directly invoked by a recursive make, but instead
+they are imported by the top level Makefile and/or Makefile.target
+
+Each Makefile.objs usually just declares a set of variables listing the
+.o files that need building from the source files in the directory. They
+will also define any custom linker or compiler flags. For example in
+block/Makefile.objs
+
+ block-obj-$(CONFIG_LIBISCSI) += iscsi.o
+ block-obj-$(CONFIG_CURL) += curl.o
+
+ ..snip...
+
+ iscsi.o-cflags := $(LIBISCSI_CFLAGS)
+ iscsi.o-libs := $(LIBISCSI_LIBS)
+ curl.o-cflags := $(CURL_CFLAGS)
+ curl.o-libs := $(CURL_LIBS)
+
+If there are any rules defined in the Makefile.objs file, they should
+all use $(obj) as a prefix to the target, e.g.
+
+ $(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp
+
+
+- Makefile.target
+
+This file provides the entry point used to build each individual system
+or userspace emulator target. Each enabled target has its own
+subdirectory. For example if configure is run with the argument
+'--target-list=x86_64-softmmu', then a sub-directory 'x86_64-softmu'
+will be created, containing a 'Makefile' which symlinks back to
+Makefile.target
+
+So when the recursive '$(MAKE) -C x86_64-softmmu' is invoked, it ends up
+using Makefile.target for the build rules.
+
+
+- rules.mak
+
+This file provides the generic helper rules for invoking build tools, in
+particular the compiler and linker. This also contains the magic (hairy)
+'unnest-vars' function which is used to merge the variable definitions
+from all Makefile.objs in the source tree down into the main Makefile
+context.
+
+
+- default-configs/*.mak
+
+The files under default-configs/ control what emulated hardware is built
+into each QEMU system and userspace emulator targets. They merely
+contain a long list of config variable definitions. For example,
+default-configs/x86_64-softmmu.mak has:
+
+ include pci.mak
+ include sound.mak
+ include usb.mak
+ CONFIG_QXL=$(CONFIG_SPICE)
+ CONFIG_VGA_ISA=y
+ CONFIG_VGA_CIRRUS=y
+ CONFIG_VMWARE_VGA=y
+ CONFIG_VIRTIO_VGA=y
+ ...snip...
+
+These files rarely need changing unless new devices / hardware need to
+be enabled for a particular system/userspace emulation target
+
+
+- tests/Makefile
+
+Rules for building the unit tests. This file is included directly by the
+top level Makefile, so anything defined in this file will influence the
+entire build system. Care needs to be taken when writing rules for tests
+to ensure they only apply to the unit test execution / build.
+
+
+- po/Makefile
+
+Rules for building and installing the binary message catalogs from the
+text .po file sources. This almost never needs changing for any reason.
+
+
+Dynamically created files
+-------------------------
+
+The following files are generated dynamically by configure in order to
+control the behaviour of the statically defined makefiles. This avoids
+the need for QEMU makefiles to go through any pre-processing as seen
+with autotools, where Makefile.am generates Makefile.in which generates
+Makefile.
+
+
+- config-host.mak
+
+When configure has determined the characteristics of the build host it
+will write a long list of variables to config-host.mak file. This
+provides the various install directories, compiler / linker flags and a
+variety of CONFIG_* variables related to optionally enabled features.
+This is imported by the top level Makefile in order to tailor the build
+output.
+
+The variables defined here are those which are applicable to all QEMU
+build outputs. Variables which are potentially different for each
+emulator target are defined by the next file...
+
+It is also used as a dependency checking mechanism. If make sees that
+the modification timestamp on configure is newer than that on
+config-host.mak, then configure will be re-run.
+
+
+- config-host.h
+
+The config-host.h file is used by source code to determine what features
+are enabled. It is generated from the contents of config-host.mak using
+the scripts/create_config program. This extracts all the CONFIG_* variables,
+most of the HOST_* variables and a few other misc variables from
+config-host.mak, formatting them as C preprocessor macros.
+
+
+- $TARGET-NAME/config-target.mak
+
+TARGET-NAME is the name of a system or userspace emulator, for example,
+x86_64-softmmu denotes the system emulator for the x86_64 architecture.
+This file contains the variables which need to vary on a per-target
+basis. For example, it will indicate whether KVM or Xen are enabled for
+the target and any other potential custom libraries needed for linking
+the target.
+
+
+- $TARGET-NAME/config-devices.mak
+
+TARGET-NAME is again the name of a system or userspace emulator. The
+config-devices.mak file is automatically generated by make using the
+scripts/make_device_config.sh program, feeding it the
+default-configs/$TARGET-NAME file as input.
+
+
+- $TARGET-NAME/Makefile
+
+This is the entrypoint used when make recurses to build a single system
+or userspace emulator target. It is merely a symlink back to the
+Makefile.target in the top level.
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 94a2afefd5..9b71351d01 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -112,6 +112,38 @@ STEXI
Show the cpu registers.
ETEXI
+#if defined(TARGET_I386)
+ {
+ .name = "lapic",
+ .args_type = "",
+ .params = "",
+ .help = "show local apic state",
+ .mhandler.cmd = hmp_info_local_apic,
+ },
+#endif
+
+STEXI
+@item info lapic
+@findex lapic
+Show local APIC state
+ETEXI
+
+#if defined(TARGET_I386)
+ {
+ .name = "ioapic",
+ .args_type = "",
+ .params = "",
+ .help = "show io apic state",
+ .mhandler.cmd = hmp_info_io_apic,
+ },
+#endif
+
+STEXI
+@item info ioapic
+@findex ioapic
+Show io APIC state
+ETEXI
+
{
.name = "cpus",
.args_type = "",
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 40334d7561..eb214db443 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -215,7 +215,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
if (kernel_filename) {
image_size = load_elf(kernel_filename, NULL, NULL, &entry, &lowaddr,
- NULL, big_endian, ELF_MACHINE, 1);
+ NULL, big_endian, EM_ARM, 1);
if (image_size < 0) {
image_size = load_image_targphys(kernel_filename, 0, mem_size);
lowaddr = 0;
diff --git a/hw/cris/boot.c b/hw/cris/boot.c
index 622f353c9a..1cfa339c24 100644
--- a/hw/cris/boot.c
+++ b/hw/cris/boot.c
@@ -72,7 +72,7 @@ void cris_load_image(CRISCPU *cpu, struct cris_load_info *li)
/* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis
devboard SDK. */
image_size = load_elf(li->image_filename, translate_kernel_address, NULL,
- &entry, NULL, &high, 0, ELF_MACHINE, 0);
+ &entry, NULL, &high, 0, EM_CRIS, 0);
li->entry = entry;
if (image_size < 0) {
/* Takes a kimage from the axis devboard SDK. */
diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c
index d2a6c4cf60..b7390ca0da 100644
--- a/hw/i386/kvm/ioapic.c
+++ b/hw/i386/kvm/ioapic.c
@@ -10,6 +10,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "monitor/monitor.h"
#include "hw/i386/pc.h"
#include "hw/i386/ioapic_internal.h"
#include "hw/i386/apic_internal.h"
@@ -110,6 +111,15 @@ static void kvm_ioapic_put(IOAPICCommonState *s)
}
}
+void kvm_ioapic_dump_state(Monitor *mon, const QDict *qdict)
+{
+ IOAPICCommonState s;
+
+ kvm_ioapic_get(&s);
+
+ ioapic_print_redtbl(mon, &s);
+}
+
static void kvm_ioapic_reset(DeviceState *dev)
{
IOAPICCommonState *s = IOAPIC_COMMON(dev);
diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
index 1adbe9e25f..6774a1932e 100644
--- a/hw/i386/multiboot.c
+++ b/hw/i386/multiboot.c
@@ -195,7 +195,7 @@ int load_multiboot(FWCfgState *fw_cfg,
}
kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry,
- &elf_low, &elf_high, 0, ELF_MACHINE, 0);
+ &elf_low, &elf_high, 0, I386_ELF_MACHINE, 0);
if (kernel_size < 0) {
fprintf(stderr, "Error while loading elf kernel\n");
exit(1);
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index 77b639cce8..0a840b851f 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -51,14 +51,6 @@ static int apic_ffs_bit(uint32_t value)
return ctz32(value);
}
-static inline void apic_set_bit(uint32_t *tab, int index)
-{
- int i, mask;
- i = index >> 5;
- mask = 1 << (index & 0x1f);
- tab[i] |= mask;
-}
-
static inline void apic_reset_bit(uint32_t *tab, int index)
{
int i, mask;
@@ -67,14 +59,6 @@ static inline void apic_reset_bit(uint32_t *tab, int index)
tab[i] &= ~mask;
}
-static inline int apic_get_bit(uint32_t *tab, int index)
-{
- int i, mask;
- i = index >> 5;
- mask = 1 << (index & 0x1f);
- return !!(tab[i] & mask);
-}
-
/* return -1 if no bit is set */
static int get_highest_priority_int(uint32_t *tab)
{
@@ -318,7 +302,7 @@ static uint8_t apic_get_tpr(APICCommonState *s)
return s->tpr >> 4;
}
-static int apic_get_ppr(APICCommonState *s)
+int apic_get_ppr(APICCommonState *s)
{
int tpr, isrv, ppr;
@@ -739,7 +723,7 @@ static uint32_t apic_mem_readl(void *opaque, hwaddr addr)
val = s->divide_conf;
break;
default:
- s->esr |= ESR_ILLEGAL_ADDRESS;
+ s->esr |= APIC_ESR_ILLEGAL_ADDRESS;
val = 0;
break;
}
@@ -852,7 +836,7 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val)
}
break;
default:
- s->esr |= ESR_ILLEGAL_ADDRESS;
+ s->esr |= APIC_ESR_ILLEGAL_ADDRESS;
break;
}
}
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index b527932382..de2dd4ba8e 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -20,6 +20,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "monitor/monitor.h"
#include "hw/hw.h"
#include "hw/i386/pc.h"
#include "hw/i386/ioapic.h"
@@ -98,7 +99,9 @@ static void ioapic_set_irq(void *opaque, int vector, int level)
/* level triggered */
if (level) {
s->irr |= mask;
- ioapic_service(s);
+ if (!(entry & IOAPIC_LVT_REMOTE_IRR)) {
+ ioapic_service(s);
+ }
} else {
s->irr &= ~mask;
}
@@ -137,6 +140,17 @@ void ioapic_eoi_broadcast(int vector)
}
}
+void ioapic_dump_state(Monitor *mon, const QDict *qdict)
+{
+ int i;
+
+ for (i = 0; i < MAX_IOAPICS; i++) {
+ if (ioapics[i] != 0) {
+ ioapic_print_redtbl(mon, ioapics[i]);
+ }
+ }
+}
+
static uint64_t
ioapic_mem_read(void *opaque, hwaddr addr, unsigned int size)
{
@@ -154,15 +168,13 @@ ioapic_mem_read(void *opaque, hwaddr addr, unsigned int size)
}
switch (s->ioregsel) {
case IOAPIC_REG_ID:
+ case IOAPIC_REG_ARB:
val = s->id << IOAPIC_ID_SHIFT;
break;
case IOAPIC_REG_VER:
val = IOAPIC_VERSION |
((IOAPIC_NUM_PINS - 1) << IOAPIC_VER_ENTRIES_SHIFT);
break;
- case IOAPIC_REG_ARB:
- val = 0;
- break;
default:
index = (s->ioregsel - IOAPIC_REG_REDTBL_BASE) >> 1;
if (index >= 0 && index < IOAPIC_NUM_PINS) {
diff --git a/hw/intc/ioapic_common.c b/hw/intc/ioapic_common.c
index 8b7d11806c..65f6877d79 100644
--- a/hw/intc/ioapic_common.c
+++ b/hw/intc/ioapic_common.c
@@ -19,6 +19,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "monitor/monitor.h"
#include "hw/i386/ioapic.h"
#include "hw/i386/ioapic_internal.h"
#include "hw/sysbus.h"
@@ -31,6 +32,60 @@
*/
int ioapic_no;
+static void ioapic_irr_dump(Monitor *mon, const char *name, uint32_t bitmap)
+{
+ int i;
+
+ monitor_printf(mon, "%-10s ", name);
+ if (bitmap == 0) {
+ monitor_printf(mon, "(none)\n");
+ return;
+ }
+ for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+ if (bitmap & (1 << i)) {
+ monitor_printf(mon, "%-2u ", i);
+ }
+ }
+ monitor_printf(mon, "\n");
+}
+
+void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s)
+{
+ static const char *delm_str[] = {
+ "fixed", "lowest", "SMI", "...", "NMI", "INIT", "...", "extINT"};
+ uint32_t remote_irr = 0;
+ int i;
+
+ monitor_printf(mon, "ioapic id=0x%02x sel=0x%02x", s->id, s->ioregsel);
+ if (s->ioregsel) {
+ monitor_printf(mon, " (redir[%u])\n",
+ (s->ioregsel - IOAPIC_REG_REDTBL_BASE) >> 1);
+ } else {
+ monitor_printf(mon, "\n");
+ }
+ for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+ uint64_t entry = s->ioredtbl[i];
+ uint32_t delm = (uint32_t)((entry & IOAPIC_LVT_DELIV_MODE) >>
+ IOAPIC_LVT_DELIV_MODE_SHIFT);
+ monitor_printf(mon, "pin %-2u 0x%016"PRIx64" dest=%"PRIx64
+ " vec=%-3"PRIu64" %s %-5s %-6s %-6s %s\n",
+ i, entry,
+ (entry >> IOAPIC_LVT_DEST_SHIFT) &
+ (entry & IOAPIC_LVT_DEST_MODE ? 0xff : 0xf),
+ entry & IOAPIC_VECTOR_MASK,
+ entry & IOAPIC_LVT_POLARITY ? "active-lo" : "active-hi",
+ entry & IOAPIC_LVT_TRIGGER_MODE ? "level" : "edge",
+ entry & IOAPIC_LVT_MASKED ? "masked" : "",
+ delm_str[delm],
+ entry & IOAPIC_LVT_DEST_MODE ? "logical" : "physical");
+
+ remote_irr |= entry & IOAPIC_LVT_TRIGGER_MODE ?
+ (entry & IOAPIC_LVT_REMOTE_IRR ? (1 << i) : 0) : 0;
+ }
+ ioapic_irr_dump(mon, "IRR", s->irr);
+ ioapic_irr_dump(mon, "Remote IRR", remote_irr);
+}
+
void ioapic_reset_common(DeviceState *dev)
{
IOAPICCommonState *s = IOAPIC_COMMON(dev);
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index 8e17a82a40..eb553a174e 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -142,7 +142,7 @@ static void lm32_evr_init(MachineState *machine)
int kernel_size;
kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL,
- 1, ELF_MACHINE, 0);
+ 1, EM_LATTICEMICO32, 0);
reset_info->bootstrap_pc = entry;
if (kernel_size < 0) {
@@ -244,7 +244,7 @@ static void lm32_uclinux_init(MachineState *machine)
int kernel_size;
kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL,
- 1, ELF_MACHINE, 0);
+ 1, EM_LATTICEMICO32, 0);
reset_info->bootstrap_pc = entry;
if (kernel_size < 0) {
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index cb308500b4..13976b3489 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -176,7 +176,7 @@ milkymist_init(MachineState *machine)
/* Boots a kernel elf binary. */
kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL,
- 1, ELF_MACHINE, 0);
+ 1, EM_LATTICEMICO32, 0);
reset_info->bootstrap_pc = entry;
if (kernel_size < 0) {
diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
index aa49cd5c42..c1dea17f33 100644
--- a/hw/m68k/an5206.c
+++ b/hw/m68k/an5206.c
@@ -70,7 +70,7 @@ static void an5206_init(MachineState *machine)
}
kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry,
- NULL, NULL, 1, ELF_MACHINE, 0);
+ NULL, NULL, 1, EM_68K, 0);
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL,
diff --git a/hw/m68k/dummy_m68k.c b/hw/m68k/dummy_m68k.c
index d4f2073e37..8b3b77597d 100644
--- a/hw/m68k/dummy_m68k.c
+++ b/hw/m68k/dummy_m68k.c
@@ -49,7 +49,7 @@ static void dummy_m68k_init(MachineState *machine)
/* Load kernel. */
if (kernel_filename) {
kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry,
- NULL, NULL, 1, ELF_MACHINE, 0);
+ NULL, NULL, 1, EM_68K, 0);
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL,
diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index c3365eb21d..ddeccc5064 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -275,7 +275,7 @@ static void mcf5208evb_init(MachineState *machine)
}
kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry,
- NULL, NULL, 1, ELF_MACHINE, 0);
+ NULL, NULL, 1, EM_68K, 0);
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL,
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 3e8820f365..d7eaa1f022 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -141,12 +141,12 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
/* Boots a kernel elf binary. */
kernel_size = load_elf(kernel_filename, NULL, NULL,
&entry, &low, &high,
- big_endian, ELF_MACHINE, 0);
+ big_endian, EM_MICROBLAZE, 0);
base32 = entry;
if (base32 == 0xc0000000) {
kernel_size = load_elf(kernel_filename, translate_kernel_address,
NULL, &entry, NULL, NULL,
- big_endian, ELF_MACHINE, 0);
+ big_endian, EM_MICROBLAZE, 0);
}
/* Always boot into physical ram. */
boot_info.bootstrap_pc = (uint32_t)entry;
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index e44521ffa9..5988a88c0b 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -116,7 +116,7 @@ static int64_t load_kernel (CPUMIPSState *env)
if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
(uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
- (uint64_t *)&kernel_high, 0, ELF_MACHINE, 1) < 0) {
+ (uint64_t *)&kernel_high, 0, EM_MIPS, 1) < 0) {
fprintf(stderr, "qemu: could not load kernel '%s'\n",
loaderparams.kernel_filename);
exit(1);
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index bb864fe908..c1f570a79f 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -795,7 +795,7 @@ static int64_t load_kernel (void)
if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
(uint64_t *)&kernel_entry, NULL, (uint64_t *)&kernel_high,
- big_endian, ELF_MACHINE, 1) < 0) {
+ big_endian, EM_MIPS, 1) < 0) {
fprintf(stderr, "qemu: could not load kernel '%s'\n",
loaderparams.kernel_filename);
exit(1);
diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
index e65131266c..23b35bea21 100644
--- a/hw/mips/mips_mipssim.c
+++ b/hw/mips/mips_mipssim.c
@@ -69,7 +69,7 @@ static int64_t load_kernel(void)
kernel_size = load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys,
NULL, (uint64_t *)&entry, NULL,
(uint64_t *)&kernel_high, big_endian,
- ELF_MACHINE, 1);
+ EM_MIPS, 1);
if (kernel_size >= 0) {
if ((entry & ~0x7fffffffULL) == 0x80000000)
entry = (int32_t)entry;
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index 97628fc5fe..af10da1c57 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -87,7 +87,7 @@ static int64_t load_kernel(void)
kernel_size = load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys,
NULL, (uint64_t *)&entry, NULL,
(uint64_t *)&kernel_high, big_endian,
- ELF_MACHINE, 1);
+ EM_MIPS, 1);
if (kernel_size >= 0) {
if ((entry & ~0x7fffffffULL) == 0x80000000)
entry = (int32_t)entry;
diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c
index a3d1a1ba2a..ada3d58829 100644
--- a/hw/moxie/moxiesim.c
+++ b/hw/moxie/moxiesim.c
@@ -34,6 +34,7 @@
#include "hw/loader.h"
#include "hw/char/serial.h"
#include "exec/address-spaces.h"
+#include "elf.h"
#define PHYS_MEM_BASE 0x80000000
@@ -52,8 +53,7 @@ static void load_kernel(MoxieCPU *cpu, LoaderParams *loader_params)
ram_addr_t initrd_offset;
kernel_size = load_elf(loader_params->kernel_filename, NULL, NULL,
- &entry, &kernel_low, &kernel_high, 1,
- ELF_MACHINE, 0);
+ &entry, &kernel_low, &kernel_high, 1, EM_MOXIE, 0);
if (kernel_size <= 0) {
fprintf(stderr, "qemu: could not load kernel '%s'\n",
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 5f267850e0..be6c9b5622 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -68,7 +68,7 @@ static void cpu_openrisc_load_kernel(ram_addr_t ram_size,
if (kernel_filename && !qtest_enabled()) {
kernel_size = load_elf(kernel_filename, NULL, NULL,
- &elf_entry, NULL, NULL, 1, ELF_MACHINE, 1);
+ &elf_entry, NULL, NULL, 1, EM_OPENRISC, 1);
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(kernel_filename,
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index e968386ff6..b3418dbae4 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -1017,7 +1017,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
bios_size = load_elf(filename, NULL, NULL, &bios_entry, &loadaddr, NULL,
- 1, ELF_MACHINE, 0);
+ 1, PPC_ELF_MACHINE, 0);
if (bios_size < 0) {
/*
* Hrm. No ELF image? Try a uImage, maybe someone is giving us an
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index e1c5ed76bd..66d016c6fa 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -219,7 +219,7 @@ static void ppc_core99_init(MachineState *machine)
/* Load OpenBIOS (ELF) */
if (filename) {
bios_size = load_elf(filename, NULL, NULL, NULL,
- NULL, NULL, 1, ELF_MACHINE, 0);
+ NULL, NULL, 1, PPC_ELF_MACHINE, 0);
g_free(filename);
} else {
@@ -242,7 +242,7 @@ static void ppc_core99_init(MachineState *machine)
kernel_base = KERNEL_LOAD_ADDR;
kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
- NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);
+ NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, 0);
if (kernel_size < 0)
kernel_size = load_aout(kernel_filename, kernel_base,
ram_size - kernel_base, bswap_needed,
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 5cba2cb145..21eaf0e66b 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -147,7 +147,7 @@ static void ppc_heathrow_init(MachineState *machine)
/* Load OpenBIOS (ELF) */
if (filename) {
bios_size = load_elf(filename, 0, NULL, NULL, NULL, NULL,
- 1, ELF_MACHINE, 0);
+ 1, PPC_ELF_MACHINE, 0);
g_free(filename);
} else {
bios_size = -1;
@@ -168,7 +168,7 @@ static void ppc_heathrow_init(MachineState *machine)
#endif
kernel_base = KERNEL_LOAD_ADDR;
kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
- NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);
+ NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, 0);
if (kernel_size < 0)
kernel_size = load_aout(kernel_filename, kernel_base,
ram_size - kernel_base, bswap_needed,
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index ada676cc24..b66c11338d 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -256,7 +256,7 @@ static void bamboo_init(MachineState *machine)
NULL, NULL);
if (success < 0) {
success = load_elf(kernel_filename, NULL, NULL, &elf_entry,
- &elf_lowaddr, NULL, 1, ELF_MACHINE, 0);
+ &elf_lowaddr, NULL, 1, PPC_ELF_MACHINE, 0);
entry = elf_entry;
loadaddr = elf_lowaddr;
}
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 9d6d70a16c..d95222bd7d 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -601,7 +601,7 @@ static void ppc_prep_init(MachineState *machine)
bios_name = BIOS_FILENAME;
}
qdev_prop_set_string(dev, "bios-name", bios_name);
- qdev_prop_set_uint32(dev, "elf-machine", ELF_MACHINE);
+ qdev_prop_set_uint32(dev, "elf-machine", PPC_ELF_MACHINE);
pcihost = PCI_HOST_BRIDGE(dev);
object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL);
qdev_init_nofail(dev);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 7f4f196e53..a9b5f2a669 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1860,11 +1860,11 @@ static void ppc_spapr_init(MachineState *machine)
uint64_t lowaddr = 0;
kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
- NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);
+ NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, 0);
if (kernel_size == ELF_LOAD_WRONG_ENDIAN) {
kernel_size = load_elf(kernel_filename,
translate_kernel_address, NULL,
- NULL, &lowaddr, NULL, 0, ELF_MACHINE, 0);
+ NULL, &lowaddr, NULL, 0, PPC_ELF_MACHINE, 0);
kernel_le = kernel_size > 0;
}
if (kernel_size < 0) {
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 457d762a1c..c2b5e441a5 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -257,7 +257,7 @@ static void virtex_init(MachineState *machine)
/* Boots a kernel elf binary. */
kernel_size = load_elf(kernel_filename, NULL, NULL,
- &entry, &low, &high, 1, ELF_MACHINE, 0);
+ &entry, &low, &high, 1, PPC_ELF_MACHINE, 0);
boot_info.bootstrap_pc = entry & 0x00ffffff;
if (kernel_size < 0) {
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 2e0a8b6e0c..31473e749e 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -132,7 +132,7 @@ static int s390_ipl_init(SysBusDevice *dev)
bios_size = load_elf(bios_filename, bios_translate_addr, &fwbase,
&ipl->bios_start_addr, NULL, NULL, 1,
- ELF_MACHINE, 0);
+ EM_S390, 0);
if (bios_size > 0) {
/* Adjust ELF start address to final location */
ipl->bios_start_addr += fwbase;
@@ -154,7 +154,7 @@ static int s390_ipl_init(SysBusDevice *dev)
if (ipl->kernel) {
kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL,
- NULL, 1, ELF_MACHINE, 0);
+ NULL, 1, EM_S390, 0);
if (kernel_size < 0) {
kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);
}
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 1b6350be41..a4626f72c1 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -210,6 +210,20 @@ static void scsi_read_complete(void * opaque, int ret)
}
blk_set_guest_block_size(s->conf.blk, s->blocksize);
+ /* Patch MODE SENSE device specific parameters if the BDS is opened
+ * readonly.
+ */
+ if ((s->type == TYPE_DISK || s->type == TYPE_TAPE) &&
+ blk_is_read_only(s->conf.blk) &&
+ (r->req.cmd.buf[0] == MODE_SENSE ||
+ r->req.cmd.buf[0] == MODE_SENSE_10) &&
+ (r->req.cmd.buf[1] & 0x8) == 0) {
+ if (r->req.cmd.buf[0] == MODE_SENSE) {
+ r->buf[2] |= 0x80;
+ } else {
+ r->buf[3] |= 0x80;
+ }
+ }
scsi_req_data(&r->req, len);
scsi_req_unref(&r->req);
}
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index bac9ddb1d9..fb7983d9dc 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -26,6 +26,7 @@
#include "hw/virtio/virtio-bus.h"
#include "hw/virtio/virtio-access.h"
#include "hw/fw-path-provider.h"
+#include "linux/vhost.h"
/* Features supported by host kernel. */
static const int kernel_feature_bits[] = {
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index ee73fea8a4..22d1e7e31b 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -193,7 +193,7 @@ static void leon3_generic_hw_init(MachineState *machine)
uint64_t entry;
kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL,
- 1 /* big endian */, ELF_MACHINE, 0);
+ 1 /* big endian */, EM_SPARC, 0);
if (kernel_size < 0) {
fprintf(stderr, "qemu: could not load kernel '%s'\n",
kernel_filename);
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 9f1917fbe1..230dac955b 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -300,7 +300,7 @@ static unsigned long sun4m_load_kernel(const char *kernel_filename,
bswap_needed = 0;
#endif
kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
- NULL, NULL, NULL, 1, ELF_MACHINE, 0);
+ NULL, NULL, NULL, 1, EM_SPARC, 0);
if (kernel_size < 0)
kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
RAM_size - KERNEL_LOAD_ADDR, bswap_needed,
@@ -744,7 +744,7 @@ static void prom_init(hwaddr addr, const char *bios_name)
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) {
ret = load_elf(filename, translate_prom_address, &addr, NULL,
- NULL, NULL, 1, ELF_MACHINE, 0);
+ NULL, NULL, 1, EM_SPARC, 0);
if (ret < 0 || ret > PROM_SIZE_MAX) {
ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
}
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index a6b59572fc..d6b929cf8f 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -208,7 +208,7 @@ static uint64_t sun4u_load_kernel(const char *kernel_filename,
bswap_needed = 0;
#endif
kernel_size = load_elf(kernel_filename, NULL, NULL, kernel_entry,
- kernel_addr, &kernel_top, 1, ELF_MACHINE, 0);
+ kernel_addr, &kernel_top, 1, EM_SPARCV9, 0);
if (kernel_size < 0) {
*kernel_addr = KERNEL_LOAD_ADDR;
*kernel_entry = KERNEL_LOAD_ADDR;
@@ -671,7 +671,7 @@ static void prom_init(hwaddr addr, const char *bios_name)
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) {
ret = load_elf(filename, translate_prom_address, &addr,
- NULL, NULL, NULL, 1, ELF_MACHINE, 0);
+ NULL, NULL, NULL, 1, EM_SPARCV9, 0);
if (ret < 0 || ret > PROM_SIZE_MAX) {
ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
}
diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c
index 8532410756..4ff5e7b685 100644
--- a/hw/tricore/tricore_testboard.c
+++ b/hw/tricore/tricore_testboard.c
@@ -44,7 +44,7 @@ static void tricore_load_kernel(CPUTriCoreState *env)
kernel_size = load_elf(tricoretb_binfo.kernel_filename, NULL,
NULL, (uint64_t *)&entry, NULL,
NULL, 0,
- ELF_MACHINE, 1);
+ EM_TRICORE, 1);
if (kernel_size <= 0) {
error_report("qemu: no kernel file '%s'",
tricoretb_binfo.kernel_filename);
diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c
index aa1cd107ce..6266b8d446 100644
--- a/hw/xtensa/sim.c
+++ b/hw/xtensa/sim.c
@@ -93,10 +93,10 @@ static void xtensa_sim_init(MachineState *machine)
uint64_t elf_lowaddr;
#ifdef TARGET_WORDS_BIGENDIAN
int success = load_elf(kernel_filename, translate_phys_addr, cpu,
- &elf_entry, &elf_lowaddr, NULL, 1, ELF_MACHINE, 0);
+ &elf_entry, &elf_lowaddr, NULL, 1, EM_XTENSA, 0);
#else
int success = load_elf(kernel_filename, translate_phys_addr, cpu,
- &elf_entry, &elf_lowaddr, NULL, 0, ELF_MACHINE, 0);
+ &elf_entry, &elf_lowaddr, NULL, 0, EM_XTENSA, 0);
#endif
if (success > 0) {
env->pc = elf_entry;
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index 7aca1cf9da..72350f1418 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -341,7 +341,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
uint64_t elf_entry;
uint64_t elf_lowaddr;
int success = load_elf(kernel_filename, translate_phys_addr, cpu,
- &elf_entry, &elf_lowaddr, NULL, be, ELF_MACHINE, 0);
+ &elf_entry, &elf_lowaddr, NULL, be, EM_XTENSA, 0);
if (success > 0) {
entry_point = elf_entry;
} else {
diff --git a/include/elf.h b/include/elf.h
index 79859f0cd8..66add810df 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -135,6 +135,9 @@ typedef int64_t Elf64_Sxword;
#define EM_TILEGX 191 /* TILE-Gx */
+#define EM_MOXIE 223 /* Moxie processor family */
+#define EM_MOXIE_OLD 0xFEED
+
/* This is the info that is needed to parse the dynamic section of the file */
#define DT_NULL 0
#define DT_NEEDED 1
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
index bd71968143..0010c441d9 100644
--- a/include/hw/elf_ops.h
+++ b/include/hw/elf_ops.h
@@ -282,25 +282,36 @@ static int glue(load_elf, SZ)(const char *name, int fd,
switch (elf_machine) {
case EM_PPC64:
- if (EM_PPC64 != ehdr.e_machine)
- if (EM_PPC != ehdr.e_machine) {
+ if (ehdr.e_machine != EM_PPC64) {
+ if (ehdr.e_machine != EM_PPC) {
ret = ELF_LOAD_WRONG_ARCH;
goto fail;
}
+ }
break;
case EM_X86_64:
- if (EM_X86_64 != ehdr.e_machine)
- if (EM_386 != ehdr.e_machine) {
+ if (ehdr.e_machine != EM_X86_64) {
+ if (ehdr.e_machine != EM_386) {
ret = ELF_LOAD_WRONG_ARCH;
goto fail;
}
+ }
break;
case EM_MICROBLAZE:
- if (EM_MICROBLAZE != ehdr.e_machine)
- if (EM_MICROBLAZE_OLD != ehdr.e_machine) {
+ if (ehdr.e_machine != EM_MICROBLAZE) {
+ if (ehdr.e_machine != EM_MICROBLAZE_OLD) {
+ ret = ELF_LOAD_WRONG_ARCH;
+ goto fail;
+ }
+ }
+ break;
+ case EM_MOXIE:
+ if (ehdr.e_machine != EM_MOXIE) {
+ if (ehdr.e_machine != EM_MOXIE_OLD) {
ret = ELF_LOAD_WRONG_ARCH;
goto fail;
}
+ }
break;
default:
if (elf_machine != ehdr.e_machine) {
diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h
index 26632acf37..7813396e49 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -50,17 +50,73 @@
#define APIC_TRIGGER_EDGE 0
#define APIC_TRIGGER_LEVEL 1
-#define APIC_LVT_TIMER_PERIODIC (1<<17)
-#define APIC_LVT_MASKED (1<<16)
-#define APIC_LVT_LEVEL_TRIGGER (1<<15)
-#define APIC_LVT_REMOTE_IRR (1<<14)
-#define APIC_INPUT_POLARITY (1<<13)
-#define APIC_SEND_PENDING (1<<12)
-
-#define ESR_ILLEGAL_ADDRESS (1 << 7)
-
-#define APIC_SV_DIRECTED_IO (1<<12)
-#define APIC_SV_ENABLE (1<<8)
+#define APIC_VECTOR_MASK 0xff
+#define APIC_DCR_MASK 0xf
+
+#define APIC_LVT_TIMER_SHIFT 17
+#define APIC_LVT_MASKED_SHIFT 16
+#define APIC_LVT_LEVEL_TRIGGER_SHIFT 15
+#define APIC_LVT_REMOTE_IRR_SHIFT 14
+#define APIC_LVT_INT_POLARITY_SHIFT 13
+#define APIC_LVT_DELIV_STS_SHIFT 12
+#define APIC_LVT_DELIV_MOD_SHIFT 8
+
+#define APIC_LVT_TIMER_TSCDEADLINE (2 << APIC_LVT_TIMER_SHIFT)
+#define APIC_LVT_TIMER_PERIODIC (1 << APIC_LVT_TIMER_SHIFT)
+#define APIC_LVT_MASKED (1 << APIC_LVT_MASKED_SHIFT)
+#define APIC_LVT_LEVEL_TRIGGER (1 << APIC_LVT_LEVEL_TRIGGER_SHIFT)
+#define APIC_LVT_REMOTE_IRR (1 << APIC_LVT_REMOTE_IRR_SHIFT)
+#define APIC_LVT_INT_POLARITY (1 << APIC_LVT_INT_POLARITY_SHIFT)
+#define APIC_LVT_DELIV_STS (1 << APIC_LVT_DELIV_STS_SHIFT)
+#define APIC_LVT_DELIV_MOD (7 << APIC_LVT_DELIV_MOD_SHIFT)
+
+#define APIC_ESR_ILL_ADDRESS_SHIFT 7
+#define APIC_ESR_RECV_ILL_VECT_SHIFT 6
+#define APIC_ESR_SEND_ILL_VECT_SHIFT 5
+#define APIC_ESR_RECV_ACCEPT_SHIFT 3
+#define APIC_ESR_SEND_ACCEPT_SHIFT 2
+#define APIC_ESR_RECV_CHECK_SUM_SHIFT 1
+
+#define APIC_ESR_ILLEGAL_ADDRESS (1 << APIC_ESR_ILL_ADDRESS_SHIFT)
+#define APIC_ESR_RECV_ILLEGAL_VECT (1 << APIC_ESR_RECV_ILL_VECT_SHIFT)
+#define APIC_ESR_SEND_ILLEGAL_VECT (1 << APIC_ESR_SEND_ILL_VECT_SHIFT)
+#define APIC_ESR_RECV_ACCEPT (1 << APIC_ESR_RECV_ACCEPT_SHIFT)
+#define APIC_ESR_SEND_ACCEPT (1 << APIC_ESR_SEND_ACCEPT_SHIFT)
+#define APIC_ESR_RECV_CHECK_SUM (1 << APIC_ESR_RECV_CHECK_SUM_SHIFT)
+#define APIC_ESR_SEND_CHECK_SUM 1
+
+#define APIC_ICR_DEST_SHIFT 24
+#define APIC_ICR_DEST_SHORT_SHIFT 18
+#define APIC_ICR_TRIGGER_MOD_SHIFT 15
+#define APIC_ICR_LEVEL_SHIFT 14
+#define APIC_ICR_DELIV_STS_SHIFT 12
+#define APIC_ICR_DEST_MOD_SHIFT 11
+#define APIC_ICR_DELIV_MOD_SHIFT 8
+
+#define APIC_ICR_DEST_SHORT (3 << APIC_ICR_DEST_SHORT_SHIFT)
+#define APIC_ICR_TRIGGER_MOD (1 << APIC_ICR_TRIGGER_MOD_SHIFT)
+#define APIC_ICR_LEVEL (1 << APIC_ICR_LEVEL_SHIFT)
+#define APIC_ICR_DELIV_STS (1 << APIC_ICR_DELIV_STS_SHIFT)
+#define APIC_ICR_DEST_MOD (1 << APIC_ICR_DEST_MOD_SHIFT)
+#define APIC_ICR_DELIV_MOD (7 << APIC_ICR_DELIV_MOD_SHIFT)
+
+#define APIC_PR_CLASS_SHIFT 4
+#define APIC_PR_SUB_CLASS 0xf
+
+#define APIC_LOGDEST_XAPIC_SHIFT 4
+#define APIC_LOGDEST_XAPIC_ID 0xf
+
+#define APIC_LOGDEST_X2APIC_SHIFT 16
+#define APIC_LOGDEST_X2APIC_ID 0xffff
+
+#define APIC_SPURIO_FOCUS_SHIFT 9
+#define APIC_SPURIO_ENABLED_SHIFT 8
+
+#define APIC_SPURIO_FOCUS (1 << APIC_SPURIO_FOCUS_SHIFT)
+#define APIC_SPURIO_ENABLED (1 << APIC_SPURIO_ENABLED_SHIFT)
+
+#define APIC_SV_DIRECTED_IO (1 << 12)
+#define APIC_SV_ENABLE (1 << 8)
#define VAPIC_ENABLE_BIT 0
#define VAPIC_ENABLE_MASK (1 << VAPIC_ENABLE_BIT)
@@ -147,4 +203,22 @@ void apic_enable_vapic(DeviceState *d, hwaddr paddr);
void vapic_report_tpr_access(DeviceState *dev, CPUState *cpu, target_ulong ip,
TPRAccess access);
+int apic_get_ppr(APICCommonState *s);
+
+static inline void apic_set_bit(uint32_t *tab, int index)
+{
+ int i, mask;
+ i = index >> 5;
+ mask = 1 << (index & 0x1f);
+ tab[i] |= mask;
+}
+
+static inline int apic_get_bit(uint32_t *tab, int index)
+{
+ int i, mask;
+ i = index >> 5;
+ mask = 1 << (index & 0x1f);
+ return !!(tab[i] & mask);
+}
+
#endif /* !QEMU_APIC_INTERNAL_H */
diff --git a/include/hw/i386/ioapic_internal.h b/include/hw/i386/ioapic_internal.h
index 3be3352185..797ed47305 100644
--- a/include/hw/i386/ioapic_internal.h
+++ b/include/hw/i386/ioapic_internal.h
@@ -40,7 +40,12 @@
#define IOAPIC_LVT_DELIV_MODE_SHIFT 8
#define IOAPIC_LVT_MASKED (1 << IOAPIC_LVT_MASKED_SHIFT)
+#define IOAPIC_LVT_TRIGGER_MODE (1 << IOAPIC_LVT_TRIGGER_MODE_SHIFT)
#define IOAPIC_LVT_REMOTE_IRR (1 << IOAPIC_LVT_REMOTE_IRR_SHIFT)
+#define IOAPIC_LVT_POLARITY (1 << IOAPIC_LVT_POLARITY_SHIFT)
+#define IOAPIC_LVT_DELIV_STATUS (1 << IOAPIC_LVT_DELIV_STATUS_SHIFT)
+#define IOAPIC_LVT_DEST_MODE (1 << IOAPIC_LVT_DEST_MODE_SHIFT)
+#define IOAPIC_LVT_DELIV_MODE (7 << IOAPIC_LVT_DELIV_MODE_SHIFT)
#define IOAPIC_TRIGGER_EDGE 0
#define IOAPIC_TRIGGER_LEVEL 1
@@ -100,4 +105,6 @@ struct IOAPICCommonState {
void ioapic_reset_common(DeviceState *dev);
+void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s);
+
#endif /* !QEMU_IOAPIC_INTERNAL_H */
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 6896328aa0..ab5413f561 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -123,6 +123,11 @@ int pic_get_output(DeviceState *d);
void hmp_info_pic(Monitor *mon, const QDict *qdict);
void hmp_info_irq(Monitor *mon, const QDict *qdict);
+/* ioapic.c */
+
+void kvm_ioapic_dump_state(Monitor *mon, const QDict *qdict);
+void ioapic_dump_state(Monitor *mon, const QDict *qdict);
+
/* Global System Interrupts */
#define GSI_NUM_PINS IOAPIC_NUM_PINS
diff --git a/include/hw/virtio/vhost-scsi.h b/include/hw/virtio/vhost-scsi.h
index 701bfee619..9fd63df12e 100644
--- a/include/hw/virtio/vhost-scsi.h
+++ b/include/hw/virtio/vhost-scsi.h
@@ -19,37 +19,12 @@
#include "hw/virtio/virtio-scsi.h"
#include "hw/virtio/vhost.h"
-/*
- * Used by QEMU userspace to ensure a consistent vhost-scsi ABI.
- *
- * ABI Rev 0: July 2012 version starting point for v3.6-rc merge candidate +
- * RFC-v2 vhost-scsi userspace. Add GET_ABI_VERSION ioctl usage
- * ABI Rev 1: January 2013. Ignore vhost_tpgt filed in struct vhost_scsi_target.
- * All the targets under vhost_wwpn can be seen and used by guest.
- */
-
-#define VHOST_SCSI_ABI_VERSION 1
-
-/* TODO #include <linux/vhost.h> properly */
-/* For VHOST_SCSI_SET_ENDPOINT/VHOST_SCSI_CLEAR_ENDPOINT ioctl */
-struct vhost_scsi_target {
- int abi_version;
- char vhost_wwpn[224];
- unsigned short vhost_tpgt;
- unsigned short reserved;
-};
-
enum vhost_scsi_vq_list {
VHOST_SCSI_VQ_CONTROL = 0,
VHOST_SCSI_VQ_EVENT = 1,
VHOST_SCSI_VQ_NUM_FIXED = 2,
};
-#define VHOST_VIRTIO 0xAF
-#define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target)
-#define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target)
-#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, int)
-
#define TYPE_VHOST_SCSI "vhost-scsi"
#define VHOST_SCSI(obj) \
OBJECT_CHECK(VHostSCSI, (obj), TYPE_VHOST_SCSI)
diff --git a/include/monitor/hmp-target.h b/include/monitor/hmp-target.h
index 611541d1cb..213566c612 100644
--- a/include/monitor/hmp-target.h
+++ b/include/monitor/hmp-target.h
@@ -37,9 +37,12 @@ struct MonitorDef {
const MonitorDef *target_monitor_defs(void);
CPUArchState *mon_get_cpu_env(void);
+CPUState *mon_get_cpu(void);
void hmp_info_mem(Monitor *mon, const QDict *qdict);
void hmp_info_tlb(Monitor *mon, const QDict *qdict);
void hmp_mce(Monitor *mon, const QDict *qdict);
+void hmp_info_local_apic(Monitor *mon, const QDict *qdict);
+void hmp_info_io_apic(Monitor *mon, const QDict *qdict);
#endif /* MONITOR_COMMON */
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index bc6cb6d185..91b95ae90a 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -34,6 +34,7 @@ int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp);
void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
GCC_FMT_ATTR(2, 0);
void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
+int monitor_fprintf(FILE *stream, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
void monitor_flush(Monitor *mon);
int monitor_set_cpu(int cpu_index);
int monitor_get_cpu_index(void);
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 01d29dd45a..0bd212b218 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -217,22 +217,23 @@ int parse_uint(const char *s, unsigned long long *value, char **endptr,
int parse_uint_full(const char *s, unsigned long long *value, int base);
/*
- * strtosz() suffixes used to specify the default treatment of an
- * argument passed to strtosz() without an explicit suffix.
+ * qemu_strtosz() suffixes used to specify the default treatment of an
+ * argument passed to qemu_strtosz() without an explicit suffix.
* These should be defined using upper case characters in the range
- * A-Z, as strtosz() will use qemu_toupper() on the given argument
+ * A-Z, as qemu_strtosz() will use qemu_toupper() on the given argument
* prior to comparison.
*/
-#define STRTOSZ_DEFSUFFIX_EB 'E'
-#define STRTOSZ_DEFSUFFIX_PB 'P'
-#define STRTOSZ_DEFSUFFIX_TB 'T'
-#define STRTOSZ_DEFSUFFIX_GB 'G'
-#define STRTOSZ_DEFSUFFIX_MB 'M'
-#define STRTOSZ_DEFSUFFIX_KB 'K'
-#define STRTOSZ_DEFSUFFIX_B 'B'
-int64_t strtosz(const char *nptr, char **end);
-int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix);
-int64_t strtosz_suffix_unit(const char *nptr, char **end,
+#define QEMU_STRTOSZ_DEFSUFFIX_EB 'E'
+#define QEMU_STRTOSZ_DEFSUFFIX_PB 'P'
+#define QEMU_STRTOSZ_DEFSUFFIX_TB 'T'
+#define QEMU_STRTOSZ_DEFSUFFIX_GB 'G'
+#define QEMU_STRTOSZ_DEFSUFFIX_MB 'M'
+#define QEMU_STRTOSZ_DEFSUFFIX_KB 'K'
+#define QEMU_STRTOSZ_DEFSUFFIX_B 'B'
+int64_t qemu_strtosz(const char *nptr, char **end);
+int64_t qemu_strtosz_suffix(const char *nptr, char **end,
+ const char default_suffix);
+int64_t qemu_strtosz_suffix_unit(const char *nptr, char **end,
const char default_suffix, int64_t unit);
#define K_BYTE (1ULL << 10)
#define M_BYTE (1ULL << 20)
diff --git a/include/qemu/option.h b/include/qemu/option.h
index 57e51c9628..71f5f27ec8 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -30,6 +30,7 @@
#include "qemu/queue.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
+#include "qemu/typedefs.h"
const char *get_opt_name(char *buf, int buf_size, const char *p, char delim);
const char *get_opt_value(char *buf, int buf_size, const char *p);
@@ -44,10 +45,6 @@ void parse_option_size(const char *name, const char *value,
bool has_help_option(const char *param);
bool is_valid_option_list(const char *param);
-typedef struct QemuOpt QemuOpt;
-typedef struct QemuOpts QemuOpts;
-typedef struct QemuOptsList QemuOptsList;
-
enum QemuOptType {
QEMU_OPT_STRING = 0, /* no parsing (use string as-is) */
QEMU_OPT_BOOL, /* on/off */
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index ce82c642b5..3a835ffb9b 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -67,6 +67,9 @@ typedef struct Property Property;
typedef struct QEMUBH QEMUBH;
typedef struct QemuConsole QemuConsole;
typedef struct QEMUFile QEMUFile;
+typedef struct QemuOpt QemuOpt;
+typedef struct QemuOpts QemuOpts;
+typedef struct QemuOptsList QemuOptsList;
typedef struct QEMUSGList QEMUSGList;
typedef struct QEMUSizedBuffer QEMUSizedBuffer;
typedef struct QEMUTimerListGroup QEMUTimerListGroup;
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 39f32826ba..a7ff58c8bb 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -145,7 +145,6 @@ static uint32_t get_elf_hwcap(void)
#ifdef TARGET_X86_64
#define ELF_START_MMAP 0x2aaaaab000ULL
-#define elf_check_arch(x) ( ((x) == ELF_ARCH) )
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_X86_64
@@ -273,9 +272,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ((x) == ELF_MACHINE)
-
-#define ELF_ARCH ELF_MACHINE
+#define ELF_ARCH EM_ARM
#define ELF_CLASS ELFCLASS32
static inline void init_thread(struct target_pt_regs *regs,
@@ -481,9 +478,7 @@ static uint32_t get_elf_hwcap2(void)
/* 64 bit ARM definitions */
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ((x) == ELF_MACHINE)
-
-#define ELF_ARCH ELF_MACHINE
+#define ELF_ARCH EM_AARCH64
#define ELF_CLASS ELFCLASS64
#define ELF_PLATFORM "aarch64"
@@ -556,8 +551,6 @@ static uint32_t get_elf_hwcap(void)
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ((x) == EM_UNICORE32)
-
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_UNICORE32
@@ -666,7 +659,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_START_MMAP 0x80000000
#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \
| HWCAP_SPARC_MULDIV)
-#define elf_check_arch(x) ( (x) == EM_SPARC )
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_SPARC
@@ -686,6 +678,7 @@ static inline void init_thread(struct target_pt_regs *regs,
#ifdef TARGET_PPC
+#define ELF_MACHINE PPC_ELF_MACHINE
#define ELF_START_MMAP 0x80000000
#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
@@ -696,8 +689,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#else
-#define elf_check_arch(x) ( (x) == EM_PPC )
-
#define ELF_CLASS ELFCLASS32
#endif
@@ -875,8 +866,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ( (x) == EM_MIPS )
-
#ifdef TARGET_MIPS64
#define ELF_CLASS ELFCLASS64
#else
@@ -985,8 +974,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMBState *env
#define ELF_START_MMAP 0x08000000
-#define elf_check_arch(x) ((x) == EM_OPENRISC)
-
#define ELF_ARCH EM_OPENRISC
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2MSB
@@ -1026,8 +1013,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ( (x) == EM_SH )
-
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_SH
@@ -1110,8 +1095,6 @@ static uint32_t get_elf_hwcap(void)
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ( (x) == EM_CRIS )
-
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_CRIS
@@ -1129,8 +1112,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_START_MMAP 0x80000000
-#define elf_check_arch(x) ( (x) == EM_68K )
-
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_68K
@@ -1182,8 +1163,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUM68KState *e
#define ELF_START_MMAP (0x30000000000ULL)
-#define elf_check_arch(x) ( (x) == ELF_ARCH )
-
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_ALPHA
@@ -1203,8 +1182,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_START_MMAP (0x20000000000ULL)
-#define elf_check_arch(x) ( (x) == ELF_ARCH )
-
#define ELF_CLASS ELFCLASS64
#define ELF_DATA ELFDATA2MSB
#define ELF_ARCH EM_S390
@@ -1245,6 +1222,14 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_PLATFORM (NULL)
#endif
+#ifndef ELF_MACHINE
+#define ELF_MACHINE ELF_ARCH
+#endif
+
+#ifndef elf_check_arch
+#define elf_check_arch(x) ((x) == ELF_ARCH)
+#endif
+
#ifndef ELF_HWCAP
#define ELF_HWCAP 0
#endif
diff --git a/monitor.c b/monitor.c
index d0edb3bb15..4f1ba2f666 100644
--- a/monitor.c
+++ b/monitor.c
@@ -372,8 +372,7 @@ void monitor_printf(Monitor *mon, const char *fmt, ...)
va_end(ap);
}
-static int GCC_FMT_ATTR(2, 3) monitor_fprintf(FILE *stream,
- const char *fmt, ...)
+int monitor_fprintf(FILE *stream, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@@ -957,7 +956,7 @@ int monitor_set_cpu(int cpu_index)
return 0;
}
-static CPUState *mon_get_cpu(void)
+CPUState *mon_get_cpu(void)
{
if (!cur_mon->mon_cpu) {
monitor_set_cpu(0);
@@ -2697,7 +2696,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
break;
}
}
- val = strtosz(p, &end);
+ val = qemu_strtosz(p, &end);
if (val < 0) {
monitor_printf(mon, "invalid size\n");
goto fail;
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 7ae33b311e..cd10392f18 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -474,8 +474,8 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)
return;
}
- val = strtosz_suffix(opt->str ? opt->str : "", &endptr,
- STRTOSZ_DEFSUFFIX_B);
+ val = qemu_strtosz_suffix(opt->str ? opt->str : "", &endptr,
+ QEMU_STRTOSZ_DEFSUFFIX_B);
if (val < 0 || *endptr) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
"a size value representible as a non-negative int64");
diff --git a/qemu-img.c b/qemu-img.c
index 6ff4e852b1..7d65c0a78c 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -338,7 +338,8 @@ static int img_create(int argc, char **argv)
if (optind < argc) {
int64_t sval;
char *end;
- sval = strtosz_suffix(argv[optind++], &end, STRTOSZ_DEFSUFFIX_B);
+ sval = qemu_strtosz_suffix(argv[optind++], &end,
+ QEMU_STRTOSZ_DEFSUFFIX_B);
if (sval < 0 || *end) {
if (sval == -ERANGE) {
error_report("Image size must be less than 8 EiB!");
@@ -1607,7 +1608,7 @@ static int img_convert(int argc, char **argv)
{
int64_t sval;
char *end;
- sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B);
+ sval = qemu_strtosz_suffix(optarg, &end, QEMU_STRTOSZ_DEFSUFFIX_B);
if (sval < 0 || *end) {
error_report("Invalid minimum zero buffer size for sparse output specified");
ret = -1;
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index d6572a8585..6e5d1e4d38 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -136,7 +136,7 @@ static char **breakline(char *input, int *count)
static int64_t cvtnum(const char *s)
{
char *end;
- return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
+ return qemu_strtosz_suffix(s, &end, QEMU_STRTOSZ_DEFSUFFIX_B);
}
#define EXABYTES(x) ((long long)(x) << 60)
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 9518b75a3a..6428c15403 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -49,7 +49,7 @@
static NBDExport *exp;
static int verbose;
static char *srcpath;
-static char *sockpath;
+static SocketAddress *saddr;
static int persistent = 0;
static enum { RUNNING, TERMINATE, TERMINATING, TERMINATED } state;
static int shared = 1;
@@ -213,52 +213,6 @@ static void termsig_handler(int signum)
qemu_notify_event();
}
-static void combine_addr(char *buf, size_t len, const char* address,
- uint16_t port)
-{
- /* If the address-part contains a colon, it's an IPv6 IP so needs [] */
- if (strstr(address, ":")) {
- snprintf(buf, len, "[%s]:%u", address, port);
- } else {
- snprintf(buf, len, "%s:%u", address, port);
- }
-}
-
-static int tcp_socket_incoming(const char *address, uint16_t port)
-{
- char address_and_port[128];
- Error *local_err = NULL;
-
- combine_addr(address_and_port, 128, address, port);
- int fd = inet_listen(address_and_port, NULL, 0, SOCK_STREAM, 0, &local_err);
-
- if (local_err != NULL) {
- error_report_err(local_err);
- }
- return fd;
-}
-
-static int unix_socket_incoming(const char *path)
-{
- Error *local_err = NULL;
- int fd = unix_listen(path, NULL, 0, &local_err);
-
- if (local_err != NULL) {
- error_report_err(local_err);
- }
- return fd;
-}
-
-static int unix_socket_outgoing(const char *path)
-{
- Error *local_err = NULL;
- int fd = unix_connect(path, &local_err);
-
- if (local_err != NULL) {
- error_report_err(local_err);
- }
- return fd;
-}
static void *show_parts(void *arg)
{
@@ -287,8 +241,10 @@ static void *nbd_client_thread(void *arg)
pthread_t show_parts_thread;
Error *local_error = NULL;
- sock = unix_socket_outgoing(sockpath);
+
+ sock = socket_connect(saddr, &local_error, NULL, NULL);
if (sock < 0) {
+ error_report_err(local_error);
goto out;
}
@@ -399,6 +355,33 @@ static void nbd_update_server_fd_handler(int fd)
}
}
+
+static SocketAddress *nbd_build_socket_address(const char *sockpath,
+ const char *bindto,
+ const char *port)
+{
+ SocketAddress *saddr;
+
+ saddr = g_new0(SocketAddress, 1);
+ if (sockpath) {
+ saddr->kind = SOCKET_ADDRESS_KIND_UNIX;
+ saddr->q_unix = g_new0(UnixSocketAddress, 1);
+ saddr->q_unix->path = g_strdup(sockpath);
+ } else {
+ saddr->kind = SOCKET_ADDRESS_KIND_INET;
+ saddr->inet = g_new0(InetSocketAddress, 1);
+ saddr->inet->host = g_strdup(bindto);
+ if (port) {
+ saddr->inet->port = g_strdup(port);
+ } else {
+ saddr->inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
+ }
+ }
+
+ return saddr;
+}
+
+
int main(int argc, char **argv)
{
BlockBackend *blk;
@@ -407,8 +390,9 @@ int main(int argc, char **argv)
uint32_t nbdflags = 0;
bool disconnect = false;
const char *bindto = "0.0.0.0";
+ const char *port = NULL;
+ char *sockpath = NULL;
char *device = NULL;
- int port = NBD_DEFAULT_PORT;
off_t fd_size;
QemuOpts *sn_opts = NULL;
const char *sn_id_or_name = NULL;
@@ -441,7 +425,6 @@ int main(int argc, char **argv)
};
int ch;
int opt_ind = 0;
- int li;
char *end;
int flags = BDRV_O_RDWR;
int partition = -1;
@@ -529,14 +512,7 @@ int main(int argc, char **argv)
bindto = optarg;
break;
case 'p':
- li = strtol(optarg, &end, 0);
- if (*end) {
- errx(EXIT_FAILURE, "Invalid port `%s'", optarg);
- }
- if (li < 1 || li > 65535) {
- errx(EXIT_FAILURE, "Port out of range `%s'", optarg);
- }
- port = (uint16_t)li;
+ port = optarg;
break;
case 'o':
dev_offset = strtoll (optarg, &end, 0);
@@ -695,6 +671,8 @@ int main(int argc, char **argv)
snprintf(sockpath, 128, SOCKET_PATH, basename(device));
}
+ saddr = nbd_build_socket_address(sockpath, bindto, port);
+
if (qemu_init_main_loop(&local_err)) {
error_report_err(local_err);
exit(EXIT_FAILURE);
@@ -752,13 +730,9 @@ int main(int argc, char **argv)
errx(EXIT_FAILURE, "%s", error_get_pretty(local_err));
}
- if (sockpath) {
- fd = unix_socket_incoming(sockpath);
- } else {
- fd = tcp_socket_incoming(bindto, port);
- }
-
+ fd = socket_listen(saddr, &local_err);
if (fd < 0) {
+ error_report_err(local_err);
return 1;
}
diff --git a/qemu-tech.texi b/qemu-tech.texi
index b6fcb2d61b..022017d55d 100644
--- a/qemu-tech.texi
+++ b/qemu-tech.texi
@@ -320,7 +320,7 @@ SH4
@node QEMU compared to other emulators
@section QEMU compared to other emulators
-Like bochs [3], QEMU emulates an x86 CPU. But QEMU is much faster than
+Like bochs [1], QEMU emulates an x86 CPU. But QEMU is much faster than
bochs as it uses dynamic compilation. Bochs is closely tied to x86 PC
emulation while QEMU can emulate several processors.
@@ -333,25 +333,25 @@ than QEMU (in particular it does register allocation) but it is closely
tied to an x86 host and target and has no support for precise exceptions
and system emulation.
-EM86 [4] is the closest project to user space QEMU (and QEMU still uses
+EM86 [3] is the closest project to user space QEMU (and QEMU still uses
some of its code, in particular the ELF file loader). EM86 was limited
to an alpha host and used a proprietary and slow interpreter (the
-interpreter part of the FX!32 Digital Win32 code translator [5]).
+interpreter part of the FX!32 Digital Win32 code translator [4]).
-TWIN [6] is a Windows API emulator like Wine. It is less accurate than
-Wine but includes a protected mode x86 interpreter to launch x86 Windows
-executables. Such an approach has greater potential because most of the
-Windows API is executed natively but it is far more difficult to develop
-because all the data structures and function parameters exchanged
+TWIN from Willows Software was a Windows API emulator like Wine. It is less
+accurate than Wine but includes a protected mode x86 interpreter to launch
+x86 Windows executables. Such an approach has greater potential because most
+of the Windows API is executed natively but it is far more difficult to
+develop because all the data structures and function parameters exchanged
between the API and the x86 code must be converted.
-User mode Linux [7] was the only solution before QEMU to launch a
+User mode Linux [5] was the only solution before QEMU to launch a
Linux kernel as a process while not needing any host kernel
patches. However, user mode Linux requires heavy kernel patches while
QEMU accepts unpatched Linux kernels. The price to pay is that QEMU is
slower.
-The Plex86 [8] PC virtualizer is done in the same spirit as the now
+The Plex86 [6] PC virtualizer is done in the same spirit as the now
obsolete qemu-fast system emulator. It requires a patched Linux kernel
to work (you cannot launch the same kernel on your PC), but the
patches are really small. As it is a PC virtualizer (no emulation is
@@ -359,13 +359,13 @@ done except for some privileged instructions), it has the potential of
being faster than QEMU. The downside is that a complicated (and
potentially unsafe) host kernel patch is needed.
-The commercial PC Virtualizers (VMWare [9], VirtualPC [10], TwoOStwo
-[11]) are faster than QEMU, but they all need specific, proprietary
+The commercial PC Virtualizers (VMWare [7], VirtualPC [8]) are faster
+than QEMU (without virtualization), but they all need specific, proprietary
and potentially unsafe host drivers. Moreover, they are unable to
provide cycle exact simulation as an emulator can.
-VirtualBox [12], Xen [13] and KVM [14] are based on QEMU. QEMU-SystemC
-[15] uses QEMU to simulate a system where some hardware devices are
+VirtualBox [9], Xen [10] and KVM [11] are based on QEMU. QEMU-SystemC
+[12] uses QEMU to simulate a system where some hardware devices are
developed in SystemC.
@node Portable dynamic translation
@@ -608,64 +608,51 @@ way, it can be relocated at load time.
@table @asis
@item [1]
-@url{http://citeseer.nj.nec.com/piumarta98optimizing.html}, Optimizing
-direct threaded code by selective inlining (1998) by Ian Piumarta, Fabio
-Riccardi.
+@url{http://bochs.sourceforge.net/}, the Bochs IA-32 Emulator Project,
+by Kevin Lawton et al.
@item [2]
-@url{http://developer.kde.org/~sewardj/}, Valgrind, an open-source
-memory debugger for x86-GNU/Linux, by Julian Seward.
+@url{http://www.valgrind.org/}, Valgrind, an open-source memory debugger
+for GNU/Linux.
@item [3]
-@url{http://bochs.sourceforge.net/}, the Bochs IA-32 Emulator Project,
-by Kevin Lawton et al.
+@url{http://ftp.dreamtime.org/pub/linux/Linux-Alpha/em86/v0.2/docs/em86.html},
+the EM86 x86 emulator on Alpha-Linux.
@item [4]
-@url{http://www.cs.rose-hulman.edu/~donaldlf/em86/index.html}, the EM86
-x86 emulator on Alpha-Linux.
-
-@item [5]
@url{http://www.usenix.org/publications/library/proceedings/usenix-nt97/@/full_papers/chernoff/chernoff.pdf},
DIGITAL FX!32: Running 32-Bit x86 Applications on Alpha NT, by Anton
Chernoff and Ray Hookway.
-@item [6]
-@url{http://www.willows.com/}, Windows API library emulation from
-Willows Software.
-
-@item [7]
+@item [5]
@url{http://user-mode-linux.sourceforge.net/},
The User-mode Linux Kernel.
-@item [8]
+@item [6]
@url{http://www.plex86.org/},
The new Plex86 project.
-@item [9]
+@item [7]
@url{http://www.vmware.com/},
The VMWare PC virtualizer.
-@item [10]
-@url{http://www.microsoft.com/windowsxp/virtualpc/},
+@item [8]
+@url{https://www.microsoft.com/download/details.aspx?id=3702},
The VirtualPC PC virtualizer.
-@item [11]
-@url{http://www.twoostwo.org/},
-The TwoOStwo PC virtualizer.
-
-@item [12]
+@item [9]
@url{http://virtualbox.org/},
The VirtualBox PC virtualizer.
-@item [13]
+@item [10]
@url{http://www.xen.org/},
The Xen hypervisor.
-@item [14]
-@url{http://kvm.qumranet.com/kvmwiki/Front_Page},
+@item [11]
+@url{http://www.linux-kvm.org/},
Kernel Based Virtual Machine (KVM).
-@item [15]
+@item [12]
@url{http://www.greensocs.com/projects/QEMUSystemC},
QEMU-SystemC, a hardware co-simulator.
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 574334b985..b6d71eae17 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2463,8 +2463,8 @@ sub process {
WARN("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr);
}
-# recommend qemu_strto* over strto*
- if ($line =~ /\b(strto.*?)\s*\(/) {
+# recommend qemu_strto* over strto* for numeric conversions
+ if ($line =~ /\b(strto[^k].*?)\s*\(/) {
WARN("consider using qemu_$1 in preference to $1\n" . $herecurr);
}
# check for module_init(), use category-specific init macros explicitly please
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index f39630eb3d..7dacf32f43 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -258,7 +258,7 @@ open (my $maint, '<', "${lk_path}MAINTAINERS")
while (<$maint>) {
my $line = $_;
- if ($line =~ m/^(\C):\s*(.*)/) {
+ if ($line =~ m/^(.):\s*(.*)/) {
my $type = $1;
my $value = $2;
@@ -493,7 +493,7 @@ sub range_is_maintained {
for (my $i = $start; $i < $end; $i++) {
my $line = $typevalue[$i];
- if ($line =~ m/^(\C):\s*(.*)/) {
+ if ($line =~ m/^(.):\s*(.*)/) {
my $type = $1;
my $value = $2;
if ($type eq 'S') {
@@ -511,7 +511,7 @@ sub range_has_maintainer {
for (my $i = $start; $i < $end; $i++) {
my $line = $typevalue[$i];
- if ($line =~ m/^(\C):\s*(.*)/) {
+ if ($line =~ m/^(.):\s*(.*)/) {
my $type = $1;
my $value = $2;
if ($type eq 'M') {
@@ -560,7 +560,7 @@ sub get_maintainers {
for ($i = $start; $i < $end; $i++) {
my $line = $typevalue[$i];
- if ($line =~ m/^(\C):\s*(.*)/) {
+ if ($line =~ m/^(.):\s*(.*)/) {
my $type = $1;
my $value = $2;
if ($type eq 'X') {
@@ -575,7 +575,7 @@ sub get_maintainers {
if (!$exclude) {
for ($i = $start; $i < $end; $i++) {
my $line = $typevalue[$i];
- if ($line =~ m/^(\C):\s*(.*)/) {
+ if ($line =~ m/^(.):\s*(.*)/) {
my $type = $1;
my $value = $2;
if ($type eq 'F') {
@@ -855,7 +855,7 @@ sub find_first_section {
while ($index < @typevalue) {
my $tv = $typevalue[$index];
- if (($tv =~ m/^(\C):\s*(.*)/)) {
+ if (($tv =~ m/^(.):\s*(.*)/)) {
last;
}
$index++;
@@ -869,7 +869,7 @@ sub find_starting_index {
while ($index > 0) {
my $tv = $typevalue[$index];
- if (!($tv =~ m/^(\C):\s*(.*)/)) {
+ if (!($tv =~ m/^(.):\s*(.*)/)) {
last;
}
$index--;
@@ -883,7 +883,7 @@ sub find_ending_index {
while ($index < @typevalue) {
my $tv = $typevalue[$index];
- if (!($tv =~ m/^(\C):\s*(.*)/)) {
+ if (!($tv =~ m/^(.):\s*(.*)/)) {
last;
}
$index++;
@@ -909,7 +909,7 @@ sub get_maintainer_role {
for ($i = $start + 1; $i < $end; $i++) {
my $tv = $typevalue[$i];
- if ($tv =~ m/^(\C):\s*(.*)/) {
+ if ($tv =~ m/^(.):\s*(.*)/) {
my $ptype = $1;
my $pvalue = $2;
if ($ptype eq "S") {
@@ -968,7 +968,7 @@ sub add_categories {
for ($i = $start + 1; $i < $end; $i++) {
my $tv = $typevalue[$i];
- if ($tv =~ m/^(\C):\s*(.*)/) {
+ if ($tv =~ m/^(.):\s*(.*)/) {
my $ptype = $1;
my $pvalue = $2;
if ($ptype eq "L") {
@@ -1010,7 +1010,7 @@ sub add_categories {
if ($name eq "") {
if ($i > 0) {
my $tv = $typevalue[$i - 1];
- if ($tv =~ m/^(\C):\s*(.*)/) {
+ if ($tv =~ m/^(.):\s*(.*)/) {
if ($1 eq "P") {
$name = $2;
$pvalue = format_email($name, $address, $email_usename);
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index ef88ffb83b..097637eb4e 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -32,8 +32,6 @@
#include "fpu/softfloat.h"
-#define ELF_MACHINE EM_ALPHA
-
#define ICACHE_LINE_SIZE 32
#define DCACHE_LINE_SIZE 32
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 1b8051613f..cc1578c9e8 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -26,10 +26,8 @@
#if defined(TARGET_AARCH64)
/* AArch64 definitions */
# define TARGET_LONG_BITS 64
-# define ELF_MACHINE EM_AARCH64
#else
# define TARGET_LONG_BITS 32
-# define ELF_MACHINE EM_ARM
#endif
#define TARGET_IS_BIENDIAN 1
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index 8ae7708645..d47fad466b 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -29,8 +29,6 @@
#include "exec/cpu-defs.h"
-#define ELF_MACHINE EM_CRIS
-
#define EXCP_NMI 1
#define EXCP_GURU 2
#define EXCP_BUSFAULT 3
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 7c52714014..bd411b9d8d 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1893,8 +1893,8 @@ static void x86_cpu_parse_featurestr(CPUState *cs, char *features,
char *err;
char num[32];
- tsc_freq = strtosz_suffix_unit(val, &err,
- STRTOSZ_DEFSUFFIX_B, 1000);
+ tsc_freq = qemu_strtosz_suffix_unit(val, &err,
+ QEMU_STRTOSZ_DEFSUFFIX_B, 1000);
if (tsc_freq < 0 || *err) {
error_setg(errp, "bad numerical value %s", val);
return;
@@ -3098,14 +3098,8 @@ static bool x86_cpu_has_work(CPUState *cs)
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
-#if !defined(CONFIG_USER_ONLY)
- if (cs->interrupt_request & CPU_INTERRUPT_POLL) {
- apic_poll_irq(cpu->apic_state);
- cpu_reset_interrupt(cs, CPU_INTERRUPT_POLL);
- }
-#endif
-
- return ((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
+ return ((cs->interrupt_request & (CPU_INTERRUPT_HARD |
+ CPU_INTERRUPT_POLL)) &&
(env->eflags & IF_MASK)) ||
(cs->interrupt_request & (CPU_INTERRUPT_NMI |
CPU_INTERRUPT_INIT |
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 5231e8c300..034fab6f39 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -37,10 +37,10 @@
#define TARGET_HAS_PRECISE_SMC
#ifdef TARGET_X86_64
-#define ELF_MACHINE EM_X86_64
+#define I386_ELF_MACHINE EM_X86_64
#define ELF_MACHINE_UNAME "x86_64"
#else
-#define ELF_MACHINE EM_386
+#define I386_ELF_MACHINE EM_386
#define ELF_MACHINE_UNAME "i686"
#endif
@@ -1353,4 +1353,7 @@ void enable_compat_apic_id_mode(void);
#define APIC_DEFAULT_ADDRESS 0xfee00000
#define APIC_SPACE_SIZE 0x100000
+void x86_cpu_dump_local_apic_state(CPUState *cs, FILE *f,
+ fprintf_function cpu_fprintf, int flags);
+
#endif /* CPU_I386_H */
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 5480a96a0f..9364d96f96 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -23,6 +23,7 @@
#ifndef CONFIG_USER_ONLY
#include "sysemu/sysemu.h"
#include "monitor/monitor.h"
+#include "hw/i386/apic_internal.h"
#endif
static void cpu_x86_version(CPUX86State *env, int *family, int *model)
@@ -177,6 +178,196 @@ done:
cpu_fprintf(f, "\n");
}
+#ifndef CONFIG_USER_ONLY
+
+/* ARRAY_SIZE check is not required because
+ * DeliveryMode(dm) has a size of 3 bit.
+ */
+static inline const char *dm2str(uint32_t dm)
+{
+ static const char *str[] = {
+ "Fixed",
+ "...",
+ "SMI",
+ "...",
+ "NMI",
+ "INIT",
+ "...",
+ "ExtINT"
+ };
+ return str[dm];
+}
+
+static void dump_apic_lvt(FILE *f, fprintf_function cpu_fprintf,
+ const char *name, uint32_t lvt, bool is_timer)
+{
+ uint32_t dm = (lvt & APIC_LVT_DELIV_MOD) >> APIC_LVT_DELIV_MOD_SHIFT;
+ cpu_fprintf(f,
+ "%s\t 0x%08x %s %-5s %-6s %-7s %-12s %-6s",
+ name, lvt,
+ lvt & APIC_LVT_INT_POLARITY ? "active-lo" : "active-hi",
+ lvt & APIC_LVT_LEVEL_TRIGGER ? "level" : "edge",
+ lvt & APIC_LVT_MASKED ? "masked" : "",
+ lvt & APIC_LVT_DELIV_STS ? "pending" : "",
+ !is_timer ?
+ "" : lvt & APIC_LVT_TIMER_PERIODIC ?
+ "periodic" : lvt & APIC_LVT_TIMER_TSCDEADLINE ?
+ "tsc-deadline" : "one-shot",
+ dm2str(dm));
+ if (dm != APIC_DM_NMI) {
+ cpu_fprintf(f, " (vec %u)\n", lvt & APIC_VECTOR_MASK);
+ } else {
+ cpu_fprintf(f, "\n");
+ }
+}
+
+/* ARRAY_SIZE check is not required because
+ * destination shorthand has a size of 2 bit.
+ */
+static inline const char *shorthand2str(uint32_t shorthand)
+{
+ const char *str[] = {
+ "no-shorthand", "self", "all-self", "all"
+ };
+ return str[shorthand];
+}
+
+static inline uint8_t divider_conf(uint32_t divide_conf)
+{
+ uint8_t divide_val = ((divide_conf & 0x8) >> 1) | (divide_conf & 0x3);
+
+ return divide_val == 7 ? 1 : 2 << divide_val;
+}
+
+static inline void mask2str(char *str, uint32_t val, uint8_t size)
+{
+ while (size--) {
+ *str++ = (val >> size) & 1 ? '1' : '0';
+ }
+ *str = 0;
+}
+
+#define MAX_LOGICAL_APIC_ID_MASK_SIZE 16
+
+static void dump_apic_icr(FILE *f, fprintf_function cpu_fprintf,
+ APICCommonState *s, CPUX86State *env)
+{
+ uint32_t icr = s->icr[0], icr2 = s->icr[1];
+ uint8_t dest_shorthand = \
+ (icr & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT;
+ bool logical_mod = icr & APIC_ICR_DEST_MOD;
+ char apic_id_str[MAX_LOGICAL_APIC_ID_MASK_SIZE + 1];
+ uint32_t dest_field;
+ bool x2apic;
+
+ cpu_fprintf(f, "ICR\t 0x%08x %s %s %s %s\n",
+ icr,
+ logical_mod ? "logical" : "physical",
+ icr & APIC_ICR_TRIGGER_MOD ? "level" : "edge",
+ icr & APIC_ICR_LEVEL ? "assert" : "de-assert",
+ shorthand2str(dest_shorthand));
+
+ cpu_fprintf(f, "ICR2\t 0x%08x", icr2);
+ if (dest_shorthand != 0) {
+ cpu_fprintf(f, "\n");
+ return;
+ }
+ x2apic = env->features[FEAT_1_ECX] & CPUID_EXT_X2APIC;
+ dest_field = x2apic ? icr2 : icr2 >> APIC_ICR_DEST_SHIFT;
+
+ if (!logical_mod) {
+ if (x2apic) {
+ cpu_fprintf(f, " cpu %u (X2APIC ID)\n", dest_field);
+ } else {
+ cpu_fprintf(f, " cpu %u (APIC ID)\n",
+ dest_field & APIC_LOGDEST_XAPIC_ID);
+ }
+ return;
+ }
+
+ if (s->dest_mode == 0xf) { /* flat mode */
+ mask2str(apic_id_str, icr2 >> APIC_ICR_DEST_SHIFT, 8);
+ cpu_fprintf(f, " mask %s (APIC ID)\n", apic_id_str);
+ } else if (s->dest_mode == 0) { /* cluster mode */
+ if (x2apic) {
+ mask2str(apic_id_str, dest_field & APIC_LOGDEST_X2APIC_ID, 16);
+ cpu_fprintf(f, " cluster %u mask %s (X2APIC ID)\n",
+ dest_field >> APIC_LOGDEST_X2APIC_SHIFT, apic_id_str);
+ } else {
+ mask2str(apic_id_str, dest_field & APIC_LOGDEST_XAPIC_ID, 4);
+ cpu_fprintf(f, " cluster %u mask %s (APIC ID)\n",
+ dest_field >> APIC_LOGDEST_XAPIC_SHIFT, apic_id_str);
+ }
+ }
+}
+
+static void dump_apic_interrupt(FILE *f, fprintf_function cpu_fprintf,
+ const char *name, uint32_t *ireg_tab,
+ uint32_t *tmr_tab)
+{
+ int i, empty = true;
+
+ cpu_fprintf(f, "%s\t ", name);
+ for (i = 0; i < 256; i++) {
+ if (apic_get_bit(ireg_tab, i)) {
+ cpu_fprintf(f, "%u%s ", i,
+ apic_get_bit(tmr_tab, i) ? "(level)" : "");
+ empty = false;
+ }
+ }
+ cpu_fprintf(f, "%s\n", empty ? "(none)" : "");
+}
+
+void x86_cpu_dump_local_apic_state(CPUState *cs, FILE *f,
+ fprintf_function cpu_fprintf, int flags)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ APICCommonState *s = APIC_COMMON(cpu->apic_state);
+ uint32_t *lvt = s->lvt;
+
+ cpu_fprintf(f, "dumping local APIC state for CPU %-2u\n\n",
+ CPU(cpu)->cpu_index);
+ dump_apic_lvt(f, cpu_fprintf, "LVT0", lvt[APIC_LVT_LINT0], false);
+ dump_apic_lvt(f, cpu_fprintf, "LVT1", lvt[APIC_LVT_LINT1], false);
+ dump_apic_lvt(f, cpu_fprintf, "LVTPC", lvt[APIC_LVT_PERFORM], false);
+ dump_apic_lvt(f, cpu_fprintf, "LVTERR", lvt[APIC_LVT_ERROR], false);
+ dump_apic_lvt(f, cpu_fprintf, "LVTTHMR", lvt[APIC_LVT_THERMAL], false);
+ dump_apic_lvt(f, cpu_fprintf, "LVTT", lvt[APIC_LVT_TIMER], true);
+
+ cpu_fprintf(f, "Timer\t DCR=0x%x (divide by %u) initial_count = %u\n",
+ s->divide_conf & APIC_DCR_MASK,
+ divider_conf(s->divide_conf),
+ s->initial_count);
+
+ cpu_fprintf(f, "SPIV\t 0x%08x APIC %s, focus=%s, spurious vec %u\n",
+ s->spurious_vec,
+ s->spurious_vec & APIC_SPURIO_ENABLED ? "enabled" : "disabled",
+ s->spurious_vec & APIC_SPURIO_FOCUS ? "on" : "off",
+ s->spurious_vec & APIC_VECTOR_MASK);
+
+ dump_apic_icr(f, cpu_fprintf, s, &cpu->env);
+
+ cpu_fprintf(f, "ESR\t 0x%08x\n", s->esr);
+
+ dump_apic_interrupt(f, cpu_fprintf, "ISR", s->isr, s->tmr);
+ dump_apic_interrupt(f, cpu_fprintf, "IRR", s->irr, s->tmr);
+
+ cpu_fprintf(f, "\nAPR 0x%02x TPR 0x%02x DFR 0x%02x LDR 0x%02x",
+ s->arb_id, s->tpr, s->dest_mode, s->log_dest);
+ if (s->dest_mode == 0) {
+ cpu_fprintf(f, "(cluster %u: id %u)",
+ s->log_dest >> APIC_LOGDEST_XAPIC_SHIFT,
+ s->log_dest & APIC_LOGDEST_XAPIC_ID);
+ }
+ cpu_fprintf(f, " PPR 0x%02x\n", apic_get_ppr(s));
+}
+#else
+void x86_cpu_dump_local_apic_state(CPUState *cs, FILE *f,
+ fprintf_function cpu_fprintf, int flags)
+{
+}
+#endif /* !CONFIG_USER_ONLY */
+
#define DUMP_CODE_BYTES_TOTAL 50
#define DUMP_CODE_BYTES_BACKWARD 20
diff --git a/target-i386/monitor.c b/target-i386/monitor.c
index 6ac86360e9..aac6b1ba8e 100644
--- a/target-i386/monitor.c
+++ b/target-i386/monitor.c
@@ -24,6 +24,8 @@
#include "cpu.h"
#include "monitor/monitor.h"
#include "monitor/hmp-target.h"
+#include "hw/i386/pc.h"
+#include "sysemu/kvm.h"
#include "hmp.h"
@@ -492,3 +494,18 @@ const MonitorDef *target_monitor_defs(void)
{
return monitor_defs;
}
+
+void hmp_info_local_apic(Monitor *mon, const QDict *qdict)
+{
+ x86_cpu_dump_local_apic_state(mon_get_cpu(), (FILE *)mon, monitor_fprintf,
+ CPU_DUMP_FPU);
+}
+
+void hmp_info_io_apic(Monitor *mon, const QDict *qdict)
+{
+ if (kvm_irqchip_in_kernel()) {
+ kvm_ioapic_dump_state(mon, qdict);
+ } else {
+ ioapic_dump_state(mon, qdict);
+ }
+}
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 1a3a2e7573..1cbe559366 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -1321,6 +1321,9 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
if (interrupt_request & CPU_INTERRUPT_POLL) {
cs->interrupt_request &= ~CPU_INTERRUPT_POLL;
apic_poll_irq(cpu->apic_state);
+ /* Don't process multiple interrupt requests in a single call.
+ This is required to make icount-driven execution deterministic. */
+ return true;
}
#endif
if (interrupt_request & CPU_INTERRUPT_SIPI) {
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index cc7726301e..3f874d5111 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -30,8 +30,6 @@
struct CPULM32State;
typedef struct CPULM32State CPULM32State;
-#define ELF_MACHINE EM_LATTICEMICO32
-
#define NB_MMU_MODES 1
#define TARGET_PAGE_BITS 12
static inline int cpu_mmu_index(CPULM32State *env, bool ifetch)
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 43a9a1c612..d1957063b4 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -32,8 +32,6 @@
#define MAX_QREGS 32
-#define ELF_MACHINE EM_68K
-
#define EXCP_ACCESS 2 /* Access (MMU) error. */
#define EXCP_ADDRESS 3 /* Address error. */
#define EXCP_ILLEGAL 4 /* Illegal instruction. */
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 402124a051..b707c71367 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -34,8 +34,6 @@ typedef struct CPUMBState CPUMBState;
#include "mmu.h"
#endif
-#define ELF_MACHINE EM_MICROBLAZE
-
#define EXCP_MMU 1
#define EXCP_IRQ 2
#define EXCP_BREAK 3
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index ed7d86d779..ec5f991dfb 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -5,8 +5,6 @@
#define ALIGNED_ONLY
-#define ELF_MACHINE EM_MIPS
-
#define CPUArchState struct CPUMIPSState
#include "config.h"
diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
index 15ca15bf53..2bac15bf60 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -26,8 +26,6 @@
#define CPUArchState struct CPUMoxieState
-#define ELF_MACHINE 0xFEED /* EM_MOXIE */
-
#define MOXIE_EX_DIV0 0
#define MOXIE_EX_BAD 1
#define MOXIE_EX_IRQ 2
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 560210d9e5..1ff1c9ec2a 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -21,7 +21,6 @@
#define CPU_OPENRISC_H
#define TARGET_LONG_BITS 32
-#define ELF_MACHINE EM_OPENRISC
#define CPUArchState struct CPUOpenRISCState
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 406d308960..c6dbb38fea 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -81,9 +81,9 @@
#include "fpu/softfloat.h"
#if defined (TARGET_PPC64)
-#define ELF_MACHINE EM_PPC64
+#define PPC_ELF_MACHINE EM_PPC64
#else
-#define ELF_MACHINE EM_PPC
+#define PPC_ELF_MACHINE EM_PPC
#endif
/*****************************************************************************/
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 9aeb0241fb..5acd54c6ca 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -27,7 +27,6 @@
#define TARGET_LONG_BITS 64
-#define ELF_MACHINE EM_S390
#define ELF_MACHINE_UNAME "S390X"
#define CPUArchState struct CPUS390XState
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index 1f68b27a90..6fb63215ef 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -24,8 +24,6 @@
#define TARGET_LONG_BITS 32
-#define ELF_MACHINE EM_SH
-
/* CPU Subtypes */
#define SH_CPU_SH7750 (1 << 0)
#define SH_CPU_SH7750S (1 << 1)
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 72ea1710ae..053edd5ed1 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -31,12 +31,6 @@
#include "fpu/softfloat.h"
-#if !defined(TARGET_SPARC64)
-#define ELF_MACHINE EM_SPARC
-#else
-#define ELF_MACHINE EM_SPARCV9
-#endif
-
/*#define EXCP_INTERRUPT 0x100*/
/* trap definitions */
diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h
index 42751e8a0c..20a12f3a40 100644
--- a/target-tricore/cpu.h
+++ b/target-tricore/cpu.h
@@ -25,8 +25,6 @@
#include "exec/cpu-defs.h"
#include "fpu/softfloat.h"
-#define ELF_MACHINE EM_TRICORE
-
#define CPUArchState struct CPUTriCoreState
struct CPUTriCoreState;
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index 121e5283d7..01c370c30d 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -17,8 +17,6 @@
#define TARGET_PHYS_ADDR_SPACE_BITS 32
#define TARGET_VIRT_ADDR_SPACE_BITS 32
-#define ELF_MACHINE EM_UNICORE32
-
#define CPUArchState struct CPUUniCore32State
#include "config.h"
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index dbd2c9cd0f..148a0f8d92 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -30,7 +30,6 @@
#define ALIGNED_ONLY
#define TARGET_LONG_BITS 32
-#define ELF_MACHINE EM_XTENSA
#define CPUArchState struct CPUXtensaState
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index 0046c61fe9..a3de6ab870 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1352,6 +1352,86 @@ static void test_qemu_strtoull_full_max(void)
g_assert_cmpint(res, ==, ULLONG_MAX);
}
+static void test_qemu_strtosz_simple(void)
+{
+ const char *str = "12345M";
+ char *endptr = NULL;
+ int64_t res;
+
+ res = qemu_strtosz(str, &endptr);
+ g_assert_cmpint(res, ==, 12345 * M_BYTE);
+ g_assert(endptr == str + 6);
+
+ res = qemu_strtosz(str, NULL);
+ g_assert_cmpint(res, ==, 12345 * M_BYTE);
+}
+
+static void test_qemu_strtosz_units(void)
+{
+ const char *none = "1";
+ const char *b = "1B";
+ const char *k = "1K";
+ const char *m = "1M";
+ const char *g = "1G";
+ const char *t = "1T";
+ const char *p = "1P";
+ const char *e = "1E";
+ int64_t res;
+
+ /* default is M */
+ res = qemu_strtosz(none, NULL);
+ g_assert_cmpint(res, ==, M_BYTE);
+
+ res = qemu_strtosz(b, NULL);
+ g_assert_cmpint(res, ==, 1);
+
+ res = qemu_strtosz(k, NULL);
+ g_assert_cmpint(res, ==, K_BYTE);
+
+ res = qemu_strtosz(m, NULL);
+ g_assert_cmpint(res, ==, M_BYTE);
+
+ res = qemu_strtosz(g, NULL);
+ g_assert_cmpint(res, ==, G_BYTE);
+
+ res = qemu_strtosz(t, NULL);
+ g_assert_cmpint(res, ==, T_BYTE);
+
+ res = qemu_strtosz(p, NULL);
+ g_assert_cmpint(res, ==, P_BYTE);
+
+ res = qemu_strtosz(e, NULL);
+ g_assert_cmpint(res, ==, E_BYTE);
+}
+
+static void test_qemu_strtosz_float(void)
+{
+ const char *str = "12.345M";
+ int64_t res;
+
+ res = qemu_strtosz(str, NULL);
+ g_assert_cmpint(res, ==, 12.345 * M_BYTE);
+}
+
+static void test_qemu_strtosz_erange(void)
+{
+ const char *str = "10E";
+ int64_t res;
+
+ res = qemu_strtosz(str, NULL);
+ g_assert_cmpint(res, ==, -ERANGE);
+}
+
+static void test_qemu_strtosz_suffix_unit(void)
+{
+ const char *str = "12345";
+ int64_t res;
+
+ res = qemu_strtosz_suffix_unit(str, NULL,
+ QEMU_STRTOSZ_DEFSUFFIX_KB, 1000);
+ g_assert_cmpint(res, ==, 12345000);
+}
+
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
@@ -1502,5 +1582,16 @@ int main(int argc, char **argv)
g_test_add_func("/cutils/qemu_strtoull_full/max",
test_qemu_strtoull_full_max);
+ g_test_add_func("/cutils/strtosz/simple",
+ test_qemu_strtosz_simple);
+ g_test_add_func("/cutils/strtosz/units",
+ test_qemu_strtosz_units);
+ g_test_add_func("/cutils/strtosz/float",
+ test_qemu_strtosz_float);
+ g_test_add_func("/cutils/strtosz/erange",
+ test_qemu_strtosz_erange);
+ g_test_add_func("/cutils/strtosz/suffix-unit",
+ test_qemu_strtosz_suffix_unit);
+
return g_test_run();
}
diff --git a/util/cutils.c b/util/cutils.c
index ae351984d9..cfeb848d19 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -276,19 +276,19 @@ int fcntl_setfl(int fd, int flag)
static int64_t suffix_mul(char suffix, int64_t unit)
{
switch (qemu_toupper(suffix)) {
- case STRTOSZ_DEFSUFFIX_B:
+ case QEMU_STRTOSZ_DEFSUFFIX_B:
return 1;
- case STRTOSZ_DEFSUFFIX_KB:
+ case QEMU_STRTOSZ_DEFSUFFIX_KB:
return unit;
- case STRTOSZ_DEFSUFFIX_MB:
+ case QEMU_STRTOSZ_DEFSUFFIX_MB:
return unit * unit;
- case STRTOSZ_DEFSUFFIX_GB:
+ case QEMU_STRTOSZ_DEFSUFFIX_GB:
return unit * unit * unit;
- case STRTOSZ_DEFSUFFIX_TB:
+ case QEMU_STRTOSZ_DEFSUFFIX_TB:
return unit * unit * unit * unit;
- case STRTOSZ_DEFSUFFIX_PB:
+ case QEMU_STRTOSZ_DEFSUFFIX_PB:
return unit * unit * unit * unit * unit;
- case STRTOSZ_DEFSUFFIX_EB:
+ case QEMU_STRTOSZ_DEFSUFFIX_EB:
return unit * unit * unit * unit * unit * unit;
}
return -1;
@@ -300,7 +300,7 @@ static int64_t suffix_mul(char suffix, int64_t unit)
* in *end, if not NULL. Return -ERANGE on overflow, Return -EINVAL on
* other error.
*/
-int64_t strtosz_suffix_unit(const char *nptr, char **end,
+int64_t qemu_strtosz_suffix_unit(const char *nptr, char **end,
const char default_suffix, int64_t unit)
{
int64_t retval = -EINVAL;
@@ -343,14 +343,15 @@ fail:
return retval;
}
-int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix)
+int64_t qemu_strtosz_suffix(const char *nptr, char **end,
+ const char default_suffix)
{
- return strtosz_suffix_unit(nptr, end, default_suffix, 1024);
+ return qemu_strtosz_suffix_unit(nptr, end, default_suffix, 1024);
}
-int64_t strtosz(const char *nptr, char **end)
+int64_t qemu_strtosz(const char *nptr, char **end)
{
- return strtosz_suffix(nptr, end, STRTOSZ_DEFSUFFIX_MB);
+ return qemu_strtosz_suffix(nptr, end, QEMU_STRTOSZ_DEFSUFFIX_MB);
}
/**