aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rwxr-xr-xQMP/qom-fuse138
-rw-r--r--async.c2
-rw-r--r--audio/paaudio.c3
-rwxr-xr-xconfigure6
-rw-r--r--hw/hda-audio.c243
-rw-r--r--hw/pc_sysfw.c8
-rw-r--r--hw/virtio-serial-bus.c57
-rw-r--r--main-loop.c23
-rw-r--r--main-loop.h2
-rw-r--r--os-posix.c4
-rw-r--r--pc-bios/qemu-icon.bmpbin0 -> 630 bytes
-rw-r--r--qemu-timer.c33
-rw-r--r--qemu-timer.h1
-rw-r--r--qemu-tool.c4
-rw-r--r--slirp/libslirp.h1
-rw-r--r--slirp/slirp.c7
-rw-r--r--target-i386/cpu.c318
-rw-r--r--target-i386/cpu.h2
-rw-r--r--target-i386/helper.c2
-rw-r--r--tests/libqtest.c7
21 files changed, 746 insertions, 116 deletions
diff --git a/Makefile b/Makefile
index 4f43793866..121cad4b14 100644
--- a/Makefile
+++ b/Makefile
@@ -257,6 +257,7 @@ vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin \
ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc \
pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \
pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
+qemu-icon.bmp \
bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
mpc8544ds.dtb \
multiboot.bin linuxboot.bin kvmvapic.bin \
diff --git a/QMP/qom-fuse b/QMP/qom-fuse
new file mode 100755
index 0000000000..5c6754aa63
--- /dev/null
+++ b/QMP/qom-fuse
@@ -0,0 +1,138 @@
+#!/usr/bin/python
+##
+# QEMU Object Model test tools
+#
+# Copyright IBM, Corp. 2012
+#
+# Authors:
+# Anthony Liguori <aliguori@us.ibm.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later. See
+# the COPYING file in the top-level directory.
+##
+
+import fuse, stat
+from fuse import Fuse
+import os, posix
+from errno import *
+from qmp import QEMUMonitorProtocol
+
+fuse.fuse_python_api = (0, 2)
+
+class QOMFS(Fuse):
+ def __init__(self, qmp, *args, **kwds):
+ Fuse.__init__(self, *args, **kwds)
+ self.qmp = qmp
+ self.qmp.connect()
+ self.ino_map = {}
+ self.ino_count = 1
+
+ def get_ino(self, path):
+ if self.ino_map.has_key(path):
+ return self.ino_map[path]
+ self.ino_map[path] = self.ino_count
+ self.ino_count += 1
+ return self.ino_map[path]
+
+ def is_object(self, path):
+ try:
+ items = self.qmp.command('qom-list', path=path)
+ return True
+ except:
+ return False
+
+ def is_property(self, path):
+ try:
+ path, prop = path.rsplit('/', 1)
+ for item in self.qmp.command('qom-list', path=path):
+ if item['name'] == prop:
+ return True
+ return False
+ except:
+ return False
+
+ def is_link(self, path):
+ try:
+ path, prop = path.rsplit('/', 1)
+ for item in self.qmp.command('qom-list', path=path):
+ if item['name'] == prop:
+ if item['type'].startswith('link<'):
+ return True
+ return False
+ return False
+ except:
+ return False
+
+ def read(self, path, length, offset):
+ if not self.is_property(path):
+ return -ENOENT
+
+ path, prop = path.rsplit('/', 1)
+ try:
+ data = str(self.qmp.command('qom-get', path=path, property=prop))
+ data += '\n' # make values shell friendly
+ except:
+ return -EPERM
+
+ if offset > len(data):
+ return ''
+
+ return str(data[offset:][:length])
+
+ def readlink(self, path):
+ if not self.is_link(path):
+ return False
+ path, prop = path.rsplit('/', 1)
+ prefix = '/'.join(['..'] * (len(path.split('/')) - 1))
+ return prefix + str(self.qmp.command('qom-get', path=path,
+ property=prop))
+
+ def getattr(self, path):
+ if self.is_link(path):
+ value = posix.stat_result((0755 | stat.S_IFLNK,
+ self.get_ino(path),
+ 0,
+ 2,
+ 1000,
+ 1000,
+ 4096,
+ 0,
+ 0,
+ 0))
+ elif self.is_object(path):
+ value = posix.stat_result((0755 | stat.S_IFDIR,
+ self.get_ino(path),
+ 0,
+ 2,
+ 1000,
+ 1000,
+ 4096,
+ 0,
+ 0,
+ 0))
+ elif self.is_property(path):
+ value = posix.stat_result((0644 | stat.S_IFREG,
+ self.get_ino(path),
+ 0,
+ 1,
+ 1000,
+ 1000,
+ 4096,
+ 0,
+ 0,
+ 0))
+ else:
+ value = -ENOENT
+ return value
+
+ def readdir(self, path, offset):
+ yield fuse.Direntry('.')
+ yield fuse.Direntry('..')
+ for item in self.qmp.command('qom-list', path=path):
+ yield fuse.Direntry(str(item['name']))
+
+if __name__ == '__main__':
+ import sys, os
+
+ fs = QOMFS(QEMUMonitorProtocol(os.environ['QMP_SOCKET']))
+ fs.main(sys.argv)
diff --git a/async.c b/async.c
index 332d511ed5..ecdaf15887 100644
--- a/async.c
+++ b/async.c
@@ -120,7 +120,7 @@ void qemu_bh_delete(QEMUBH *bh)
bh->deleted = 1;
}
-void qemu_bh_update_timeout(int *timeout)
+void qemu_bh_update_timeout(uint32_t *timeout)
{
QEMUBH *bh;
diff --git a/audio/paaudio.c b/audio/paaudio.c
index e6708d0db5..aa15f16ec7 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -505,8 +505,7 @@ fail:
pa_stream_unref (stream);
}
- qpa_logerr (pa_context_errno (g->context),
- "stream_new() failed\n");
+ *rerror = pa_context_errno (g->context);
return NULL;
}
diff --git a/configure b/configure
index dd09f1a18f..15bbc735c4 100755
--- a/configure
+++ b/configure
@@ -2898,11 +2898,9 @@ tools=
if test "$softmmu" = yes ; then
tools="qemu-img\$(EXESUF) qemu-io\$(EXESUF) $tools"
if test "$virtfs" != no ; then
- if test "$linux" = yes && test "$attr" = yes ; then
+ if test "$cap" = yes && test "$linux" = yes && test "$attr" = yes ; then
virtfs=yes
- if test "$cap" = yes ; then
- tools="$tools fsdev/virtfs-proxy-helper\$(EXESUF)"
- fi
+ tools="$tools fsdev/virtfs-proxy-helper\$(EXESUF)"
else
if test "$virtfs" = yes; then
feature_not_found "virtfs"
diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index 8995519573..36761dd2de 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -113,22 +113,25 @@ static void hda_codec_parse_fmt(uint32_t format, struct audsettings *as)
/* some defines */
#define QEMU_HDA_ID_VENDOR 0x1af4
-#define QEMU_HDA_ID_OUTPUT ((QEMU_HDA_ID_VENDOR << 16) | 0x10)
-#define QEMU_HDA_ID_DUPLEX ((QEMU_HDA_ID_VENDOR << 16) | 0x20)
-
#define QEMU_HDA_PCM_FORMATS (AC_SUPPCM_BITS_16 | \
0x1fc /* 16 -> 96 kHz */)
#define QEMU_HDA_AMP_NONE (0)
#define QEMU_HDA_AMP_STEPS 0x4a
#ifdef CONFIG_MIXEMU
-#define QEMU_HDA_AMP_CAPS \
+# define QEMU_HDA_ID_OUTPUT ((QEMU_HDA_ID_VENDOR << 16) | 0x12)
+# define QEMU_HDA_ID_DUPLEX ((QEMU_HDA_ID_VENDOR << 16) | 0x22)
+# define QEMU_HDA_ID_MICRO ((QEMU_HDA_ID_VENDOR << 16) | 0x32)
+# define QEMU_HDA_AMP_CAPS \
(AC_AMPCAP_MUTE | \
(QEMU_HDA_AMP_STEPS << AC_AMPCAP_OFFSET_SHIFT) | \
(QEMU_HDA_AMP_STEPS << AC_AMPCAP_NUM_STEPS_SHIFT) | \
(3 << AC_AMPCAP_STEP_SIZE_SHIFT))
#else
-#define QEMU_HDA_AMP_CAPS QEMU_HDA_AMP_NONE
+# define QEMU_HDA_ID_OUTPUT ((QEMU_HDA_ID_VENDOR << 16) | 0x11)
+# define QEMU_HDA_ID_DUPLEX ((QEMU_HDA_ID_VENDOR << 16) | 0x21)
+# define QEMU_HDA_ID_MICRO ((QEMU_HDA_ID_VENDOR << 16) | 0x31)
+# define QEMU_HDA_AMP_CAPS QEMU_HDA_AMP_NONE
#endif
/* common: audio output widget */
@@ -155,6 +158,34 @@ static const desc_param common_params_audio_dac[] = {
},
};
+/* common: audio input widget */
+static const desc_param common_params_audio_adc[] = {
+ {
+ .id = AC_PAR_AUDIO_WIDGET_CAP,
+ .val = ((AC_WID_AUD_IN << AC_WCAP_TYPE_SHIFT) |
+ AC_WCAP_CONN_LIST |
+ AC_WCAP_FORMAT_OVRD |
+ AC_WCAP_AMP_OVRD |
+ AC_WCAP_IN_AMP |
+ AC_WCAP_STEREO),
+ },{
+ .id = AC_PAR_CONNLIST_LEN,
+ .val = 1,
+ },{
+ .id = AC_PAR_PCM,
+ .val = QEMU_HDA_PCM_FORMATS,
+ },{
+ .id = AC_PAR_STREAM,
+ .val = AC_SUPFMT_PCM,
+ },{
+ .id = AC_PAR_AMP_IN_CAP,
+ .val = QEMU_HDA_AMP_CAPS,
+ },{
+ .id = AC_PAR_AMP_OUT_CAP,
+ .val = QEMU_HDA_AMP_NONE,
+ },
+};
+
/* common: pin widget (line-out) */
static const desc_param common_params_audio_lineout[] = {
{
@@ -177,6 +208,24 @@ static const desc_param common_params_audio_lineout[] = {
},
};
+/* common: pin widget (line-in) */
+static const desc_param common_params_audio_linein[] = {
+ {
+ .id = AC_PAR_AUDIO_WIDGET_CAP,
+ .val = ((AC_WID_PIN << AC_WCAP_TYPE_SHIFT) |
+ AC_WCAP_STEREO),
+ },{
+ .id = AC_PAR_PIN_CAP,
+ .val = AC_PINCAP_IN,
+ },{
+ .id = AC_PAR_AMP_IN_CAP,
+ .val = QEMU_HDA_AMP_NONE,
+ },{
+ .id = AC_PAR_AMP_OUT_CAP,
+ .val = QEMU_HDA_AMP_NONE,
+ },
+};
+
/* output: root node */
static const desc_param output_params_root[] = {
{
@@ -287,19 +336,17 @@ static const desc_param duplex_params_root[] = {
},
};
-/* duplex: audio input widget */
-static const desc_param duplex_params_audio_adc[] = {
+/* duplex: audio function */
+static const desc_param duplex_params_audio_func[] = {
{
- .id = AC_PAR_AUDIO_WIDGET_CAP,
- .val = ((AC_WID_AUD_IN << AC_WCAP_TYPE_SHIFT) |
- AC_WCAP_CONN_LIST |
- AC_WCAP_FORMAT_OVRD |
- AC_WCAP_AMP_OVRD |
- AC_WCAP_IN_AMP |
- AC_WCAP_STEREO),
+ .id = AC_PAR_FUNCTION_TYPE,
+ .val = AC_GRP_AUDIO_FUNCTION,
},{
- .id = AC_PAR_CONNLIST_LEN,
- .val = 1,
+ .id = AC_PAR_SUBSYSTEM_ID,
+ .val = QEMU_HDA_ID_DUPLEX,
+ },{
+ .id = AC_PAR_NODE_COUNT,
+ .val = 0x00020004,
},{
.id = AC_PAR_PCM,
.val = QEMU_HDA_PCM_FORMATS,
@@ -308,39 +355,106 @@ static const desc_param duplex_params_audio_adc[] = {
.val = AC_SUPFMT_PCM,
},{
.id = AC_PAR_AMP_IN_CAP,
- .val = QEMU_HDA_AMP_CAPS,
+ .val = QEMU_HDA_AMP_NONE,
},{
.id = AC_PAR_AMP_OUT_CAP,
.val = QEMU_HDA_AMP_NONE,
+ },{
+ .id = AC_PAR_GPIO_CAP,
+ .val = 0,
+ },{
+ .id = AC_PAR_AUDIO_FG_CAP,
+ .val = 0x00000808,
+ },{
+ .id = AC_PAR_POWER_STATE,
+ .val = 0,
},
};
-/* duplex: pin widget (line-in) */
-static const desc_param duplex_params_audio_linein[] = {
+/* duplex: nodes */
+static const desc_node duplex_nodes[] = {
{
- .id = AC_PAR_AUDIO_WIDGET_CAP,
- .val = ((AC_WID_PIN << AC_WCAP_TYPE_SHIFT) |
- AC_WCAP_STEREO),
+ .nid = AC_NODE_ROOT,
+ .name = "root",
+ .params = duplex_params_root,
+ .nparams = ARRAY_SIZE(duplex_params_root),
},{
- .id = AC_PAR_PIN_CAP,
- .val = AC_PINCAP_IN,
+ .nid = 1,
+ .name = "func",
+ .params = duplex_params_audio_func,
+ .nparams = ARRAY_SIZE(duplex_params_audio_func),
},{
- .id = AC_PAR_AMP_IN_CAP,
- .val = QEMU_HDA_AMP_NONE,
+ .nid = 2,
+ .name = "dac",
+ .params = common_params_audio_dac,
+ .nparams = ARRAY_SIZE(common_params_audio_dac),
+ .stindex = 0,
},{
- .id = AC_PAR_AMP_OUT_CAP,
- .val = QEMU_HDA_AMP_NONE,
+ .nid = 3,
+ .name = "out",
+ .params = common_params_audio_lineout,
+ .nparams = ARRAY_SIZE(common_params_audio_lineout),
+ .config = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
+ (AC_JACK_LINE_OUT << AC_DEFCFG_DEVICE_SHIFT) |
+ (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
+ (AC_JACK_COLOR_GREEN << AC_DEFCFG_COLOR_SHIFT) |
+ 0x10),
+ .pinctl = AC_PINCTL_OUT_EN,
+ .conn = (uint32_t[]) { 2 },
+ },{
+ .nid = 4,
+ .name = "adc",
+ .params = common_params_audio_adc,
+ .nparams = ARRAY_SIZE(common_params_audio_adc),
+ .stindex = 1,
+ .conn = (uint32_t[]) { 5 },
+ },{
+ .nid = 5,
+ .name = "in",
+ .params = common_params_audio_linein,
+ .nparams = ARRAY_SIZE(common_params_audio_linein),
+ .config = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
+ (AC_JACK_LINE_IN << AC_DEFCFG_DEVICE_SHIFT) |
+ (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
+ (AC_JACK_COLOR_RED << AC_DEFCFG_COLOR_SHIFT) |
+ 0x20),
+ .pinctl = AC_PINCTL_IN_EN,
+ }
+};
+
+/* duplex: codec */
+static const desc_codec duplex = {
+ .name = "duplex",
+ .iid = QEMU_HDA_ID_DUPLEX,
+ .nodes = duplex_nodes,
+ .nnodes = ARRAY_SIZE(duplex_nodes),
+};
+
+/* micro: root node */
+static const desc_param micro_params_root[] = {
+ {
+ .id = AC_PAR_VENDOR_ID,
+ .val = QEMU_HDA_ID_MICRO,
+ },{
+ .id = AC_PAR_SUBSYSTEM_ID,
+ .val = QEMU_HDA_ID_MICRO,
+ },{
+ .id = AC_PAR_REV_ID,
+ .val = 0x00100101,
+ },{
+ .id = AC_PAR_NODE_COUNT,
+ .val = 0x00010001,
},
};
-/* duplex: audio function */
-static const desc_param duplex_params_audio_func[] = {
+/* micro: audio function */
+static const desc_param micro_params_audio_func[] = {
{
.id = AC_PAR_FUNCTION_TYPE,
.val = AC_GRP_AUDIO_FUNCTION,
},{
.id = AC_PAR_SUBSYSTEM_ID,
- .val = QEMU_HDA_ID_DUPLEX,
+ .val = QEMU_HDA_ID_MICRO,
},{
.id = AC_PAR_NODE_COUNT,
.val = 0x00020004,
@@ -368,18 +482,18 @@ static const desc_param duplex_params_audio_func[] = {
},
};
-/* duplex: nodes */
-static const desc_node duplex_nodes[] = {
+/* micro: nodes */
+static const desc_node micro_nodes[] = {
{
.nid = AC_NODE_ROOT,
.name = "root",
- .params = duplex_params_root,
- .nparams = ARRAY_SIZE(duplex_params_root),
+ .params = micro_params_root,
+ .nparams = ARRAY_SIZE(micro_params_root),
},{
.nid = 1,
.name = "func",
- .params = duplex_params_audio_func,
- .nparams = ARRAY_SIZE(duplex_params_audio_func),
+ .params = micro_params_audio_func,
+ .nparams = ARRAY_SIZE(micro_params_audio_func),
},{
.nid = 2,
.name = "dac",
@@ -392,7 +506,7 @@ static const desc_node duplex_nodes[] = {
.params = common_params_audio_lineout,
.nparams = ARRAY_SIZE(common_params_audio_lineout),
.config = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
- (AC_JACK_LINE_OUT << AC_DEFCFG_DEVICE_SHIFT) |
+ (AC_JACK_SPEAKER << AC_DEFCFG_DEVICE_SHIFT) |
(AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
(AC_JACK_COLOR_GREEN << AC_DEFCFG_COLOR_SHIFT) |
0x10),
@@ -401,17 +515,17 @@ static const desc_node duplex_nodes[] = {
},{
.nid = 4,
.name = "adc",
- .params = duplex_params_audio_adc,
- .nparams = ARRAY_SIZE(duplex_params_audio_adc),
+ .params = common_params_audio_adc,
+ .nparams = ARRAY_SIZE(common_params_audio_adc),
.stindex = 1,
.conn = (uint32_t[]) { 5 },
},{
.nid = 5,
.name = "in",
- .params = duplex_params_audio_linein,
- .nparams = ARRAY_SIZE(duplex_params_audio_linein),
+ .params = common_params_audio_linein,
+ .nparams = ARRAY_SIZE(common_params_audio_linein),
.config = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
- (AC_JACK_LINE_IN << AC_DEFCFG_DEVICE_SHIFT) |
+ (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT) |
(AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
(AC_JACK_COLOR_RED << AC_DEFCFG_COLOR_SHIFT) |
0x20),
@@ -419,12 +533,12 @@ static const desc_node duplex_nodes[] = {
}
};
-/* duplex: codec */
-static const desc_codec duplex = {
- .name = "duplex",
- .iid = QEMU_HDA_ID_DUPLEX,
- .nodes = duplex_nodes,
- .nnodes = ARRAY_SIZE(duplex_nodes),
+/* micro: codec */
+static const desc_codec micro = {
+ .name = "micro",
+ .iid = QEMU_HDA_ID_MICRO,
+ .nodes = micro_nodes,
+ .nnodes = ARRAY_SIZE(micro_nodes),
};
/* -------------------------------------------------------------------------- */
@@ -906,6 +1020,11 @@ static int hda_audio_init_duplex(HDACodecDevice *hda)
return hda_audio_init(hda, &duplex);
}
+static int hda_audio_init_micro(HDACodecDevice *hda)
+{
+ return hda_audio_init(hda, &micro);
+}
+
static void hda_audio_output_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -915,7 +1034,7 @@ static void hda_audio_output_class_init(ObjectClass *klass, void *data)
k->exit = hda_audio_exit;
k->command = hda_audio_command;
k->stream = hda_audio_stream;
- dc->desc = "HDA Audio Codec, output-only";
+ dc->desc = "HDA Audio Codec, output-only (line-out)";
dc->vmsd = &vmstate_hda_audio;
dc->props = hda_audio_properties;
}
@@ -936,7 +1055,7 @@ static void hda_audio_duplex_class_init(ObjectClass *klass, void *data)
k->exit = hda_audio_exit;
k->command = hda_audio_command;
k->stream = hda_audio_stream;
- dc->desc = "HDA Audio Codec, duplex";
+ dc->desc = "HDA Audio Codec, duplex (line-out, line-in)";
dc->vmsd = &vmstate_hda_audio;
dc->props = hda_audio_properties;
}
@@ -948,10 +1067,32 @@ static TypeInfo hda_audio_duplex_info = {
.class_init = hda_audio_duplex_class_init,
};
+static void hda_audio_micro_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
+
+ k->init = hda_audio_init_micro;
+ k->exit = hda_audio_exit;
+ k->command = hda_audio_command;
+ k->stream = hda_audio_stream;
+ dc->desc = "HDA Audio Codec, duplex (speaker, microphone)";
+ dc->vmsd = &vmstate_hda_audio;
+ dc->props = hda_audio_properties;
+}
+
+static TypeInfo hda_audio_micro_info = {
+ .name = "hda-micro",
+ .parent = TYPE_HDA_CODEC_DEVICE,
+ .instance_size = sizeof(HDAAudioState),
+ .class_init = hda_audio_micro_class_init,
+};
+
static void hda_audio_register_types(void)
{
type_register_static(&hda_audio_output_info);
type_register_static(&hda_audio_duplex_info);
+ type_register_static(&hda_audio_micro_info);
}
type_init(hda_audio_register_types)
diff --git a/hw/pc_sysfw.c b/hw/pc_sysfw.c
index abf9004182..fafdf9b1c1 100644
--- a/hw/pc_sysfw.c
+++ b/hw/pc_sysfw.c
@@ -190,6 +190,8 @@ void pc_system_firmware_init(MemoryRegion *rom_memory)
sysfw_dev = (PcSysFwDevice*) qdev_create(NULL, "pc-sysfw");
+ qdev_init_nofail(DEVICE(sysfw_dev));
+
if (sysfw_dev->rom_only) {
old_pc_system_rom_init(rom_memory);
return;
@@ -230,11 +232,17 @@ static Property pcsysfw_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
+static int pcsysfw_init(DeviceState *dev)
+{
+ return 0;
+}
+
static void pcsysfw_class_init (ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS (klass);
dc->desc = "PC System Firmware";
+ dc->init = pcsysfw_init;
dc->props = pcsysfw_properties;
}
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index e22940ecb2..ffbdfc2de1 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -528,6 +528,53 @@ static void set_config(VirtIODevice *vdev, const uint8_t *config_data)
memcpy(&config, config_data, sizeof(config));
}
+static void guest_reset(VirtIOSerial *vser)
+{
+ VirtIOSerialPort *port;
+ VirtIOSerialPortClass *vsc;
+
+ QTAILQ_FOREACH(port, &vser->ports, next) {
+ vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
+ if (port->guest_connected) {
+ port->guest_connected = false;
+
+ if (vsc->guest_close)
+ vsc->guest_close(port);
+ }
+ }
+}
+
+static void set_status(VirtIODevice *vdev, uint8_t status)
+{
+ VirtIOSerial *vser;
+ VirtIOSerialPort *port;
+
+ vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
+ port = find_port_by_id(vser, 0);
+
+ if (port && !use_multiport(port->vser)
+ && (status & VIRTIO_CONFIG_S_DRIVER_OK)) {
+ /*
+ * Non-multiport guests won't be able to tell us guest
+ * open/close status. Such guests can only have a port at id
+ * 0, so set guest_connected for such ports as soon as guest
+ * is up.
+ */
+ port->guest_connected = true;
+ }
+ if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
+ guest_reset(vser);
+ }
+}
+
+static void vser_reset(VirtIODevice *vdev)
+{
+ VirtIOSerial *vser;
+
+ vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
+ guest_reset(vser);
+}
+
static void virtio_serial_save(QEMUFile *f, void *opaque)
{
VirtIOSerial *s = opaque;
@@ -798,14 +845,6 @@ static int virtser_port_qdev_init(DeviceState *qdev)
return ret;
}
- if (!use_multiport(port->vser)) {
- /*
- * Allow writes to guest in this case; we have no way of
- * knowing if a guest port is connected.
- */
- port->guest_connected = true;
- }
-
port->elem.out_num = 0;
QTAILQ_INSERT_TAIL(&port->vser->ports, port, next);
@@ -905,6 +944,8 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
vser->vdev.get_features = get_features;
vser->vdev.get_config = get_config;
vser->vdev.set_config = set_config;
+ vser->vdev.set_status = set_status;
+ vser->vdev.reset = vser_reset;
vser->qdev = dev;
diff --git a/main-loop.c b/main-loop.c
index 4887c732fa..0457bf26f4 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -226,7 +226,7 @@ static int max_priority;
#ifndef _WIN32
static void glib_select_fill(int *max_fd, fd_set *rfds, fd_set *wfds,
- fd_set *xfds, int *cur_timeout)
+ fd_set *xfds, uint32_t *cur_timeout)
{
GMainContext *context = g_main_context_default();
int i;
@@ -288,20 +288,24 @@ static void glib_select_poll(fd_set *rfds, fd_set *wfds, fd_set *xfds,
}
}
-static int os_host_main_loop_wait(int timeout)
+static int os_host_main_loop_wait(uint32_t timeout)
{
- struct timeval tv;
+ struct timeval tv, *tvarg = NULL;
int ret;
glib_select_fill(&nfds, &rfds, &wfds, &xfds, &timeout);
+ if (timeout < UINT32_MAX) {
+ tvarg = &tv;
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ }
+
if (timeout > 0) {
qemu_mutex_unlock_iothread();
}
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
- ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
+ ret = select(nfds + 1, &rfds, &wfds, &xfds, tvarg);
if (timeout > 0) {
qemu_mutex_lock_iothread();
@@ -400,7 +404,7 @@ void qemu_fd_register(int fd)
FD_CONNECT | FD_WRITE | FD_OOB);
}
-static int os_host_main_loop_wait(int timeout)
+static int os_host_main_loop_wait(uint32_t timeout)
{
GMainContext *context = g_main_context_default();
int ret, i;
@@ -463,12 +467,12 @@ static int os_host_main_loop_wait(int timeout)
int main_loop_wait(int nonblocking)
{
- int ret, timeout;
+ int ret;
+ uint32_t timeout = UINT32_MAX;
if (nonblocking) {
timeout = 0;
} else {
- timeout = qemu_calculate_timeout();
qemu_bh_update_timeout(&timeout);
}
@@ -480,6 +484,7 @@ int main_loop_wait(int nonblocking)
FD_ZERO(&xfds);
#ifdef CONFIG_SLIRP
+ slirp_update_timeout(&timeout);
slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
#endif
qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
diff --git a/main-loop.h b/main-loop.h
index e743aa0cf6..c06b8bc441 100644
--- a/main-loop.h
+++ b/main-loop.h
@@ -365,6 +365,6 @@ void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int rc
void qemu_bh_schedule_idle(QEMUBH *bh);
int qemu_bh_poll(void);
-void qemu_bh_update_timeout(int *timeout);
+void qemu_bh_update_timeout(uint32_t *timeout);
#endif
diff --git a/os-posix.c b/os-posix.c
index e3ed497224..daf3d6f6f3 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -44,6 +44,10 @@
#include <sys/prctl.h>
#endif
+#ifdef __FreeBSD__
+#include <sys/sysctl.h>
+#endif
+
static struct passwd *user_pwd;
static const char *chroot_dir;
static int daemonize;
diff --git a/pc-bios/qemu-icon.bmp b/pc-bios/qemu-icon.bmp
new file mode 100644
index 0000000000..72d9a2f561
--- /dev/null
+++ b/pc-bios/qemu-icon.bmp
Binary files differ
diff --git a/qemu-timer.c b/qemu-timer.c
index 17915df22d..0b28edad1c 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -106,23 +106,21 @@ static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
static int64_t qemu_next_alarm_deadline(void)
{
- int64_t delta;
+ int64_t delta = INT64_MAX;
int64_t rtdelta;
- if (!use_icount && vm_clock->active_timers) {
+ if (!use_icount && vm_clock->enabled && vm_clock->active_timers) {
delta = vm_clock->active_timers->expire_time -
qemu_get_clock_ns(vm_clock);
- } else {
- delta = INT32_MAX;
}
- if (host_clock->active_timers) {
+ if (host_clock->enabled && host_clock->active_timers) {
int64_t hdelta = host_clock->active_timers->expire_time -
qemu_get_clock_ns(host_clock);
if (hdelta < delta) {
delta = hdelta;
}
}
- if (rt_clock->active_timers) {
+ if (rt_clock->enabled && rt_clock->active_timers) {
rtdelta = (rt_clock->active_timers->expire_time -
qemu_get_clock_ns(rt_clock));
if (rtdelta < delta) {
@@ -696,13 +694,17 @@ static void mm_stop_timer(struct qemu_alarm_timer *t)
static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta)
{
- int nearest_delta_ms = (delta + 999999) / 1000000;
+ int64_t nearest_delta_ms = delta / 1000000;
if (nearest_delta_ms < 1) {
nearest_delta_ms = 1;
}
+ /* UINT_MAX can be 32 bit */
+ if (nearest_delta_ms > UINT_MAX) {
+ nearest_delta_ms = UINT_MAX;
+ }
timeKillEvent(mm_timer);
- mm_timer = timeSetEvent(nearest_delta_ms,
+ mm_timer = timeSetEvent((unsigned int) nearest_delta_ms,
mm_period,
mm_alarm_handler,
(DWORD_PTR)t,
@@ -757,16 +759,20 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t,
int64_t nearest_delta_ns)
{
HANDLE hTimer = t->timer;
- int nearest_delta_ms;
+ int64_t nearest_delta_ms;
BOOLEAN success;
- nearest_delta_ms = (nearest_delta_ns + 999999) / 1000000;
+ nearest_delta_ms = nearest_delta_ns / 1000000;
if (nearest_delta_ms < 1) {
nearest_delta_ms = 1;
}
+ /* ULONG_MAX can be 32 bit */
+ if (nearest_delta_ms > ULONG_MAX) {
+ nearest_delta_ms = ULONG_MAX;
+ }
success = ChangeTimerQueueTimer(NULL,
hTimer,
- nearest_delta_ms,
+ (unsigned long) nearest_delta_ms,
3600000);
if (!success) {
@@ -815,8 +821,3 @@ fail:
return err;
}
-int qemu_calculate_timeout(void)
-{
- return 1000;
-}
-
diff --git a/qemu-timer.h b/qemu-timer.h
index 661bbe76b2..094e730ca2 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -63,7 +63,6 @@ void qemu_run_timers(QEMUClock *clock);
void qemu_run_all_timers(void);
int qemu_alarm_pending(void);
void configure_alarms(char const *opt);
-int qemu_calculate_timeout(void);
void init_clocks(void);
int init_timer_alarm(void);
diff --git a/qemu-tool.c b/qemu-tool.c
index 6579b00552..07fc4f201a 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -90,6 +90,10 @@ int qemu_init_main_loop(void)
return main_loop_init();
}
+void slirp_update_timeout(uint32_t *timeout)
+{
+}
+
void slirp_select_fill(int *pnfds, fd_set *readfds,
fd_set *writefds, fd_set *xfds)
{
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 890fd86c3c..77527ad922 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -15,6 +15,7 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
struct in_addr vnameserver, void *opaque);
void slirp_cleanup(Slirp *slirp);
+void slirp_update_timeout(uint32_t *timeout);
void slirp_select_fill(int *pnfds,
fd_set *readfds, fd_set *writefds, fd_set *xfds);
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 1502830978..90473eb74a 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -258,6 +258,13 @@ void slirp_cleanup(Slirp *slirp)
#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
#define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
+void slirp_update_timeout(uint32_t *timeout)
+{
+ if (!QTAILQ_EMPTY(&slirp_instances)) {
+ *timeout = MIN(1000, *timeout);
+ }
+}
+
void slirp_select_fill(int *pnfds,
fd_set *readfds, fd_set *writefds, fd_set *xfds)
{
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 3df53ca74b..65d9af6ac7 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -27,6 +27,8 @@
#include "qemu-option.h"
#include "qemu-config.h"
+#include "qapi/qapi-visit-core.h"
+
#include "hyperv.h"
/* feature flags taken from "Intel Processor Identification and the CPUID
@@ -597,36 +599,252 @@ static int check_features_against_host(x86_def_t *guest_def)
return rv;
}
-static void x86_cpuid_version_set_family(CPUX86State *env, int family)
+static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ int64_t value;
+
+ value = (env->cpuid_version >> 8) & 0xf;
+ if (value == 0xf) {
+ value += (env->cpuid_version >> 20) & 0xff;
+ }
+ visit_type_int(v, &value, name, errp);
+}
+
+static void x86_cpuid_version_set_family(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ const int64_t min = 0;
+ const int64_t max = 0xff + 0xf;
+ int64_t value;
+
+ visit_type_int(v, &value, name, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+ if (value < min || value > max) {
+ error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
+ name ? name : "null", value, min, max);
+ return;
+ }
+
env->cpuid_version &= ~0xff00f00;
- if (family > 0x0f) {
- env->cpuid_version |= 0xf00 | ((family - 0x0f) << 20);
+ if (value > 0x0f) {
+ env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
} else {
- env->cpuid_version |= family << 8;
+ env->cpuid_version |= value << 8;
}
}
-static void x86_cpuid_version_set_model(CPUX86State *env, int model)
+static void x86_cpuid_version_get_model(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ int64_t value;
+
+ value = (env->cpuid_version >> 4) & 0xf;
+ value |= ((env->cpuid_version >> 16) & 0xf) << 4;
+ visit_type_int(v, &value, name, errp);
+}
+
+static void x86_cpuid_version_set_model(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ const int64_t min = 0;
+ const int64_t max = 0xff;
+ int64_t value;
+
+ visit_type_int(v, &value, name, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+ if (value < min || value > max) {
+ error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
+ name ? name : "null", value, min, max);
+ return;
+ }
+
env->cpuid_version &= ~0xf00f0;
- env->cpuid_version |= ((model & 0xf) << 4) | ((model >> 4) << 16);
+ env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
}
-static void x86_cpuid_version_set_stepping(CPUX86State *env, int stepping)
+static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
+ void *opaque, const char *name,
+ Error **errp)
{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ int64_t value;
+
+ value = env->cpuid_version & 0xf;
+ visit_type_int(v, &value, name, errp);
+}
+
+static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
+ void *opaque, const char *name,
+ Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ const int64_t min = 0;
+ const int64_t max = 0xf;
+ int64_t value;
+
+ visit_type_int(v, &value, name, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+ if (value < min || value > max) {
+ error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
+ name ? name : "null", value, min, max);
+ return;
+ }
+
env->cpuid_version &= ~0xf;
- env->cpuid_version |= stepping & 0xf;
+ env->cpuid_version |= value & 0xf;
}
-static void x86_cpuid_set_model_id(CPUX86State *env, const char *model_id)
+static void x86_cpuid_get_level(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
+ X86CPU *cpu = X86_CPU(obj);
+ int64_t value;
+
+ value = cpu->env.cpuid_level;
+ /* TODO Use visit_type_uint32() once available */
+ visit_type_int(v, &value, name, errp);
+}
+
+static void x86_cpuid_set_level(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ const int64_t min = 0;
+ const int64_t max = UINT32_MAX;
+ int64_t value;
+
+ /* TODO Use visit_type_uint32() once available */
+ visit_type_int(v, &value, name, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+ if (value < min || value > max) {
+ error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
+ name ? name : "null", value, min, max);
+ return;
+ }
+
+ cpu->env.cpuid_level = value;
+}
+
+static void x86_cpuid_get_xlevel(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ int64_t value;
+
+ value = cpu->env.cpuid_xlevel;
+ /* TODO Use visit_type_uint32() once available */
+ visit_type_int(v, &value, name, errp);
+}
+
+static void x86_cpuid_set_xlevel(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ const int64_t min = 0;
+ const int64_t max = UINT32_MAX;
+ int64_t value;
+
+ /* TODO Use visit_type_uint32() once available */
+ visit_type_int(v, &value, name, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+ if (value < min || value > max) {
+ error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
+ name ? name : "null", value, min, max);
+ return;
+ }
+
+ cpu->env.cpuid_xlevel = value;
+}
+
+static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ char *value;
+ int i;
+
+ value = (char *)g_malloc(12 + 1);
+ for (i = 0; i < 4; i++) {
+ value[i ] = env->cpuid_vendor1 >> (8 * i);
+ value[i + 4] = env->cpuid_vendor2 >> (8 * i);
+ value[i + 8] = env->cpuid_vendor3 >> (8 * i);
+ }
+ value[12] = '\0';
+ return value;
+}
+
+static void x86_cpuid_set_vendor(Object *obj, const char *value,
+ Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ int i;
+
+ if (strlen(value) != 12) {
+ error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
+ "vendor", value);
+ return;
+ }
+
+ env->cpuid_vendor1 = 0;
+ env->cpuid_vendor2 = 0;
+ env->cpuid_vendor3 = 0;
+ for (i = 0; i < 4; i++) {
+ env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
+ env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
+ env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
+ }
+ env->cpuid_vendor_override = 1;
+}
+
+static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ char *value;
+ int i;
+
+ value = g_malloc(48 + 1);
+ for (i = 0; i < 48; i++) {
+ value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
+ }
+ value[48] = '\0';
+ return value;
+}
+
+static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
+ Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
int c, len, i;
if (model_id == NULL) {
model_id = "";
}
len = strlen(model_id);
+ memset(env->cpuid_model, 0, 48);
for (i = 0; i < 48; i++) {
if (i >= len) {
c = '\0';
@@ -637,6 +855,37 @@ static void x86_cpuid_set_model_id(CPUX86State *env, const char *model_id)
}
}
+static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ int64_t value;
+
+ value = cpu->env.tsc_khz * 1000;
+ visit_type_int(v, &value, name, errp);
+}
+
+static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ const int64_t min = 0;
+ const int64_t max = INT_MAX;
+ int64_t value;
+
+ visit_type_int(v, &value, name, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+ if (value < min || value > max) {
+ error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
+ name ? name : "null", value, min, max);
+ return;
+ }
+
+ cpu->env.tsc_khz = value / 1000;
+}
+
static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
{
unsigned int i;
@@ -690,7 +939,7 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
if (!strcmp(featurestr, "family")) {
char *err;
numvalue = strtoul(val, &err, 0);
- if (!*val || *err) {
+ if (!*val || *err || numvalue > 0xff + 0xf) {
fprintf(stderr, "bad numerical value %s\n", val);
goto error;
}
@@ -904,9 +1153,11 @@ void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
}
}
-int cpu_x86_register (CPUX86State *env, const char *cpu_model)
+int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
{
+ CPUX86State *env = &cpu->env;
x86_def_t def1, *def = &def1;
+ Error *error = NULL;
memset(def, 0, sizeof(*def));
@@ -922,20 +1173,21 @@ int cpu_x86_register (CPUX86State *env, const char *cpu_model)
env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
}
env->cpuid_vendor_override = def->vendor_override;
- env->cpuid_level = def->level;
- x86_cpuid_version_set_family(env, def->family);
- x86_cpuid_version_set_model(env, def->model);
- x86_cpuid_version_set_stepping(env, def->stepping);
+ object_property_set_int(OBJECT(cpu), def->level, "level", &error);
+ object_property_set_int(OBJECT(cpu), def->family, "family", &error);
+ object_property_set_int(OBJECT(cpu), def->model, "model", &error);
+ object_property_set_int(OBJECT(cpu), def->stepping, "stepping", &error);
env->cpuid_features = def->features;
env->cpuid_ext_features = def->ext_features;
env->cpuid_ext2_features = def->ext2_features;
env->cpuid_ext3_features = def->ext3_features;
- env->cpuid_xlevel = def->xlevel;
+ object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", &error);
env->cpuid_kvm_features = def->kvm_features;
env->cpuid_svm_features = def->svm_features;
env->cpuid_ext4_features = def->ext4_features;
env->cpuid_xlevel2 = def->xlevel2;
- env->tsc_khz = def->tsc_khz;
+ object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000,
+ "tsc-frequency", &error);
if (!kvm_enabled()) {
env->cpuid_features &= TCG_FEATURES;
env->cpuid_ext_features &= TCG_EXT_FEATURES;
@@ -947,7 +1199,11 @@ int cpu_x86_register (CPUX86State *env, const char *cpu_model)
env->cpuid_ext3_features &= TCG_EXT3_FEATURES;
env->cpuid_svm_features &= TCG_SVM_FEATURES;
}
- x86_cpuid_set_model_id(env, def->model_id);
+ object_property_set_str(OBJECT(cpu), def->model_id, "model-id", &error);
+ if (error_is_set(&error)) {
+ error_free(error);
+ return -1;
+ }
return 0;
}
@@ -1472,6 +1728,32 @@ static void x86_cpu_initfn(Object *obj)
CPUX86State *env = &cpu->env;
cpu_exec_init(env);
+
+ object_property_add(obj, "family", "int",
+ x86_cpuid_version_get_family,
+ x86_cpuid_version_set_family, NULL, NULL, NULL);
+ object_property_add(obj, "model", "int",
+ x86_cpuid_version_get_model,
+ x86_cpuid_version_set_model, NULL, NULL, NULL);
+ object_property_add(obj, "stepping", "int",
+ x86_cpuid_version_get_stepping,
+ x86_cpuid_version_set_stepping, NULL, NULL, NULL);
+ object_property_add(obj, "level", "int",
+ x86_cpuid_get_level,
+ x86_cpuid_set_level, NULL, NULL, NULL);
+ object_property_add(obj, "xlevel", "int",
+ x86_cpuid_get_xlevel,
+ x86_cpuid_set_xlevel, NULL, NULL, NULL);
+ object_property_add_str(obj, "vendor",
+ x86_cpuid_get_vendor,
+ x86_cpuid_set_vendor, NULL);
+ object_property_add_str(obj, "model-id",
+ x86_cpuid_get_model_id,
+ x86_cpuid_set_model_id, NULL);
+ object_property_add(obj, "tsc-frequency", "int",
+ x86_cpuid_get_tsc_freq,
+ x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
+
env->cpuid_apic_id = env->cpu_index;
mce_init(cpu);
}
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 4bb4592db5..b5b9a50695 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -901,7 +901,7 @@ int cpu_x86_signal_handler(int host_signum, void *pinfo,
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx);
-int cpu_x86_register (CPUX86State *env, const char *cpu_model);
+int cpu_x86_register(X86CPU *cpu, const char *cpu_model);
void cpu_clear_apic_feature(CPUX86State *env);
void host_cpuid(uint32_t function, uint32_t count,
uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 87954f0919..0b22582ed6 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1176,7 +1176,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
cpu_set_debug_excp_handler(breakpoint_handler);
#endif
}
- if (cpu_x86_register(env, cpu_model) < 0) {
+ if (cpu_x86_register(cpu, cpu_model) < 0) {
object_delete(OBJECT(cpu));
return NULL;
}
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 1ce6fa10df..295c6d49d0 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -26,6 +26,7 @@
#include <unistd.h>
#include <string.h>
+#include "compiler.h"
#include "osdep.h"
#define MAX_IRQ 256
@@ -130,7 +131,7 @@ void qtest_quit(QTestState *s)
}
}
-static void qtest_sendf(QTestState *s, const char *fmt, ...)
+static void GCC_FMT_ATTR(2, 3) qtest_sendf(QTestState *s, const char *fmt, ...)
{
va_list ap;
gchar *str;
@@ -356,7 +357,7 @@ void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size)
gchar **args;
size_t i;
- qtest_sendf(s, "read 0x%" PRIx64 " 0x%x\n", addr, size);
+ qtest_sendf(s, "read 0x%" PRIx64 " 0x%zx\n", addr, size);
args = qtest_rsp(s, 2);
for (i = 0; i < size; i++) {
@@ -378,7 +379,7 @@ void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size)
const uint8_t *ptr = data;
size_t i;
- qtest_sendf(s, "write 0x%" PRIx64 " 0x%x 0x", addr, size);
+ qtest_sendf(s, "write 0x%" PRIx64 " 0x%zx 0x", addr, size);
for (i = 0; i < size; i++) {
qtest_sendf(s, "%02x", ptr[i]);
}