summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--block/raw-posix.c26
-rw-r--r--exec.c8
-rw-r--r--hmp-commands.hx3
-rw-r--r--hmp.c36
-rw-r--r--hmp.h36
-rw-r--r--hw/fw_cfg.c86
-rw-r--r--hw/fw_cfg.h17
-rw-r--r--hw/i8259.c4
-rw-r--r--hw/lm32_pic.c4
-rw-r--r--hw/lm32_pic.h4
-rw-r--r--hw/loader.c2
-rw-r--r--hw/loader.h3
-rw-r--r--hw/openpic.c40
-rw-r--r--hw/pc.c21
-rw-r--r--hw/pc.h4
-rw-r--r--hw/pcmcia.h2
-rw-r--r--hw/ppc.c17
-rw-r--r--hw/ppc.h2
-rw-r--r--hw/ppc/e500.c17
-rw-r--r--hw/qdev-core.h14
-rw-r--r--hw/qdev-monitor.c4
-rw-r--r--hw/qdev-monitor.h4
-rw-r--r--hw/s390-virtio.c194
-rw-r--r--hw/s390-virtio.h22
-rw-r--r--hw/s390x/Makefile.objs2
-rw-r--r--hw/s390x/ipl.c174
-rw-r--r--hw/s390x/s390-virtio-hcall.c36
-rw-r--r--hw/sun4m.c16
-rw-r--r--hw/sun4m.h4
-rw-r--r--hw/sun4u.c4
-rw-r--r--hw/usb.h2
-rw-r--r--hw/usb/bus.c2
-rw-r--r--hw/usb/host-bsd.c2
-rw-r--r--hw/usb/host-linux.c2
-rw-r--r--hw/usb/host-stub.c2
-rw-r--r--hw/virtio-pci.c6
-rw-r--r--include/exec/cpu-defs.h2
-rw-r--r--include/exec/exec-all.h8
-rw-r--r--include/net/net.h2
-rw-r--r--include/net/slirp.h2
-rw-r--r--include/qemu/bswap.h20
-rw-r--r--include/qom/object.h104
-rw-r--r--include/sysemu/sysemu.h6
-rw-r--r--linux-headers/asm-powerpc/kvm.h6
-rw-r--r--linux-headers/linux/kvm.h27
-rw-r--r--linux-user/syscall.c40
-rw-r--r--linux-user/syscall_defs.h18
-rw-r--r--monitor.c200
-rw-r--r--net/net.c2
-rw-r--r--net/slirp.c2
-rw-r--r--qga/commands-posix.c13
-rw-r--r--savevm.c2
-rw-r--r--target-ppc/kvm.c21
-rw-r--r--target-ppc/kvm_ppc.h5
-rw-r--r--target-ppc/translate_init.c4
-rw-r--r--target-s390x/cpu.c71
-rw-r--r--target-s390x/cpu.h91
-rw-r--r--target-s390x/kvm.c17
-rw-r--r--target-s390x/misc_helper.c83
-rw-r--r--tcg/arm/tcg-target.c4
-rw-r--r--tcg/optimize.c177
-rw-r--r--trace-events7
-rw-r--r--util/path.c5
-rw-r--r--vl.c8
65 files changed, 1174 insertions, 597 deletions
diff --git a/Makefile b/Makefile
index cfa2fa6383..73adf429d7 100644
--- a/Makefile
+++ b/Makefile
@@ -227,7 +227,7 @@ clean:
rm -rf qapi-generated
rm -rf qga/qapi-generated
$(MAKE) -C tests/tcg clean
- for d in $(ALL_SUBDIRS) libcacard; do \
+ for d in $(ALL_SUBDIRS); do \
if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
rm -f $$d/qemu-options.def; \
done
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 679fcc5113..657af95637 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1371,19 +1371,6 @@ static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
return thread_pool_submit_aio(aio_worker, acb, cb, opaque);
}
-static coroutine_fn BlockDriverAIOCB *hdev_aio_discard(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVRawState *s = bs->opaque;
-
- if (fd_open(bs) < 0) {
- return NULL;
- }
- return paio_submit(bs, s->fd, sector_num, NULL, nb_sectors,
- cb, opaque, QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV);
-}
-
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
static int fd_open(BlockDriverState *bs)
{
@@ -1403,6 +1390,19 @@ static int fd_open(BlockDriverState *bs)
#endif /* !linux && !FreeBSD */
+static coroutine_fn BlockDriverAIOCB *hdev_aio_discard(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors,
+ BlockDriverCompletionFunc *cb, void *opaque)
+{
+ BDRVRawState *s = bs->opaque;
+
+ if (fd_open(bs) < 0) {
+ return NULL;
+ }
+ return paio_submit(bs, s->fd, sector_num, NULL, nb_sectors,
+ cb, opaque, QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV);
+}
+
static int hdev_create(const char *filename, QEMUOptionParameter *options)
{
int fd;
diff --git a/exec.c b/exec.c
index 5689613d0a..b85508ba30 100644
--- a/exec.c
+++ b/exec.c
@@ -863,18 +863,16 @@ static void *file_ram_alloc(RAMBlock *block,
return NULL;
}
- if (asprintf(&filename, "%s/qemu_back_mem.XXXXXX", path) == -1) {
- return NULL;
- }
+ filename = g_strdup_printf("%s/qemu_back_mem.XXXXXX", path);
fd = mkstemp(filename);
if (fd < 0) {
perror("unable to create backing store for hugepages");
- free(filename);
+ g_free(filename);
return NULL;
}
unlink(filename);
- free(filename);
+ g_free(filename);
memory = (memory+hpagesize-1) & ~(hpagesize-1);
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 67569eff4a..0934b9b915 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1521,7 +1521,8 @@ ETEXI
.args_type = "item:s?",
.params = "[subcommand]",
.help = "show various information about the system state",
- .mhandler.cmd = do_info,
+ .mhandler.cmd = do_info_help,
+ .sub_table = info_cmds,
},
STEXI
diff --git a/hmp.c b/hmp.c
index 68929b4acf..c7b6ba02fc 100644
--- a/hmp.c
+++ b/hmp.c
@@ -31,7 +31,7 @@ static void hmp_handle_error(Monitor *mon, Error **errp)
}
}
-void hmp_info_name(Monitor *mon)
+void hmp_info_name(Monitor *mon, const QDict *qdict)
{
NameInfo *info;
@@ -42,7 +42,7 @@ void hmp_info_name(Monitor *mon)
qapi_free_NameInfo(info);
}
-void hmp_info_version(Monitor *mon)
+void hmp_info_version(Monitor *mon, const QDict *qdict)
{
VersionInfo *info;
@@ -55,7 +55,7 @@ void hmp_info_version(Monitor *mon)
qapi_free_VersionInfo(info);
}
-void hmp_info_kvm(Monitor *mon)
+void hmp_info_kvm(Monitor *mon, const QDict *qdict)
{
KvmInfo *info;
@@ -70,7 +70,7 @@ void hmp_info_kvm(Monitor *mon)
qapi_free_KvmInfo(info);
}
-void hmp_info_status(Monitor *mon)
+void hmp_info_status(Monitor *mon, const QDict *qdict)
{
StatusInfo *info;
@@ -89,7 +89,7 @@ void hmp_info_status(Monitor *mon)
qapi_free_StatusInfo(info);
}
-void hmp_info_uuid(Monitor *mon)
+void hmp_info_uuid(Monitor *mon, const QDict *qdict)
{
UuidInfo *info;
@@ -98,7 +98,7 @@ void hmp_info_uuid(Monitor *mon)
qapi_free_UuidInfo(info);
}
-void hmp_info_chardev(Monitor *mon)
+void hmp_info_chardev(Monitor *mon, const QDict *qdict)
{
ChardevInfoList *char_info, *info;
@@ -111,7 +111,7 @@ void hmp_info_chardev(Monitor *mon)
qapi_free_ChardevInfoList(char_info);
}
-void hmp_info_mice(Monitor *mon)
+void hmp_info_mice(Monitor *mon, const QDict *qdict)
{
MouseInfoList *mice_list, *mouse;
@@ -131,7 +131,7 @@ void hmp_info_mice(Monitor *mon)
qapi_free_MouseInfoList(mice_list);
}
-void hmp_info_migrate(Monitor *mon)
+void hmp_info_migrate(Monitor *mon, const QDict *qdict)
{
MigrationInfo *info;
MigrationCapabilityStatusList *caps, *cap;
@@ -209,7 +209,7 @@ void hmp_info_migrate(Monitor *mon)
qapi_free_MigrationCapabilityStatusList(caps);
}
-void hmp_info_migrate_capabilities(Monitor *mon)
+void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict)
{
MigrationCapabilityStatusList *caps, *cap;
@@ -228,13 +228,13 @@ void hmp_info_migrate_capabilities(Monitor *mon)
qapi_free_MigrationCapabilityStatusList(caps);
}
-void hmp_info_migrate_cache_size(Monitor *mon)
+void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict)
{
monitor_printf(mon, "xbzrel cache size: %" PRId64 " kbytes\n",
qmp_query_migrate_cache_size(NULL) >> 10);
}
-void hmp_info_cpus(Monitor *mon)
+void hmp_info_cpus(Monitor *mon, const QDict *qdict)
{
CpuInfoList *cpu_list, *cpu;
@@ -272,7 +272,7 @@ void hmp_info_cpus(Monitor *mon)
qapi_free_CpuInfoList(cpu_list);
}
-void hmp_info_block(Monitor *mon)
+void hmp_info_block(Monitor *mon, const QDict *qdict)
{
BlockInfoList *block_list, *info;
@@ -326,7 +326,7 @@ void hmp_info_block(Monitor *mon)
qapi_free_BlockInfoList(block_list);
}
-void hmp_info_blockstats(Monitor *mon)
+void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
{
BlockStatsList *stats_list, *stats;
@@ -360,7 +360,7 @@ void hmp_info_blockstats(Monitor *mon)
qapi_free_BlockStatsList(stats_list);
}
-void hmp_info_vnc(Monitor *mon)
+void hmp_info_vnc(Monitor *mon, const QDict *qdict)
{
VncInfo *info;
Error *err = NULL;
@@ -406,7 +406,7 @@ out:
qapi_free_VncInfo(info);
}
-void hmp_info_spice(Monitor *mon)
+void hmp_info_spice(Monitor *mon, const QDict *qdict)
{
SpiceChannelList *chan;
SpiceInfo *info;
@@ -453,7 +453,7 @@ out:
qapi_free_SpiceInfo(info);
}
-void hmp_info_balloon(Monitor *mon)
+void hmp_info_balloon(Monitor *mon, const QDict *qdict)
{
BalloonInfo *info;
Error *err = NULL;
@@ -570,7 +570,7 @@ static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
}
}
-void hmp_info_pci(Monitor *mon)
+void hmp_info_pci(Monitor *mon, const QDict *qdict)
{
PciInfoList *info_list, *info;
Error *err = NULL;
@@ -593,7 +593,7 @@ void hmp_info_pci(Monitor *mon)
qapi_free_PciInfoList(info_list);
}
-void hmp_info_block_jobs(Monitor *mon)
+void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
{
BlockJobInfoList *list;
Error *err = NULL;
diff --git a/hmp.h b/hmp.h
index 700fbdc777..44be683fcc 100644
--- a/hmp.h
+++ b/hmp.h
@@ -18,24 +18,24 @@
#include "qapi-types.h"
#include "qapi/qmp/qdict.h"
-void hmp_info_name(Monitor *mon);
-void hmp_info_version(Monitor *mon);
-void hmp_info_kvm(Monitor *mon);
-void hmp_info_status(Monitor *mon);
-void hmp_info_uuid(Monitor *mon);
-void hmp_info_chardev(Monitor *mon);
-void hmp_info_mice(Monitor *mon);
-void hmp_info_migrate(Monitor *mon);
-void hmp_info_migrate_capabilities(Monitor *mon);
-void hmp_info_migrate_cache_size(Monitor *mon);
-void hmp_info_cpus(Monitor *mon);
-void hmp_info_block(Monitor *mon);
-void hmp_info_blockstats(Monitor *mon);
-void hmp_info_vnc(Monitor *mon);
-void hmp_info_spice(Monitor *mon);
-void hmp_info_balloon(Monitor *mon);
-void hmp_info_pci(Monitor *mon);
-void hmp_info_block_jobs(Monitor *mon);
+void hmp_info_name(Monitor *mon, const QDict *qdict);
+void hmp_info_version(Monitor *mon, const QDict *qdict);
+void hmp_info_kvm(Monitor *mon, const QDict *qdict);
+void hmp_info_status(Monitor *mon, const QDict *qdict);
+void hmp_info_uuid(Monitor *mon, const QDict *qdict);
+void hmp_info_chardev(Monitor *mon, const QDict *qdict);
+void hmp_info_mice(Monitor *mon, const QDict *qdict);
+void hmp_info_migrate(Monitor *mon, const QDict *qdict);
+void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict);
+void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict);
+void hmp_info_cpus(Monitor *mon, const QDict *qdict);
+void hmp_info_block(Monitor *mon, const QDict *qdict);
+void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
+void hmp_info_vnc(Monitor *mon, const QDict *qdict);
+void hmp_info_spice(Monitor *mon, const QDict *qdict);
+void hmp_info_balloon(Monitor *mon, const QDict *qdict);
+void hmp_info_pci(Monitor *mon, const QDict *qdict);
+void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
void hmp_quit(Monitor *mon, const QDict *qdict);
void hmp_stop(Monitor *mon, const QDict *qdict);
void hmp_system_reset(Monitor *mon, const QDict *qdict);
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 7c9480c4d7..3b31d77f3f 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -26,19 +26,10 @@
#include "isa.h"
#include "fw_cfg.h"
#include "sysbus.h"
+#include "trace.h"
#include "qemu/error-report.h"
#include "qemu/config-file.h"
-/* debug firmware config */
-//#define DEBUG_FW_CFG
-
-#ifdef DEBUG_FW_CFG
-#define FW_CFG_DPRINTF(fmt, ...) \
- do { printf("FW_CFG: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define FW_CFG_DPRINTF(fmt, ...)
-#endif
-
#define FW_CFG_SIZE 2
#define FW_CFG_DATA_SIZE 1
@@ -213,7 +204,7 @@ static void fw_cfg_write(FWCfgState *s, uint8_t value)
int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL);
FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
- FW_CFG_DPRINTF("write %d\n", value);
+ trace_fw_cfg_write(s, value);
if (s->cur_entry & FW_CFG_WRITE_CHANNEL && e->callback &&
s->cur_offset < e->len) {
@@ -238,8 +229,7 @@ static int fw_cfg_select(FWCfgState *s, uint16_t key)
ret = 1;
}
- FW_CFG_DPRINTF("select key %d (%sfound)\n", key, ret ? "" : "not ");
-
+ trace_fw_cfg_select(s, key, ret);
return ret;
}
@@ -254,8 +244,7 @@ static uint8_t fw_cfg_read(FWCfgState *s)
else
ret = e->data[s->cur_offset++];
- FW_CFG_DPRINTF("read %d\n", ret);
-
+ trace_fw_cfg_read(s, ret);
return ret;
}
@@ -384,85 +373,83 @@ static const VMStateDescription vmstate_fw_cfg = {
}
};
-int fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len)
+void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len)
{
int arch = !!(key & FW_CFG_ARCH_LOCAL);
key &= FW_CFG_ENTRY_MASK;
- if (key >= FW_CFG_MAX_ENTRY)
- return 0;
+ assert(key < FW_CFG_MAX_ENTRY && len < UINT32_MAX);
s->entries[arch][key].data = data;
- s->entries[arch][key].len = len;
+ s->entries[arch][key].len = (uint32_t)len;
+}
- return 1;
+void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value)
+{
+ size_t sz = strlen(value) + 1;
+
+ return fw_cfg_add_bytes(s, key, g_memdup(value, sz), sz);
}
-int fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value)
+void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value)
{
uint16_t *copy;
copy = g_malloc(sizeof(value));
*copy = cpu_to_le16(value);
- return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
+ fw_cfg_add_bytes(s, key, copy, sizeof(value));
}
-int fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value)
+void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value)
{
uint32_t *copy;
copy = g_malloc(sizeof(value));
*copy = cpu_to_le32(value);
- return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
+ fw_cfg_add_bytes(s, key, copy, sizeof(value));
}
-int fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)
+void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)
{
uint64_t *copy;
copy = g_malloc(sizeof(value));
*copy = cpu_to_le64(value);
- return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
+ fw_cfg_add_bytes(s, key, copy, sizeof(value));
}
-int fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
- void *callback_opaque, uint8_t *data, size_t len)
+void fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
+ void *callback_opaque, void *data, size_t len)
{
int arch = !!(key & FW_CFG_ARCH_LOCAL);
- if (!(key & FW_CFG_WRITE_CHANNEL))
- return 0;
+ assert(key & FW_CFG_WRITE_CHANNEL);
key &= FW_CFG_ENTRY_MASK;
- if (key >= FW_CFG_MAX_ENTRY || len > 65535)
- return 0;
+ assert(key < FW_CFG_MAX_ENTRY && len <= UINT32_MAX);
s->entries[arch][key].data = data;
- s->entries[arch][key].len = len;
+ s->entries[arch][key].len = (uint32_t)len;
s->entries[arch][key].callback_opaque = callback_opaque;
s->entries[arch][key].callback = callback;
-
- return 1;
}
-int fw_cfg_add_file(FWCfgState *s, const char *filename, uint8_t *data,
- uint32_t len)
+void fw_cfg_add_file(FWCfgState *s, const char *filename,
+ void *data, size_t len)
{
int i, index;
+ size_t dsize;
if (!s->files) {
- int dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS;
+ dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS;
s->files = g_malloc0(dsize);
- fw_cfg_add_bytes(s, FW_CFG_FILE_DIR, (uint8_t*)s->files, dsize);
+ fw_cfg_add_bytes(s, FW_CFG_FILE_DIR, s->files, dsize);
}
index = be32_to_cpu(s->files->count);
- if (index == FW_CFG_FILE_SLOTS) {
- fprintf(stderr, "fw_cfg: out of file slots\n");
- return 0;
- }
+ assert(index < FW_CFG_FILE_SLOTS);
fw_cfg_add_bytes(s, FW_CFG_FILE_FIRST + index, data, len);
@@ -470,24 +457,21 @@ int fw_cfg_add_file(FWCfgState *s, const char *filename, uint8_t *data,
filename);
for (i = 0; i < index; i++) {
if (strcmp(s->files->f[index].name, s->files->f[i].name) == 0) {
- FW_CFG_DPRINTF("%s: skip duplicate: %s\n", __FUNCTION__,
- s->files->f[index].name);
- return 1;
+ trace_fw_cfg_add_file_dupe(s, s->files->f[index].name);
+ return;
}
}
s->files->f[index].size = cpu_to_be32(len);
s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index);
- FW_CFG_DPRINTF("%s: #%d: %s (%d bytes)\n", __FUNCTION__,
- index, s->files->f[index].name, len);
+ trace_fw_cfg_add_file(s, index, s->files->f[index].name, len);
s->files->count = cpu_to_be32(index+1);
- return 1;
}
static void fw_cfg_machine_ready(struct Notifier *n, void *data)
{
- uint32_t len;
+ size_t len;
FWCfgState *s = container_of(n, FWCfgState, machine_ready);
char *bootindex = get_boot_devices_list(&len);
@@ -515,7 +499,7 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
if (data_addr) {
sysbus_mmio_map(d, 1, data_addr);
}
- fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (uint8_t *)"QEMU", 4);
+ fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (char *)"QEMU", 4);
fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16);
fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)(display_type == DT_NOGRAPHIC));
fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
diff --git a/hw/fw_cfg.h b/hw/fw_cfg.h
index 619a39432a..05c8df186f 100644
--- a/hw/fw_cfg.h
+++ b/hw/fw_cfg.h
@@ -54,14 +54,15 @@ typedef struct FWCfgFiles {
typedef void (*FWCfgCallback)(void *opaque, uint8_t *data);
typedef struct FWCfgState FWCfgState;
-int fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len);
-int fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value);
-int fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value);
-int fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value);
-int fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
- void *callback_opaque, uint8_t *data, size_t len);
-int fw_cfg_add_file(FWCfgState *s, const char *filename, uint8_t *data,
- uint32_t len);
+void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len);
+void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value);
+void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value);
+void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value);
+void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value);
+void fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
+ void *callback_opaque, void *data, size_t len);
+void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
+ size_t len);
FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
hwaddr crl_addr, hwaddr data_addr);
diff --git a/hw/i8259.c b/hw/i8259.c
index 264879e097..54fe14447b 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -407,7 +407,7 @@ static void pic_init(PICCommonState *s)
qdev_init_gpio_in(&s->dev.qdev, pic_set_irq, 8);
}
-void pic_info(Monitor *mon)
+void pic_info(Monitor *mon, const QDict *qdict)
{
int i;
PICCommonState *s;
@@ -425,7 +425,7 @@ void pic_info(Monitor *mon)
}
}
-void irq_info(Monitor *mon)
+void irq_info(Monitor *mon, const QDict *qdict)
{
#ifndef DEBUG_IRQ_COUNT
monitor_printf(mon, "irq statistic code not compiled.\n");
diff --git a/hw/lm32_pic.c b/hw/lm32_pic.c
index 8f13355821..42f298ad51 100644
--- a/hw/lm32_pic.c
+++ b/hw/lm32_pic.c
@@ -39,7 +39,7 @@ struct LM32PicState {
typedef struct LM32PicState LM32PicState;
static LM32PicState *pic;
-void lm32_do_pic_info(Monitor *mon)
+void lm32_do_pic_info(Monitor *mon, const QDict *qdict)
{
if (pic == NULL) {
return;
@@ -49,7 +49,7 @@ void lm32_do_pic_info(Monitor *mon)
pic->im, pic->ip, pic->irq_state);
}
-void lm32_irq_info(Monitor *mon)
+void lm32_irq_info(Monitor *mon, const QDict *qdict)
{
int i;
uint32_t count;
diff --git a/hw/lm32_pic.h b/hw/lm32_pic.h
index 14456f37cb..555680304e 100644
--- a/hw/lm32_pic.h
+++ b/hw/lm32_pic.h
@@ -8,7 +8,7 @@ uint32_t lm32_pic_get_im(DeviceState *d);
void lm32_pic_set_ip(DeviceState *d, uint32_t ip);
void lm32_pic_set_im(DeviceState *d, uint32_t im);
-void lm32_do_pic_info(Monitor *mon);
-void lm32_irq_info(Monitor *mon);
+void lm32_do_pic_info(Monitor *mon, const QDict *qdict);
+void lm32_irq_info(Monitor *mon, const QDict *qdict);
#endif /* QEMU_HW_LM32_PIC_H */
diff --git a/hw/loader.c b/hw/loader.c
index 3f59fcd14a..995edc3f98 100644
--- a/hw/loader.c
+++ b/hw/loader.c
@@ -778,7 +778,7 @@ void *rom_ptr(hwaddr addr)
return rom->data + (addr - rom->addr);
}
-void do_info_roms(Monitor *mon)
+void do_info_roms(Monitor *mon, const QDict *qdict)
{
Rom *rom;
diff --git a/hw/loader.h b/hw/loader.h
index 26480ad8dd..5e61c95b84 100644
--- a/hw/loader.h
+++ b/hw/loader.h
@@ -1,5 +1,6 @@
#ifndef LOADER_H
#define LOADER_H
+#include "qapi/qmp/qdict.h"
/* loader.c */
int get_image_size(const char *filename);
@@ -30,7 +31,7 @@ int rom_load_all(void);
void rom_set_fw(void *f);
int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
void *rom_ptr(hwaddr addr);
-void do_info_roms(Monitor *mon);
+void do_info_roms(Monitor *mon, const QDict *qdict);
#define rom_add_file_fixed(_f, _a, _i) \
rom_add_file(_f, NULL, _a, _i)
diff --git a/hw/openpic.c b/hw/openpic.c
index f6cc07bd6e..cc8ec35b5d 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -40,6 +40,7 @@
#include "sysbus.h"
#include "pci/msi.h"
#include "qemu/bitops.h"
+#include "ppc.h"
//#define DEBUG_OPENPIC
@@ -644,6 +645,26 @@ static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val)
opp->src[n_IRQ].ivpr);
}
+static void openpic_gcr_write(OpenPICState *opp, uint64_t val)
+{
+ bool mpic_proxy = false;
+
+ if (val & GCR_RESET) {
+ openpic_reset(&opp->busdev.qdev);
+ return;
+ }
+
+ opp->gcr &= ~opp->mpic_mode_mask;
+ opp->gcr |= val & opp->mpic_mode_mask;
+
+ /* Set external proxy mode */
+ if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) {
+ mpic_proxy = true;
+ }
+
+ ppce500_set_mpic_proxy(mpic_proxy);
+}
+
static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
unsigned len)
{
@@ -672,23 +693,7 @@ static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
case 0x1000: /* FRR */
break;
case 0x1020: /* GCR */
- if (val & GCR_RESET) {
- openpic_reset(&opp->busdev.qdev);
- } else if (opp->mpic_mode_mask) {
- CPUArchState *env;
- int mpic_proxy = 0;
-
- opp->gcr &= ~opp->mpic_mode_mask;
- opp->gcr |= val & opp->mpic_mode_mask;
-
- /* Set external proxy mode */
- if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) {
- mpic_proxy = 1;
- }
- for (env = first_cpu; env != NULL; env = env->next_cpu) {
- env->mpic_proxy = mpic_proxy;
- }
- }
+ openpic_gcr_write(opp, val);
break;
case 0x1080: /* VIR */
break;
@@ -1464,6 +1469,7 @@ static int openpic_init(SysBusDevice *dev)
opp->irq_ipi0 = RAVEN_IPI_IRQ;
opp->irq_tim0 = RAVEN_TMR_IRQ;
opp->brr1 = -1;
+ opp->mpic_mode_mask = GCR_MODE_MIXED;
list = list_le;
/* Don't map MSI region */
list[2].map = false;
diff --git a/hw/pc.c b/hw/pc.c
index ba1f19d7e8..8fc69dbe0a 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -563,24 +563,23 @@ static void *bochs_bios_init(void)
fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
- fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES, (uint8_t *)acpi_tables,
- acpi_tables_len);
+ fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES,
+ acpi_tables, acpi_tables_len);
fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, kvm_allows_irq0_override());
smbios_table = smbios_get_table(&smbios_len);
if (smbios_table)
fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
smbios_table, smbios_len);
- fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE, (uint8_t *)&e820_table,
- sizeof(struct e820_table));
+ fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE,
+ &e820_table, sizeof(e820_table));
- fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, (uint8_t *)&hpet_cfg,
- sizeof(struct hpet_fw_config));
+ fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, &hpet_cfg, sizeof(hpet_cfg));
/* allocate memory for the NUMA channel: one (64bit) word for the number
* of nodes, one word for each VCPU->node and one word for each node to
* hold the amount of memory.
*/
- numa_fw_cfg = g_malloc0((1 + max_cpus + nb_numa_nodes) * 8);
+ numa_fw_cfg = g_new0(uint64_t, 1 + max_cpus + nb_numa_nodes);
numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes);
for (i = 0; i < max_cpus; i++) {
for (j = 0; j < nb_numa_nodes; j++) {
@@ -593,8 +592,8 @@ static void *bochs_bios_init(void)
for (i = 0; i < nb_numa_nodes; i++) {
numa_fw_cfg[max_cpus + 1 + i] = cpu_to_le64(node_mem[i]);
}
- fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, (uint8_t *)numa_fw_cfg,
- (1 + max_cpus + nb_numa_nodes) * 8);
+ fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg,
+ (1 + max_cpus + nb_numa_nodes) * sizeof(*numa_fw_cfg));
return fw_cfg;
}
@@ -693,9 +692,7 @@ static void load_linux(void *fw_cfg,
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr);
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline)+1);
- fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
- (uint8_t*)strdup(kernel_cmdline),
- strlen(kernel_cmdline)+1);
+ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
if (protocol >= 0x202) {
stl_p(header+0x228, cmdline_addr);
diff --git a/hw/pc.h b/hw/pc.h
index 4134aa94e5..fbcf43d717 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -40,8 +40,8 @@ qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq);
qemu_irq *kvm_i8259_init(ISABus *bus);
int pic_read_irq(DeviceState *d);
int pic_get_output(DeviceState *d);
-void pic_info(Monitor *mon);
-void irq_info(Monitor *mon);
+void pic_info(Monitor *mon, const QDict *qdict);
+void irq_info(Monitor *mon, const QDict *qdict);
/* Global System Interrupts */
diff --git a/hw/pcmcia.h b/hw/pcmcia.h
index aac1d77cc7..f91669305e 100644
--- a/hw/pcmcia.h
+++ b/hw/pcmcia.h
@@ -14,7 +14,7 @@ typedef struct {
void pcmcia_socket_register(PCMCIASocket *socket);
void pcmcia_socket_unregister(PCMCIASocket *socket);
-void pcmcia_info(Monitor *mon);
+void pcmcia_info(Monitor *mon, const QDict *qdict);
struct PCMCIACardState {
void *state;
diff --git a/hw/ppc.c b/hw/ppc.c
index e473f9e962..c52e22f708 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -428,6 +428,23 @@ void ppce500_irq_init(CPUPPCState *env)
env->irq_inputs = (void **)qemu_allocate_irqs(&ppce500_set_irq,
cpu, PPCE500_INPUT_NB);
}
+
+/* Enable or Disable the E500 EPR capability */
+void ppce500_set_mpic_proxy(bool enabled)
+{
+ CPUPPCState *env;
+
+ for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ PowerPCCPU *cpu = ppc_env_get_cpu(env);
+ CPUState *cs = CPU(cpu);
+
+ env->mpic_proxy = enabled;
+ if (kvm_enabled()) {
+ kvmppc_set_mpic_proxy(POWERPC_CPU(cs), enabled);
+ }
+ }
+}
+
/*****************************************************************************/
/* PowerPC time base and decrementer emulation */
diff --git a/hw/ppc.h b/hw/ppc.h
index e73ae83b52..ee0cd16ee5 100644
--- a/hw/ppc.h
+++ b/hw/ppc.h
@@ -73,6 +73,8 @@ void ppc6xx_irq_init (CPUPPCState *env);
void ppc970_irq_init (CPUPPCState *env);
void ppcPOWER7_irq_init (CPUPPCState *env);
+void ppce500_set_mpic_proxy(bool enabled);
+
/* PPC machines for OpenBIOS */
enum {
ARCH_PREP = 0,
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 7b3e2e6723..c36821a99f 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -41,6 +41,7 @@
#define UIMAGE_LOAD_BASE 0
#define DTC_LOAD_PAD 0x1800000
#define DTC_PAD_MASK 0xFFFFF
+#define DTB_MAX_SIZE (8 * 1024 * 1024)
#define INITRD_LOAD_PAD 0x2000000
#define INITRD_PAD_MASK 0xFFFFFF
@@ -463,7 +464,8 @@ void ppce500_init(PPCE500Params *params)
target_long kernel_size=0;
target_ulong dt_base = 0;
target_ulong initrd_base = 0;
- target_long initrd_size=0;
+ target_long initrd_size = 0;
+ target_ulong cur_base = 0;
int i = 0, j, k;
unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
qemu_irq **irqs, *mpic;
@@ -626,12 +628,17 @@ void ppce500_init(PPCE500Params *params)
params->kernel_filename);
exit(1);
}
+
+ cur_base = loadaddr + kernel_size;
+
+ /* Reserve space for dtb */
+ dt_base = (cur_base + DTC_LOAD_PAD) & ~DTC_PAD_MASK;
+ cur_base += DTB_MAX_SIZE;
}
/* Load initrd. */
if (params->initrd_filename) {
- initrd_base = (loadaddr + kernel_size + INITRD_LOAD_PAD) &
- ~INITRD_PAD_MASK;
+ initrd_base = (cur_base + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK;
initrd_size = load_image_targphys(params->initrd_filename, initrd_base,
ram_size - initrd_base);
@@ -640,6 +647,8 @@ void ppce500_init(PPCE500Params *params)
params->initrd_filename);
exit(1);
}
+
+ cur_base = initrd_base + initrd_size;
}
/* If we're loading a kernel directly, we must load the device tree too. */
@@ -647,13 +656,13 @@ void ppce500_init(PPCE500Params *params)
struct boot_info *boot_info;
int dt_size;
- dt_base = (loadaddr + kernel_size + DTC_LOAD_PAD) & ~DTC_PAD_MASK;
dt_size = ppce500_load_device_tree(env, params, dt_base, initrd_base,
initrd_size);
if (dt_size < 0) {
fprintf(stderr, "couldn't load device tree\n");
exit(1);
}
+ assert(dt_size < DTB_MAX_SIZE);
boot_info = env->load_info;
boot_info->entry = entry;
diff --git a/hw/qdev-core.h b/hw/qdev-core.h
index 3d75ae2e3a..731aadd677 100644
--- a/hw/qdev-core.h
+++ b/hw/qdev-core.h
@@ -60,14 +60,20 @@ struct VMStateDescription;
* The @init callback is considered private to a particular bus implementation
* (immediate abstract child types of TYPE_DEVICE). Derived leaf types set an
* "init" callback on their parent class instead.
+ *
* Any type may override the @realize and/or @unrealize callbacks but needs
- * to call (and thus save) the parent type's implementation if so desired.
- * Usually this means storing the previous value of, e.g., @realized inside
- * the type's class structure and overwriting it with a function that first
- * invokes the stored callback, then performs any additional steps.
+ * to call the parent type's implementation if keeping their functionality
+ * is desired. Refer to QOM documentation for further discussion and examples.
+ *
+ * <note>
+ * <para>
* If a type derived directly from TYPE_DEVICE implements @realize, it does
* not need to implement @init and therefore does not need to store and call
* #DeviceClass' default @realize callback.
+ * For other types consult the documentation and implementation of the
+ * respective parent types.
+ * </para>
+ * </note>
*/
typedef struct DeviceClass {
/*< private >*/
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 93283ee57a..1db5ee0f18 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -564,13 +564,13 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent)
}
#undef qdev_printf
-void do_info_qtree(Monitor *mon)
+void do_info_qtree(Monitor *mon, const QDict *qdict)
{
if (sysbus_get_default())
qbus_print(mon, sysbus_get_default(), 0);
}
-void do_info_qdm(Monitor *mon)
+void do_info_qdm(Monitor *mon, const QDict *qdict)
{
object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, NULL);
}
diff --git a/hw/qdev-monitor.h b/hw/qdev-monitor.h
index fae1b1ec84..9ec485028e 100644
--- a/hw/qdev-monitor.h
+++ b/hw/qdev-monitor.h
@@ -6,8 +6,8 @@
/*** monitor commands ***/
-void do_info_qtree(Monitor *mon);
-void do_info_qdm(Monitor *mon);
+void do_info_qtree(Monitor *mon, const QDict *qdict);
+void do_info_qdm(Monitor *mon, const QDict *qdict);
int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
int qdev_device_help(QemuOpts *opts);
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 0e93cc3641..5edaabb7c4 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -2,6 +2,7 @@
* QEMU S390 virtio target
*
* Copyright (c) 2009 Alexander Graf <agraf@suse.de>
+ * Copyright IBM Corp 2012
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -13,7 +14,10 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public
+ * Contributions after 2012-10-29 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ *
+ * You should have received a copy of the GNU (Lesser) General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
@@ -25,7 +29,6 @@
#include "boards.h"
#include "monitor/monitor.h"
#include "loader.h"
-#include "elf.h"
#include "hw/virtio.h"
#include "hw/sysbus.h"
#include "sysemu/kvm.h"
@@ -33,6 +36,7 @@
#include "hw/s390-virtio-bus.h"
#include "hw/s390x/sclp.h"
+#include "hw/s390-virtio.h"
//#define DEBUG_S390
@@ -44,21 +48,6 @@
do { } while (0)
#endif
-#define KVM_S390_VIRTIO_NOTIFY 0
-#define KVM_S390_VIRTIO_RESET 1
-#define KVM_S390_VIRTIO_SET_STATUS 2
-
-#define KERN_IMAGE_START 0x010000UL
-#define KERN_PARM_AREA 0x010480UL
-#define INITRD_START 0x800000UL
-#define INITRD_PARM_START 0x010408UL
-#define INITRD_PARM_SIZE 0x010410UL
-#define PARMFILE_START 0x001000UL
-
-#define ZIPL_START 0x009000UL
-#define ZIPL_LOAD_ADDR 0x009000UL
-#define ZIPL_FILENAME "s390-zipl.rom"
-
#define MAX_BLK_DEVS 10
static VirtIOS390Bus *s390_bus;
@@ -73,56 +62,63 @@ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
return ipi_states[cpu_addr];
}
-int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t hypercall)
+static int s390_virtio_hcall_notify(const uint64_t *args)
{
+ uint64_t mem = args[0];
int r = 0, i;
- dprintf("KVM hypercall: %ld\n", hypercall);
- switch (hypercall) {
- case KVM_S390_VIRTIO_NOTIFY:
- if (mem > ram_size) {
- VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus,
- mem, &i);
- if (dev) {
- virtio_queue_notify(dev->vdev, i);
- } else {
- r = -EINVAL;
- }
- } else {
- /* Early printk */
- }
- break;
- case KVM_S390_VIRTIO_RESET:
- {
- VirtIOS390Device *dev;
-
- dev = s390_virtio_bus_find_mem(s390_bus, mem);
- virtio_reset(dev->vdev);
- stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0);
- s390_virtio_device_sync(dev);
- s390_virtio_reset_idx(dev);
- break;
- }
- case KVM_S390_VIRTIO_SET_STATUS:
- {
- VirtIOS390Device *dev;
-
- dev = s390_virtio_bus_find_mem(s390_bus, mem);
+ if (mem > ram_size) {
+ VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus, mem, &i);
if (dev) {
- s390_virtio_device_update_status(dev);
+ virtio_queue_notify(dev->vdev, i);
} else {
r = -EINVAL;
}
- break;
+ } else {
+ /* Early printk */
}
- default:
+ return r;
+}
+
+static int s390_virtio_hcall_reset(const uint64_t *args)
+{
+ uint64_t mem = args[0];
+ VirtIOS390Device *dev;
+
+ dev = s390_virtio_bus_find_mem(s390_bus, mem);
+ virtio_reset(dev->vdev);
+ stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0);
+ s390_virtio_device_sync(dev);
+ s390_virtio_reset_idx(dev);
+
+ return 0;
+}
+
+static int s390_virtio_hcall_set_status(const uint64_t *args)
+{
+ uint64_t mem = args[0];
+ int r = 0;
+ VirtIOS390Device *dev;
+
+ dev = s390_virtio_bus_find_mem(s390_bus, mem);
+ if (dev) {
+ s390_virtio_device_update_status(dev);
+ } else {
r = -EINVAL;
- break;
}
-
return r;
}
+static void s390_virtio_register_hcalls(void)
+{
+ s390_register_virtio_hypercall(KVM_S390_VIRTIO_NOTIFY,
+ s390_virtio_hcall_notify);
+ s390_register_virtio_hypercall(KVM_S390_VIRTIO_RESET,
+ s390_virtio_hcall_reset);
+ s390_register_virtio_hypercall(KVM_S390_VIRTIO_SET_STATUS,
+ s390_virtio_hcall_set_status);
+}
+
/*
* The number of running CPUs. On s390 a shutdown is the state of all CPUs
* being either stopped or disabled (for interrupts) waiting. We have to
@@ -156,15 +152,10 @@ static void s390_init(QEMUMachineInitArgs *args)
{
ram_addr_t my_ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
- const char *kernel_filename = args->kernel_filename;
- const char *kernel_cmdline = args->kernel_cmdline;
- const char *initrd_filename = args->initrd_filename;
CPUS390XState *env = NULL;
+ DeviceState *dev;
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);
- ram_addr_t kernel_size = 0;
- ram_addr_t initrd_offset;
- ram_addr_t initrd_size = 0;
int shift = 0;
uint8_t *storage_keys;
void *virtio_region;
@@ -185,6 +176,18 @@ static void s390_init(QEMUMachineInitArgs *args)
/* get a BUS */
s390_bus = s390_virtio_bus_init(&my_ram_size);
s390_sclp_init();
+ dev = qdev_create(NULL, "s390-ipl");
+ if (args->kernel_filename) {
+ qdev_prop_set_string(dev, "kernel", args->kernel_filename);
+ }
+ if (args->initrd_filename) {
+ qdev_prop_set_string(dev, "initrd", args->initrd_filename);
+ }
+ qdev_prop_set_string(dev, "cmdline", args->kernel_cmdline);
+ qdev_init_nofail(dev);
+
+ /* register hypercalls */
+ s390_virtio_register_hcalls();
/* allocate RAM */
memory_region_init_ram(ram, "s390.ram", my_ram_size);
@@ -225,76 +228,6 @@ static void s390_init(QEMUMachineInitArgs *args)
tmp_env->storage_keys = storage_keys;
}
- /* One CPU has to run */
- s390_add_running_cpu(env);
-
- if (kernel_filename) {
-
- kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, NULL,
- NULL, 1, ELF_MACHINE, 0);
- if (kernel_size == -1UL) {
- kernel_size = load_image_targphys(kernel_filename, 0, ram_size);
- }
- if (kernel_size == -1UL) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- kernel_filename);
- exit(1);
- }
- /*
- * we can not rely on the ELF entry point, since up to 3.2 this
- * value was 0x800 (the SALIPL loader) and it wont work. For
- * all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine.
- */
- env->psw.addr = KERN_IMAGE_START;
- env->psw.mask = 0x0000000180000000ULL;
- } else {
- ram_addr_t bios_size = 0;
- char *bios_filename;
-
- /* Load zipl bootloader */
- if (bios_name == NULL) {
- bios_name = ZIPL_FILENAME;
- }
-
- bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
- bios_size = load_image_targphys(bios_filename, ZIPL_LOAD_ADDR, 4096);
- g_free(bios_filename);
-
- if ((long)bios_size < 0) {
- hw_error("could not load bootloader '%s'\n", bios_name);
- }
-
- if (bios_size > 4096) {
- hw_error("stage1 bootloader is > 4k\n");
- }
-
- env->psw.addr = ZIPL_START;
- env->psw.mask = 0x0000000180000000ULL;
- }
-
- if (initrd_filename) {
- initrd_offset = INITRD_START;
- while (kernel_size + 0x100000 > initrd_offset) {
- initrd_offset += 0x100000;
- }
- initrd_size = load_image_targphys(initrd_filename, initrd_offset,
- ram_size - initrd_offset);
- if (initrd_size == -1UL) {
- fprintf(stderr, "qemu: could not load initrd '%s'\n",
- initrd_filename);
- exit(1);
- }
-
- /* we have to overwrite values in the kernel image, which are "rom" */
- stq_p(rom_ptr(INITRD_PARM_START), initrd_offset);
- stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size);
- }
-
- if (rom_ptr(KERN_PARM_AREA)) {
- /* we have to overwrite values in the kernel image, which are "rom" */
- memcpy(rom_ptr(KERN_PARM_AREA), kernel_cmdline,
- strlen(kernel_cmdline) + 1);
- }
/* Create VirtIO network adapters */
for(i = 0; i < nb_nics; i++) {
@@ -339,4 +272,3 @@ static void s390_machine_init(void)
}
machine_init(s390_machine_init);
-
diff --git a/hw/s390-virtio.h b/hw/s390-virtio.h
new file mode 100644
index 0000000000..25bb610fd8
--- /dev/null
+++ b/hw/s390-virtio.h
@@ -0,0 +1,22 @@
+/*
+ * Virtio interfaces for s390
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#ifndef HW_S390_VIRTIO_H
+#define HW_S390_VIRTIO_H 1
+
+#define KVM_S390_VIRTIO_NOTIFY 0
+#define KVM_S390_VIRTIO_RESET 1
+#define KVM_S390_VIRTIO_SET_STATUS 2
+
+typedef int (*s390_virtio_fn)(const uint64_t *args);
+void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn);
+
+#endif
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 096dfcd6a1..1b40c2e66e 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -1,6 +1,8 @@
obj-y = s390-virtio-bus.o s390-virtio.o
obj-y := $(addprefix ../,$(obj-y))
+obj-y += s390-virtio-hcall.o
obj-y += sclp.o
obj-y += event-facility.o
obj-y += sclpquiesce.o sclpconsole.o
+obj-y += ipl.o
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
new file mode 100644
index 0000000000..7cbbf99fde
--- /dev/null
+++ b/hw/s390x/ipl.c
@@ -0,0 +1,174 @@
+/*
+ * bootloader support
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ * Christian Borntraeger <borntraeger@de.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at your
+ * option) any later version. See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "sysemu/sysemu.h"
+#include "cpu.h"
+#include "elf.h"
+#include "hw/loader.h"
+#include "hw/sysbus.h"
+
+#define KERN_IMAGE_START 0x010000UL
+#define KERN_PARM_AREA 0x010480UL
+#define INITRD_START 0x800000UL
+#define INITRD_PARM_START 0x010408UL
+#define INITRD_PARM_SIZE 0x010410UL
+#define PARMFILE_START 0x001000UL
+#define ZIPL_FILENAME "s390-zipl.rom"
+#define ZIPL_IMAGE_START 0x009000UL
+#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64)
+
+#define TYPE_S390_IPL "s390-ipl"
+#define S390_IPL(obj) \
+ OBJECT_CHECK(S390IPLState, (obj), TYPE_S390_IPL)
+#if 0
+#define S390_IPL_CLASS(klass) \
+ OBJECT_CLASS_CHECK(S390IPLState, (klass), TYPE_S390_IPL)
+#define S390_IPL_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(S390IPLState, (obj), TYPE_S390_IPL)
+#endif
+
+typedef struct S390IPLClass {
+ /*< private >*/
+ SysBusDeviceClass parent_class;
+ /*< public >*/
+
+ void (*parent_reset) (SysBusDevice *dev);
+} S390IPLClass;
+
+typedef struct S390IPLState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ /*< public >*/
+
+ char *kernel;
+ char *initrd;
+ char *cmdline;
+} S390IPLState;
+
+
+static void s390_ipl_cpu(uint64_t pswaddr)
+{
+ CPUS390XState *env = &S390_CPU(qemu_get_cpu(0))->env;
+ env->psw.addr = pswaddr;
+ env->psw.mask = IPL_PSW_MASK;
+ s390_add_running_cpu(env);
+}
+
+static int s390_ipl_init(SysBusDevice *dev)
+{
+ S390IPLState *ipl = S390_IPL(dev);
+ ram_addr_t kernel_size = 0;
+
+ if (!ipl->kernel) {
+ ram_addr_t bios_size = 0;
+ char *bios_filename;
+
+ /* Load zipl bootloader */
+ if (bios_name == NULL) {
+ bios_name = ZIPL_FILENAME;
+ }
+
+ bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START, 4096);
+ g_free(bios_filename);
+
+ if ((long)bios_size < 0) {
+ hw_error("could not load bootloader '%s'\n", bios_name);
+ }
+
+ if (bios_size > 4096) {
+ hw_error("stage1 bootloader is > 4k\n");
+ }
+ return 0;
+ } else {
+ kernel_size = load_elf(ipl->kernel, NULL, NULL, NULL, NULL,
+ NULL, 1, ELF_MACHINE, 0);
+ if (kernel_size == -1UL) {
+ kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);
+ }
+ if (kernel_size == -1UL) {
+ fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel);
+ return -1;
+ }
+ /* we have to overwrite values in the kernel image, which are "rom" */
+ strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline);
+ }
+ if (ipl->initrd) {
+ ram_addr_t initrd_offset, initrd_size;
+
+ initrd_offset = INITRD_START;
+ while (kernel_size + 0x100000 > initrd_offset) {
+ initrd_offset += 0x100000;
+ }
+ initrd_size = load_image_targphys(ipl->initrd, initrd_offset,
+ ram_size - initrd_offset);
+ if (initrd_size == -1UL) {
+ fprintf(stderr, "qemu: could not load initrd '%s'\n", ipl->initrd);
+ exit(1);
+ }
+
+ /* we have to overwrite values in the kernel image, which are "rom" */
+ stq_p(rom_ptr(INITRD_PARM_START), initrd_offset);
+ stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size);
+ }
+
+ return 0;
+}
+
+static Property s390_ipl_properties[] = {
+ DEFINE_PROP_STRING("kernel", S390IPLState, kernel),
+ DEFINE_PROP_STRING("initrd", S390IPLState, initrd),
+ DEFINE_PROP_STRING("cmdline", S390IPLState, cmdline),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void s390_ipl_reset(DeviceState *dev)
+{
+ S390IPLState *ipl = S390_IPL(dev);
+
+ if (ipl->kernel) {
+ /*
+ * we can not rely on the ELF entry point, since up to 3.2 this
+ * value was 0x800 (the SALIPL loader) and it wont work. For
+ * all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine.
+ */
+ return s390_ipl_cpu(KERN_IMAGE_START);
+ } else {
+ return s390_ipl_cpu(ZIPL_IMAGE_START);
+ }
+}
+
+static void s390_ipl_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+ k->init = s390_ipl_init;
+ dc->props = s390_ipl_properties;
+ dc->reset = s390_ipl_reset;
+ dc->no_user = 1;
+}
+
+static TypeInfo s390_ipl_info = {
+ .class_init = s390_ipl_class_init,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .name = "s390-ipl",
+ .instance_size = sizeof(S390IPLState),
+};
+
+static void s390_ipl_register_types(void)
+{
+ type_register_static(&s390_ipl_info);
+}
+
+type_init(s390_ipl_register_types)
diff --git a/hw/s390x/s390-virtio-hcall.c b/hw/s390x/s390-virtio-hcall.c
new file mode 100644
index 0000000000..d7938c0734
--- /dev/null
+++ b/hw/s390x/s390-virtio-hcall.c
@@ -0,0 +1,36 @@
+/*
+ * Support for virtio hypercalls on s390
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include "cpu.h"
+#include "hw/s390-virtio.h"
+
+#define MAX_DIAG_SUBCODES 255
+
+static s390_virtio_fn s390_diag500_table[MAX_DIAG_SUBCODES];
+
+void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn)
+{
+ assert(code < MAX_DIAG_SUBCODES);
+ assert(!s390_diag500_table[code]);
+
+ s390_diag500_table[code] = fn;
+}
+
+int s390_virtio_hypercall(CPUS390XState *env)
+{
+ s390_virtio_fn fn = s390_diag500_table[env->regs[1]];
+
+ if (!fn) {
+ return -EINVAL;
+ }
+
+ return fn(&env->regs[2]);
+}
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 6f5de44a89..41730bc7a8 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -216,13 +216,13 @@ static void nvram_init(M48t59State *nvram, uint8_t *macaddr,
static DeviceState *slavio_intctl;
-void sun4m_pic_info(Monitor *mon)
+void sun4m_pic_info(Monitor *mon, const QDict *qdict)
{
if (slavio_intctl)
slavio_pic_info(mon, slavio_intctl);
}
-void sun4m_irq_info(Monitor *mon)
+void sun4m_irq_info(Monitor *mon, const QDict *qdict)
{
if (slavio_intctl)
slavio_irq_info(mon, slavio_intctl);
@@ -1030,9 +1030,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
if (kernel_cmdline) {
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
- fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
- (uint8_t*)strdup(kernel_cmdline),
- strlen(kernel_cmdline) + 1);
+ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
strlen(kernel_cmdline) + 1);
} else {
@@ -1676,9 +1674,7 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
if (kernel_cmdline) {
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
- fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
- (uint8_t*)strdup(kernel_cmdline),
- strlen(kernel_cmdline) + 1);
+ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
} else {
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
}
@@ -1878,9 +1874,7 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
if (kernel_cmdline) {
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
- fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
- (uint8_t*)strdup(kernel_cmdline),
- strlen(kernel_cmdline) + 1);
+ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
} else {
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
}
diff --git a/hw/sun4m.h b/hw/sun4m.h
index 47eb945f07..0361eeed41 100644
--- a/hw/sun4m.h
+++ b/hw/sun4m.h
@@ -27,8 +27,8 @@ void slavio_pic_info(Monitor *mon, DeviceState *dev);
void slavio_irq_info(Monitor *mon, DeviceState *dev);
/* sun4m.c */
-void sun4m_pic_info(Monitor *mon);
-void sun4m_irq_info(Monitor *mon);
+void sun4m_pic_info(Monitor *mon, const QDict *qdict);
+void sun4m_irq_info(Monitor *mon, const QDict *qdict);
/* sparc32_dma.c */
#include "sparc32_dma.h"
diff --git a/hw/sun4u.c b/hw/sun4u.c
index cb75d03278..d36acde545 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -886,9 +886,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
if (kernel_cmdline) {
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
strlen(kernel_cmdline) + 1);
- fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
- (uint8_t*)strdup(kernel_cmdline),
- strlen(kernel_cmdline) + 1);
+ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
} else {
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0);
}
diff --git a/hw/usb.h b/hw/usb.h
index 50c297f341..bc42639b16 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -435,7 +435,7 @@ int set_usb_string(uint8_t *buf, const char *str);
/* usb-linux.c */
USBDevice *usb_host_device_open(USBBus *bus, const char *devname);
int usb_host_device_close(const char *devname);
-void usb_host_info(Monitor *mon);
+void usb_host_info(Monitor *mon, const QDict *qdict);
/* usb-bt.c */
USBDevice *usb_bt_init(USBBus *bus, HCIInfo *hci);
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 2dc76756a0..e58cd9ade2 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -542,7 +542,7 @@ static char *usb_get_fw_dev_path(DeviceState *qdev)
return fw_path;
}
-void usb_info(Monitor *mon)
+void usb_info(Monitor *mon, const QDict *qdict)
{
USBBus *bus;
USBDevice *dev;
diff --git a/hw/usb/host-bsd.c b/hw/usb/host-bsd.c
index 172aecbffd..07f0e01cc0 100644
--- a/hw/usb/host-bsd.c
+++ b/hw/usb/host-bsd.c
@@ -633,7 +633,7 @@ static int usb_host_info_device(void *opaque,
return 0;
}
-void usb_host_info(Monitor *mon)
+void usb_host_info(Monitor *mon, const QDict *qdict)
{
usb_host_scan(mon, usb_host_info_device);
}
diff --git a/hw/usb/host-linux.c b/hw/usb/host-linux.c
index ad75ce0702..a2cff8a74d 100644
--- a/hw/usb/host-linux.c
+++ b/hw/usb/host-linux.c
@@ -1998,7 +1998,7 @@ static void hex2str(int val, char *str, size_t size)
}
}
-void usb_host_info(Monitor *mon)
+void usb_host_info(Monitor *mon, const QDict *qdict)
{
struct USBAutoFilter *f;
struct USBHostDevice *s;
diff --git a/hw/usb/host-stub.c b/hw/usb/host-stub.c
index 58423a0f5c..8affba76c1 100644
--- a/hw/usb/host-stub.c
+++ b/hw/usb/host-stub.c
@@ -35,7 +35,7 @@
#include "hw/usb.h"
#include "monitor/monitor.h"
-void usb_host_info(Monitor *mon)
+void usb_host_info(Monitor *mon, const QDict *qdict)
{
monitor_printf(mon, "USB host devices not supported\n");
}
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 09342463ad..212acd8418 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -576,7 +576,7 @@ undo:
continue;
}
if (proxy->vdev->guest_notifier_mask) {
- kvm_virtio_pci_irqfd_release(proxy, vector, queue_no);
+ kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
}
kvm_virtio_pci_vq_vector_release(proxy, vector);
}
@@ -602,7 +602,7 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
* Otherwise, it was cleaned when masked in the frontend.
*/
if (proxy->vdev->guest_notifier_mask) {
- kvm_virtio_pci_irqfd_release(proxy, vector, queue_no);
+ kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
}
kvm_virtio_pci_vq_vector_release(proxy, vector);
}
@@ -651,7 +651,7 @@ static void kvm_virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
if (proxy->vdev->guest_notifier_mask) {
proxy->vdev->guest_notifier_mask(proxy->vdev, queue_no, true);
} else {
- kvm_virtio_pci_irqfd_release(proxy, vector, queue_no);
+ kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
}
}
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index d0cf85a83c..2911b9fc90 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -134,8 +134,6 @@ typedef struct icount_decr_u16 {
} icount_decr_u16;
#endif
-struct qemu_work_item;
-
typedef struct CPUBreakpoint {
target_ulong pc;
int flags; /* BP_* */
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 46dca74fda..d235ef8b2e 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -284,14 +284,8 @@ extern int tb_invalidated_flag;
/* The return address may point to the start of the next instruction.
Subtracting one gets us the call instruction itself. */
#if defined(CONFIG_TCG_INTERPRETER)
-/* Softmmu, Alpha, MIPS, SH4 and SPARC user mode emulations call GETPC().
- For all others, GETPC remains undefined (which makes TCI a little faster. */
-# if defined(CONFIG_SOFTMMU) || \
- defined(TARGET_ALPHA) || defined(TARGET_MIPS) || \
- defined(TARGET_SH4) || defined(TARGET_SPARC)
extern uintptr_t tci_tb_ptr;
-# define GETPC() tci_tb_ptr
-# endif
+# define GETPC() tci_tb_ptr
#elif defined(__s390__) && !defined(__s390x__)
# define GETPC() \
(((uintptr_t)__builtin_return_address(0) & 0x7fffffffUL) - 1)
diff --git a/include/net/net.h b/include/net/net.h
index de42dd76da..4a92b6c3d2 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -112,7 +112,7 @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
void *opaque);
void print_net_client(Monitor *mon, NetClientState *nc);
-void do_info_network(Monitor *mon);
+void do_info_network(Monitor *mon, const QDict *qdict);
/* NIC info */
diff --git a/include/net/slirp.h b/include/net/slirp.h
index 54b655c272..0502389c68 100644
--- a/include/net/slirp.h
+++ b/include/net/slirp.h
@@ -40,7 +40,7 @@ int net_slirp_parse_legacy(QemuOptsList *opts_list, const char *optarg, int *ret
int net_slirp_smb(const char *exported_dir);
-void do_info_usernet(Monitor *mon);
+void do_info_usernet(Monitor *mon, const QDict *qdict);
#endif
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index be9b035353..e6d4798142 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -72,45 +72,45 @@ static inline void bswap64s(uint64_t *s)
#if defined(HOST_WORDS_BIGENDIAN)
#define be_bswap(v, size) (v)
-#define le_bswap(v, size) bswap ## size(v)
+#define le_bswap(v, size) glue(bswap, size)(v)
#define be_bswaps(v, size)
-#define le_bswaps(p, size) *p = bswap ## size(*p);
+#define le_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
#else
#define le_bswap(v, size) (v)
-#define be_bswap(v, size) bswap ## size(v)
+#define be_bswap(v, size) glue(bswap, size)(v)
#define le_bswaps(v, size)
-#define be_bswaps(p, size) *p = bswap ## size(*p);
+#define be_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
#endif
#define CPU_CONVERT(endian, size, type)\
static inline type endian ## size ## _to_cpu(type v)\
{\
- return endian ## _bswap(v, size);\
+ return glue(endian, _bswap)(v, size);\
}\
\
static inline type cpu_to_ ## endian ## size(type v)\
{\
- return endian ## _bswap(v, size);\
+ return glue(endian, _bswap)(v, size);\
}\
\
static inline void endian ## size ## _to_cpus(type *p)\
{\
- endian ## _bswaps(p, size)\
+ glue(endian, _bswaps)(p, size);\
}\
\
static inline void cpu_to_ ## endian ## size ## s(type *p)\
{\
- endian ## _bswaps(p, size)\
+ glue(endian, _bswaps)(p, size);\
}\
\
static inline type endian ## size ## _to_cpup(const type *p)\
{\
- return endian ## size ## _to_cpu(*p);\
+ return glue(glue(endian, size), _to_cpu)(*p);\
}\
\
static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
{\
- *p = cpu_to_ ## endian ## size(v);\
+ *p = glue(glue(cpu_to_, endian), size)(v);\
}
CPU_CONVERT(be, 16, uint16_t)
diff --git a/include/qom/object.h b/include/qom/object.h
index 1ef2f0edd4..8e16ea8a44 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -147,9 +147,9 @@ typedef struct InterfaceInfo InterfaceInfo;
* </programlisting>
* </example>
*
- * Introducing new virtual functions requires a class to define its own
- * struct and to add a .class_size member to the TypeInfo. Each function
- * will also have a wrapper to call it easily:
+ * Introducing new virtual methods requires a class to define its own
+ * struct and to add a .class_size member to the #TypeInfo. Each method
+ * will also have a wrapper function to call it easily:
*
* <example>
* <title>Defining an abstract class</title>
@@ -186,6 +186,104 @@ typedef struct InterfaceInfo InterfaceInfo;
* similar to normal types except for the fact that are only defined by
* their classes and never carry any state. You can dynamically cast an object
* to one of its #Interface types and vice versa.
+ *
+ * # Methods #
+ *
+ * A <emphasis>method</emphasis> is a function within the namespace scope of
+ * a class. It usually operates on the object instance by passing it as a
+ * strongly-typed first argument.
+ * If it does not operate on an object instance, it is dubbed
+ * <emphasis>class method</emphasis>.
+ *
+ * Methods cannot be overloaded. That is, the #ObjectClass and method name
+ * uniquely identity the function to be called; the signature does not vary
+ * except for trailing varargs.
+ *
+ * Methods are always <emphasis>virtual</emphasis>. Overriding a method in
+ * #TypeInfo.class_init of a subclass leads to any user of the class obtained
+ * via OBJECT_GET_CLASS() accessing the overridden function.
+ * The original function is not automatically invoked. It is the responsability
+ * of the overriding class to determine whether and when to invoke the method
+ * being overridden.
+ *
+ * To invoke the method being overridden, the preferred solution is to store
+ * the original value in the overriding class before overriding the method.
+ * This corresponds to |[ {super,base}.method(...) ]| in Java and C#
+ * respectively; this frees the overriding class from hardcoding its parent
+ * class, which someone might choose to change at some point.
+ *
+ * <example>
+ * <title>Overriding a virtual method</title>
+ * <programlisting>
+ * typedef struct MyState MyState;
+ *
+ * typedef void (*MyDoSomething)(MyState *obj);
+ *
+ * typedef struct MyClass {
+ * ObjectClass parent_class;
+ *
+ * MyDoSomething do_something;
+ * } MyClass;
+ *
+ * static void my_do_something(MyState *obj)
+ * {
+ * // do something
+ * }
+ *
+ * static void my_class_init(ObjectClass *oc, void *data)
+ * {
+ * MyClass *mc = MY_CLASS(oc);
+ *
+ * mc->do_something = my_do_something;
+ * }
+ *
+ * static const TypeInfo my_type_info = {
+ * .name = TYPE_MY,
+ * .parent = TYPE_OBJECT,
+ * .instance_size = sizeof(MyState),
+ * .class_size = sizeof(MyClass),
+ * .class_init = my_class_init,
+ * };
+ *
+ * typedef struct DerivedClass {
+ * MyClass parent_class;
+ *
+ * MyDoSomething parent_do_something;
+ * } MyClass;
+ *
+ * static void derived_do_something(MyState *obj)
+ * {
+ * DerivedClass *dc = DERIVED_GET_CLASS(obj);
+ *
+ * // do something here
+ * dc->parent_do_something(obj);
+ * // do something else here
+ * }
+ *
+ * static void derived_class_init(ObjectClass *oc, void *data)
+ * {
+ * MyClass *mc = MY_CLASS(oc);
+ * DerivedClass *dc = DERIVED_CLASS(oc);
+ *
+ * dc->parent_do_something = mc->do_something;
+ * mc->do_something = derived_do_something;
+ * }
+ *
+ * static const TypeInfo derived_type_info = {
+ * .name = TYPE_DERIVED,
+ * .parent = TYPE_MY,
+ * .class_size = sizeof(DerivedClass),
+ * .class_init = my_class_init,
+ * };
+ * </programlisting>
+ * </example>
+ *
+ * Alternatively, object_class_by_name() can be used to obtain the class and
+ * its non-overridden methods for a specific type. This would correspond to
+ * |[ MyClass::method(...) ]| in C++.
+ *
+ * The first example of such a QOM method was #CPUClass.reset,
+ * another example is #DeviceClass.realize.
*/
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index c07d4ee458..6599617def 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -68,7 +68,7 @@ void qemu_add_machine_init_done_notifier(Notifier *notify);
void do_savevm(Monitor *mon, const QDict *qdict);
int load_vmstate(const char *name);
void do_delvm(Monitor *mon, const QDict *qdict);
-void do_info_snapshots(Monitor *mon);
+void do_info_snapshots(Monitor *mon, const QDict *qdict);
void qemu_announce_self(void);
@@ -171,7 +171,7 @@ extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
void do_usb_add(Monitor *mon, const QDict *qdict);
void do_usb_del(Monitor *mon, const QDict *qdict);
-void usb_info(Monitor *mon);
+void usb_info(Monitor *mon, const QDict *qdict);
void rtc_change_mon_event(struct tm *tm);
@@ -179,7 +179,7 @@ void register_devices(void);
void add_boot_device_path(int32_t bootindex, DeviceState *dev,
const char *suffix);
-char *get_boot_devices_list(uint32_t *size);
+char *get_boot_devices_list(size_t *size);
bool usb_enabled(bool default_usb);
diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
index 2fba8a66fb..16064d00ad 100644
--- a/linux-headers/asm-powerpc/kvm.h
+++ b/linux-headers/asm-powerpc/kvm.h
@@ -114,7 +114,10 @@ struct kvm_regs {
/* Embedded Floating Point (SPE) -- IVOR32-34 if KVM_SREGS_E_IVOR */
#define KVM_SREGS_E_SPE (1 << 9)
-/* External Proxy (EXP) -- EPR */
+/*
+ * DEPRECATED! USE ONE_REG FOR THIS ONE!
+ * External Proxy (EXP) -- EPR
+ */
#define KVM_SREGS_EXP (1 << 10)
/* External PID (E.PD) -- EPSC/EPLC */
@@ -412,5 +415,6 @@ struct kvm_get_htab_header {
#define KVM_REG_PPC_VPA_DTL (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x84)
#define KVM_REG_PPC_EPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
+#define KVM_REG_PPC_EPR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86)
#endif /* __LINUX_KVM_POWERPC_H */
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index bfdbf4d1ad..5af935761c 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -168,6 +168,8 @@ struct kvm_pit_config {
#define KVM_EXIT_PAPR_HCALL 19
#define KVM_EXIT_S390_UCONTROL 20
#define KVM_EXIT_WATCHDOG 21
+#define KVM_EXIT_S390_TSCH 22
+#define KVM_EXIT_EPR 23
/* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */
@@ -285,6 +287,19 @@ struct kvm_run {
__u64 ret;
__u64 args[9];
} papr_hcall;
+ /* KVM_EXIT_S390_TSCH */
+ struct {
+ __u16 subchannel_id;
+ __u16 subchannel_nr;
+ __u32 io_int_parm;
+ __u32 io_int_word;
+ __u32 ipb;
+ __u8 dequeued;
+ } s390_tsch;
+ /* KVM_EXIT_EPR */
+ struct {
+ __u32 epr;
+ } epr;
/* Fix the size of the union. */
char padding[256];
};
@@ -397,10 +412,20 @@ struct kvm_s390_psw {
#define KVM_S390_PROGRAM_INT 0xfffe0001u
#define KVM_S390_SIGP_SET_PREFIX 0xfffe0002u
#define KVM_S390_RESTART 0xfffe0003u
+#define KVM_S390_MCHK 0xfffe1000u
#define KVM_S390_INT_VIRTIO 0xffff2603u
#define KVM_S390_INT_SERVICE 0xffff2401u
#define KVM_S390_INT_EMERGENCY 0xffff1201u
#define KVM_S390_INT_EXTERNAL_CALL 0xffff1202u
+/* Anything below 0xfffe0000u is taken by INT_IO */
+#define KVM_S390_INT_IO(ai,cssid,ssid,schid) \
+ (((schid)) | \
+ ((ssid) << 16) | \
+ ((cssid) << 18) | \
+ ((ai) << 26))
+#define KVM_S390_INT_IO_MIN 0x00000000u
+#define KVM_S390_INT_IO_MAX 0xfffdffffu
+
struct kvm_s390_interrupt {
__u32 type;
@@ -635,6 +660,8 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_IRQFD_RESAMPLE 82
#define KVM_CAP_PPC_BOOKE_WATCHDOG 83
#define KVM_CAP_PPC_HTAB_FD 84
+#define KVM_CAP_S390_CSS_SUPPORT 85
+#define KVM_CAP_PPC_EPR 86
#ifdef KVM_CAP_IRQ_ROUTING
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3167a87549..693e66fc4f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4512,6 +4512,16 @@ static int target_to_host_fcntl_cmd(int cmd)
return -TARGET_EINVAL;
}
+#define TRANSTBL_CONVERT(a) { -1, TARGET_##a, -1, a }
+static const bitmask_transtbl flock_tbl[] = {
+ TRANSTBL_CONVERT(F_RDLCK),
+ TRANSTBL_CONVERT(F_WRLCK),
+ TRANSTBL_CONVERT(F_UNLCK),
+ TRANSTBL_CONVERT(F_EXLCK),
+ TRANSTBL_CONVERT(F_SHLCK),
+ { 0, 0, 0, 0 }
+};
+
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
{
struct flock fl;
@@ -4528,7 +4538,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
case TARGET_F_GETLK:
if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
return -TARGET_EFAULT;
- fl.l_type = tswap16(target_fl->l_type);
+ fl.l_type =
+ target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
fl.l_whence = tswap16(target_fl->l_whence);
fl.l_start = tswapal(target_fl->l_start);
fl.l_len = tswapal(target_fl->l_len);
@@ -4538,7 +4549,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
if (ret == 0) {
if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
return -TARGET_EFAULT;
- target_fl->l_type = tswap16(fl.l_type);
+ target_fl->l_type =
+ host_to_target_bitmask(tswap16(fl.l_type), flock_tbl);
target_fl->l_whence = tswap16(fl.l_whence);
target_fl->l_start = tswapal(fl.l_start);
target_fl->l_len = tswapal(fl.l_len);
@@ -4551,7 +4563,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
case TARGET_F_SETLKW:
if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
return -TARGET_EFAULT;
- fl.l_type = tswap16(target_fl->l_type);
+ fl.l_type =
+ target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
fl.l_whence = tswap16(target_fl->l_whence);
fl.l_start = tswapal(target_fl->l_start);
fl.l_len = tswapal(target_fl->l_len);
@@ -4563,7 +4576,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
case TARGET_F_GETLK64:
if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
return -TARGET_EFAULT;
- fl64.l_type = tswap16(target_fl64->l_type) >> 1;
+ fl64.l_type =
+ target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
fl64.l_whence = tswap16(target_fl64->l_whence);
fl64.l_start = tswap64(target_fl64->l_start);
fl64.l_len = tswap64(target_fl64->l_len);
@@ -4573,7 +4587,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
if (ret == 0) {
if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
return -TARGET_EFAULT;
- target_fl64->l_type = tswap16(fl64.l_type) >> 1;
+ target_fl64->l_type =
+ host_to_target_bitmask(tswap16(fl64.l_type), flock_tbl) >> 1;
target_fl64->l_whence = tswap16(fl64.l_whence);
target_fl64->l_start = tswap64(fl64.l_start);
target_fl64->l_len = tswap64(fl64.l_len);
@@ -4585,7 +4600,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
case TARGET_F_SETLKW64:
if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
return -TARGET_EFAULT;
- fl64.l_type = tswap16(target_fl64->l_type) >> 1;
+ fl64.l_type =
+ target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
fl64.l_whence = tswap16(target_fl64->l_whence);
fl64.l_start = tswap64(target_fl64->l_start);
fl64.l_len = tswap64(target_fl64->l_len);
@@ -6211,8 +6227,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
ret = get_errno(settimeofday(&tv, NULL));
}
break;
-#if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390)
+#if defined(TARGET_NR_select)
case TARGET_NR_select:
+#if defined(TARGET_S390X) || defined(TARGET_ALPHA)
+ ret = do_select(arg1, arg2, arg3, arg4, arg5);
+#else
{
struct target_sel_arg_struct *sel;
abi_ulong inp, outp, exp, tvp;
@@ -6228,6 +6247,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
unlock_user_struct(sel, arg1, 0);
ret = do_select(nsel, inp, outp, exp, tvp);
}
+#endif
break;
#endif
#ifdef TARGET_NR_pselect6
@@ -7151,12 +7171,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
#endif /* TARGET_NR_getdents64 */
-#if defined(TARGET_NR__newselect) || defined(TARGET_S390X)
-#ifdef TARGET_S390X
- case TARGET_NR_select:
-#else
+#if defined(TARGET_NR__newselect)
case TARGET_NR__newselect:
-#endif
ret = do_select(arg1, arg2, arg3, arg4, arg5);
break;
#endif
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index f8f553915d..92c01a9603 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -2017,6 +2017,12 @@ struct target_statfs64 {
#define TARGET_F_SETLKW 9
#define TARGET_F_SETOWN 5 /* for sockets. */
#define TARGET_F_GETOWN 6 /* for sockets. */
+
+#define TARGET_F_RDLCK 1
+#define TARGET_F_WRLCK 2
+#define TARGET_F_UNLCK 8
+#define TARGET_F_EXLCK 16
+#define TARGET_F_SHLCK 32
#elif defined(TARGET_MIPS)
#define TARGET_F_GETLK 14
#define TARGET_F_SETLK 6
@@ -2031,6 +2037,18 @@ struct target_statfs64 {
#define TARGET_F_GETOWN 9 /* for sockets. */
#endif
+#ifndef TARGET_F_RDLCK
+#define TARGET_F_RDLCK 0
+#define TARGET_F_WRLCK 1
+#define TARGET_F_UNLCK 2
+#endif
+
+#ifndef TARGET_F_EXLCK
+#define TARGET_F_EXLCK 4
+#define TARGET_F_SHLCK 8
+#endif
+
+
#define TARGET_F_SETSIG 10 /* for sockets. */
#define TARGET_F_GETSIG 11 /* for sockets. */
diff --git a/monitor.c b/monitor.c
index 77ac451a23..20bd19b05f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -123,13 +123,17 @@ typedef struct mon_cmd_t {
const char *help;
void (*user_print)(Monitor *mon, const QObject *data);
union {
- void (*info)(Monitor *mon);
void (*cmd)(Monitor *mon, const QDict *qdict);
int (*cmd_new)(Monitor *mon, const QDict *params, QObject **ret_data);
int (*cmd_async)(Monitor *mon, const QDict *params,
MonitorCompletion *cb, void *opaque);
} mhandler;
int flags;
+ /* @sub_table is a list of 2nd level of commands. If it do not exist,
+ * mhandler should be used. If it exist, sub_table[?].mhandler should be
+ * used, and mhandler of 1st level plays the role of help function.
+ */
+ struct mon_cmd_t *sub_table;
} mon_cmd_t;
/* file descriptors passed via SCM_RIGHTS */
@@ -807,28 +811,8 @@ static void user_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd,
}
}
-static void do_info(Monitor *mon, const QDict *qdict)
+static void do_info_help(Monitor *mon, const QDict *qdict)
{
- const mon_cmd_t *cmd;
- const char *item = qdict_get_try_str(qdict, "item");
-
- if (!item) {
- goto help;
- }
-
- for (cmd = info_cmds; cmd->name != NULL; cmd++) {
- if (compare_cmd(item, cmd->name))
- break;
- }
-
- if (cmd->name == NULL) {
- goto help;
- }
-
- cmd->mhandler.info(mon);
- return;
-
-help:
help_cmd(mon, "info");
}
@@ -899,19 +883,19 @@ int monitor_get_cpu_index(void)
return cpu->cpu_index;
}
-static void do_info_registers(Monitor *mon)
+static void do_info_registers(Monitor *mon, const QDict *qdict)
{
CPUArchState *env;
env = mon_get_cpu();
cpu_dump_state(env, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU);
}
-static void do_info_jit(Monitor *mon)
+static void do_info_jit(Monitor *mon, const QDict *qdict)
{
dump_exec_info((FILE *)mon, monitor_fprintf);
}
-static void do_info_history(Monitor *mon)
+static void do_info_history(Monitor *mon, const QDict *qdict)
{
int i;
const char *str;
@@ -930,7 +914,7 @@ static void do_info_history(Monitor *mon)
#if defined(TARGET_PPC)
/* XXX: not implemented in other targets */
-static void do_info_cpu_stats(Monitor *mon)
+static void do_info_cpu_stats(Monitor *mon, const QDict *qdict)
{
CPUArchState *env;
@@ -939,7 +923,7 @@ static void do_info_cpu_stats(Monitor *mon)
}
#endif
-static void do_trace_print_events(Monitor *mon)
+static void do_trace_print_events(Monitor *mon, const QDict *qdict)
{
trace_print_events((FILE *)mon, &monitor_fprintf);
}
@@ -1491,7 +1475,7 @@ static void tlb_info_64(Monitor *mon, CPUArchState *env)
}
#endif
-static void tlb_info(Monitor *mon)
+static void tlb_info(Monitor *mon, const QDict *qdict)
{
CPUArchState *env;
@@ -1714,7 +1698,7 @@ static void mem_info_64(Monitor *mon, CPUArchState *env)
}
#endif
-static void mem_info(Monitor *mon)
+static void mem_info(Monitor *mon, const QDict *qdict)
{
CPUArchState *env;
@@ -1753,7 +1737,7 @@ static void print_tlb(Monitor *mon, int idx, tlb_t *tlb)
tlb->d, tlb->wt);
}
-static void tlb_info(Monitor *mon)
+static void tlb_info(Monitor *mon, const QDict *qdict)
{
CPUArchState *env = mon_get_cpu();
int i;
@@ -1769,7 +1753,7 @@ static void tlb_info(Monitor *mon)
#endif
#if defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_XTENSA)
-static void tlb_info(Monitor *mon)
+static void tlb_info(Monitor *mon, const QDict *qdict)
{
CPUArchState *env1 = mon_get_cpu();
@@ -1777,12 +1761,12 @@ static void tlb_info(Monitor *mon)
}
#endif
-static void do_info_mtree(Monitor *mon)
+static void do_info_mtree(Monitor *mon, const QDict *qdict)
{
mtree_info((fprintf_function)monitor_printf, mon);
}
-static void do_info_numa(Monitor *mon)
+static void do_info_numa(Monitor *mon, const QDict *qdict)
{
int i;
CPUArchState *env;
@@ -1808,7 +1792,7 @@ static void do_info_numa(Monitor *mon)
int64_t qemu_time;
int64_t dev_time;
-static void do_info_profile(Monitor *mon)
+static void do_info_profile(Monitor *mon, const QDict *qdict)
{
int64_t total;
total = qemu_time;
@@ -1822,7 +1806,7 @@ static void do_info_profile(Monitor *mon)
dev_time = 0;
}
#else
-static void do_info_profile(Monitor *mon)
+static void do_info_profile(Monitor *mon, const QDict *qdict)
{
monitor_printf(mon, "Internal profiler not compiled\n");
}
@@ -1831,7 +1815,7 @@ static void do_info_profile(Monitor *mon)
/* Capture support */
static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
-static void do_info_capture(Monitor *mon)
+static void do_info_capture(Monitor *mon, const QDict *qdict)
{
int i;
CaptureState *s;
@@ -2429,12 +2413,6 @@ int monitor_handle_fd_param(Monitor *mon, const char *fdname)
return fd;
}
-/* mon_cmds and info_cmds would be sorted at runtime */
-static mon_cmd_t mon_cmds[] = {
-#include "hmp-commands.h"
- { NULL, NULL, },
-};
-
/* Please update hmp-commands.hx when adding or changing commands */
static mon_cmd_t info_cmds[] = {
{
@@ -2442,63 +2420,63 @@ static mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show the version of QEMU",
- .mhandler.info = hmp_info_version,
+ .mhandler.cmd = hmp_info_version,
},
{
.name = "network",
.args_type = "",
.params = "",
.help = "show the network state",
- .mhandler.info = do_info_network,
+ .mhandler.cmd = do_info_network,
},
{
.name = "chardev",
.args_type = "",
.params = "",
.help = "show the character devices",
- .mhandler.info = hmp_info_chardev,
+ .mhandler.cmd = hmp_info_chardev,
},
{
.name = "block",
.args_type = "",
.params = "",
.help = "show the block devices",
- .mhandler.info = hmp_info_block,
+ .mhandler.cmd = hmp_info_block,
},
{
.name = "blockstats",
.args_type = "",
.params = "",
.help = "show block device statistics",
- .mhandler.info = hmp_info_blockstats,
+ .mhandler.cmd = hmp_info_blockstats,
},
{
.name = "block-jobs",
.args_type = "",
.params = "",
.help = "show progress of ongoing block device operations",
- .mhandler.info = hmp_info_block_jobs,
+ .mhandler.cmd = hmp_info_block_jobs,
},
{
.name = "registers",
.args_type = "",
.params = "",
.help = "show the cpu registers",
- .mhandler.info = do_info_registers,
+ .mhandler.cmd = do_info_registers,
},
{
.name = "cpus",
.args_type = "",
.params = "",
.help = "show infos for each CPU",
- .mhandler.info = hmp_info_cpus,
+ .mhandler.cmd = hmp_info_cpus,
},
{
.name = "history",
.args_type = "",
.params = "",
.help = "show the command line history",
- .mhandler.info = do_info_history,
+ .mhandler.cmd = do_info_history,
},
#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_MIPS) || \
defined(TARGET_LM32) || (defined(TARGET_SPARC) && !defined(TARGET_SPARC64))
@@ -2508,11 +2486,11 @@ static mon_cmd_t info_cmds[] = {
.params = "",
.help = "show the interrupts statistics (if available)",
#ifdef TARGET_SPARC
- .mhandler.info = sun4m_irq_info,
+ .mhandler.cmd = sun4m_irq_info,
#elif defined(TARGET_LM32)
- .mhandler.info = lm32_irq_info,
+ .mhandler.cmd = lm32_irq_info,
#else
- .mhandler.info = irq_info,
+ .mhandler.cmd = irq_info,
#endif
},
{
@@ -2521,11 +2499,11 @@ static mon_cmd_t info_cmds[] = {
.params = "",
.help = "show i8259 (PIC) state",
#ifdef TARGET_SPARC
- .mhandler.info = sun4m_pic_info,
+ .mhandler.cmd = sun4m_pic_info,
#elif defined(TARGET_LM32)
- .mhandler.info = lm32_do_pic_info,
+ .mhandler.cmd = lm32_do_pic_info,
#else
- .mhandler.info = pic_info,
+ .mhandler.cmd = pic_info,
#endif
},
#endif
@@ -2534,7 +2512,7 @@ static mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show PCI info",
- .mhandler.info = hmp_info_pci,
+ .mhandler.cmd = hmp_info_pci,
},
#if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) || \
defined(TARGET_PPC) || defined(TARGET_XTENSA)
@@ -2543,7 +2521,7 @@ static mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show virtual to physical memory mappings",
- .mhandler.info = tlb_info,
+ .mhandler.cmd = tlb_info,
},
#endif
#if defined(TARGET_I386)
@@ -2552,7 +2530,7 @@ static mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show the active virtual memory mappings",
- .mhandler.info = mem_info,
+ .mhandler.cmd = mem_info,
},
#endif
{
@@ -2560,91 +2538,91 @@ static mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show memory tree",
- .mhandler.info = do_info_mtree,
+ .mhandler.cmd = do_info_mtree,
},
{
.name = "jit",
.args_type = "",
.params = "",
.help = "show dynamic compiler info",
- .mhandler.info = do_info_jit,
+ .mhandler.cmd = do_info_jit,
},
{
.name = "kvm",
.args_type = "",
.params = "",
.help = "show KVM information",
- .mhandler.info = hmp_info_kvm,
+ .mhandler.cmd = hmp_info_kvm,
},
{
.name = "numa",
.args_type = "",
.params = "",
.help = "show NUMA information",
- .mhandler.info = do_info_numa,
+ .mhandler.cmd = do_info_numa,
},
{
.name = "usb",
.args_type = "",
.params = "",
.help = "show guest USB devices",
- .mhandler.info = usb_info,
+ .mhandler.cmd = usb_info,
},
{
.name = "usbhost",
.args_type = "",
.params = "",
.help = "show host USB devices",
- .mhandler.info = usb_host_info,
+ .mhandler.cmd = usb_host_info,
},
{
.name = "profile",
.args_type = "",
.params = "",
.help = "show profiling information",
- .mhandler.info = do_info_profile,
+ .mhandler.cmd = do_info_profile,
},
{
.name = "capture",
.args_type = "",
.params = "",
.help = "show capture information",
- .mhandler.info = do_info_capture,
+ .mhandler.cmd = do_info_capture,
},
{
.name = "snapshots",
.args_type = "",
.params = "",
.help = "show the currently saved VM snapshots",
- .mhandler.info = do_info_snapshots,
+ .mhandler.cmd = do_info_snapshots,
},
{
.name = "status",
.args_type = "",
.params = "",
.help = "show the current VM status (running|paused)",
- .mhandler.info = hmp_info_status,
+ .mhandler.cmd = hmp_info_status,
},
{
.name = "pcmcia",
.args_type = "",
.params = "",
.help = "show guest PCMCIA status",
- .mhandler.info = pcmcia_info,
+ .mhandler.cmd = pcmcia_info,
},
{
.name = "mice",
.args_type = "",
.params = "",
.help = "show which guest mouse is receiving events",
- .mhandler.info = hmp_info_mice,
+ .mhandler.cmd = hmp_info_mice,
},
{
.name = "vnc",
.args_type = "",
.params = "",
.help = "show the vnc server status",
- .mhandler.info = hmp_info_vnc,
+ .mhandler.cmd = hmp_info_vnc,
},
#if defined(CONFIG_SPICE)
{
@@ -2652,7 +2630,7 @@ static mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show the spice server status",
- .mhandler.info = hmp_info_spice,
+ .mhandler.cmd = hmp_info_spice,
},
#endif
{
@@ -2660,14 +2638,14 @@ static mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show the current VM name",
- .mhandler.info = hmp_info_name,
+ .mhandler.cmd = hmp_info_name,
},
{
.name = "uuid",
.args_type = "",
.params = "",
.help = "show the current VM UUID",
- .mhandler.info = hmp_info_uuid,
+ .mhandler.cmd = hmp_info_uuid,
},
#if defined(TARGET_PPC)
{
@@ -2675,7 +2653,7 @@ static mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show CPU statistics",
- .mhandler.info = do_info_cpu_stats,
+ .mhandler.cmd = do_info_cpu_stats,
},
#endif
#if defined(CONFIG_SLIRP)
@@ -2684,7 +2662,7 @@ static mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show user network stack connection states",
- .mhandler.info = do_info_usernet,
+ .mhandler.cmd = do_info_usernet,
},
#endif
{
@@ -2692,62 +2670,68 @@ static mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show migration status",
- .mhandler.info = hmp_info_migrate,
+ .mhandler.cmd = hmp_info_migrate,
},
{
.name = "migrate_capabilities",
.args_type = "",
.params = "",
.help = "show current migration capabilities",
- .mhandler.info = hmp_info_migrate_capabilities,
+ .mhandler.cmd = hmp_info_migrate_capabilities,
},
{
.name = "migrate_cache_size",
.args_type = "",
.params = "",
.help = "show current migration xbzrle cache size",
- .mhandler.info = hmp_info_migrate_cache_size,
+ .mhandler.cmd = hmp_info_migrate_cache_size,
},
{
.name = "balloon",
.args_type = "",
.params = "",
.help = "show balloon information",
- .mhandler.info = hmp_info_balloon,
+ .mhandler.cmd = hmp_info_balloon,
},
{
.name = "qtree",
.args_type = "",
.params = "",
.help = "show device tree",
- .mhandler.info = do_info_qtree,
+ .mhandler.cmd = do_info_qtree,
},
{
.name = "qdm",
.args_type = "",
.params = "",
.help = "show qdev device model list",
- .mhandler.info = do_info_qdm,
+ .mhandler.cmd = do_info_qdm,
},
{
.name = "roms",
.args_type = "",
.params = "",
.help = "show roms",
- .mhandler.info = do_info_roms,
+ .mhandler.cmd = do_info_roms,
},
{
.name = "trace-events",
.args_type = "",
.params = "",
.help = "show available trace-events & their state",
- .mhandler.info = do_trace_print_events,
+ .mhandler.cmd = do_trace_print_events,
},
{
.name = NULL,
},
};
+/* mon_cmds and info_cmds would be sorted at runtime */
+static mon_cmd_t mon_cmds[] = {
+#include "hmp-commands.h"
+ { NULL, NULL, },
+};
+
static const mon_cmd_t qmp_cmds[] = {
#include "qmp-commands-old.h"
{ /* NULL */ },
@@ -3542,18 +3526,27 @@ static const mon_cmd_t *search_dispatch_table(const mon_cmd_t *disp_table,
return NULL;
}
-static const mon_cmd_t *monitor_find_command(const char *cmdname)
-{
- return search_dispatch_table(mon_cmds, cmdname);
-}
-
static const mon_cmd_t *qmp_find_cmd(const char *cmdname)
{
return search_dispatch_table(qmp_cmds, cmdname);
}
+/*
+ * Parse @cmdline according to command table @table.
+ * If @cmdline is blank, return NULL.
+ * If it can't be parsed, report to @mon, and return NULL.
+ * Else, insert command arguments into @qdict, and return the command.
+ * If sub-command table exist, and if @cmdline contains addtional string for
+ * sub-command, this function will try search sub-command table. if no
+ * addtional string for sub-command exist, this function will return the found
+ * one in @table.
+ * Do not assume the returned command points into @table! It doesn't
+ * when the command is a sub-command.
+ */
static const mon_cmd_t *monitor_parse_command(Monitor *mon,
const char *cmdline,
+ int start,
+ mon_cmd_t *table,
QDict *qdict)
{
const char *p, *typestr;
@@ -3564,20 +3557,35 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
char *key;
#ifdef DEBUG
- monitor_printf(mon, "command='%s'\n", cmdline);
+ monitor_printf(mon, "command='%s', start='%d'\n", cmdline, start);
#endif
/* extract the command name */
- p = get_command_name(cmdline, cmdname, sizeof(cmdname));
+ p = get_command_name(cmdline + start, cmdname, sizeof(cmdname));
if (!p)
return NULL;
- cmd = monitor_find_command(cmdname);
+ cmd = search_dispatch_table(table, cmdname);
if (!cmd) {
- monitor_printf(mon, "unknown command: '%s'\n", cmdname);
+ monitor_printf(mon, "unknown command: '%.*s'\n",
+ (int)(p - cmdline), cmdline);
return NULL;
}
+ /* filter out following useless space */
+ while (qemu_isspace(*p)) {
+ p++;
+ }
+ /* search sub command */
+ if (cmd->sub_table != NULL) {
+ /* check if user set additional command */
+ if (*p == '\0') {
+ return cmd;
+ }
+ return monitor_parse_command(mon, cmdline, p - cmdline,
+ cmd->sub_table, qdict);
+ }
+
/* parse the parameters */
typestr = cmd->args_type;
for(;;) {
@@ -3933,7 +3941,7 @@ static void handle_user_command(Monitor *mon, const char *cmdline)
qdict = qdict_new();
- cmd = monitor_parse_command(mon, cmdline, qdict);
+ cmd = monitor_parse_command(mon, cmdline, 0, mon_cmds, qdict);
if (!cmd)
goto out;
diff --git a/net/net.c b/net/net.c
index 02b5458a1b..cdd9b04989 100644
--- a/net/net.c
+++ b/net/net.c
@@ -852,7 +852,7 @@ void print_net_client(Monitor *mon, NetClientState *nc)
NetClientOptionsKind_lookup[nc->info->type], nc->info_str);
}
-void do_info_network(Monitor *mon)
+void do_info_network(Monitor *mon, const QDict *qdict)
{
NetClientState *nc, *peer;
NetClientOptionsKind type;
diff --git a/net/slirp.c b/net/slirp.c
index c14259f004..4df550faf6 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -670,7 +670,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
return -1;
}
-void do_info_usernet(Monitor *mon)
+void do_info_usernet(Monitor *mon, const QDict *qdict)
{
SlirpState *s;
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 77f6ee7d5f..0ad73f3430 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -939,14 +939,11 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
- if (asprintf(&info->value->hardware_address,
- "%02x:%02x:%02x:%02x:%02x:%02x",
- (int) mac_addr[0], (int) mac_addr[1],
- (int) mac_addr[2], (int) mac_addr[3],
- (int) mac_addr[4], (int) mac_addr[5]) == -1) {
- error_setg_errno(errp, errno, "failed to format MAC");
- goto error;
- }
+ info->value->hardware_address =
+ g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x",
+ (int) mac_addr[0], (int) mac_addr[1],
+ (int) mac_addr[2], (int) mac_addr[3],
+ (int) mac_addr[4], (int) mac_addr[5]);
info->value->has_hardware_address = true;
close(sock);
diff --git a/savevm.c b/savevm.c
index 4e970ca0db..d9ff1d9b72 100644
--- a/savevm.c
+++ b/savevm.c
@@ -2307,7 +2307,7 @@ void do_delvm(Monitor *mon, const QDict *qdict)
}
}
-void do_info_snapshots(Monitor *mon)
+void do_info_snapshots(Monitor *mon, const QDict *qdict)
{
BlockDriverState *bs, *bs1;
QEMUSnapshotInfo *sn_tab, *sn, s, *sn_info = &s;
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 19e9f25b19..2f4f06818a 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -846,6 +846,11 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
ret = 0;
break;
#endif
+ case KVM_EXIT_EPR:
+ dprintf("handle epr\n");
+ run->epr.epr = ldl_phys(env->mpic_iack);
+ ret = 0;
+ break;
default:
fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
ret = -1;
@@ -1057,6 +1062,22 @@ void kvmppc_set_papr(PowerPCCPU *cpu)
}
}
+void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy)
+{
+ CPUPPCState *env = &cpu->env;
+ CPUState *cs = CPU(cpu);
+ struct kvm_enable_cap cap = {};
+ int ret;
+
+ cap.cap = KVM_CAP_PPC_EPR;
+ cap.args[0] = mpic_proxy;
+ ret = kvm_vcpu_ioctl(cs, KVM_ENABLE_CAP, &cap);
+
+ if (ret && mpic_proxy) {
+ cpu_abort(env, "This KVM version does not support EPR\n");
+ }
+}
+
int kvmppc_smt_threads(void)
{
return cap_ppc_smt ? cap_ppc_smt : 1;
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 3db21fc889..c30b006674 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -25,6 +25,7 @@ int kvmppc_get_hasidle(CPUPPCState *env);
int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len);
int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level);
void kvmppc_set_papr(PowerPCCPU *cpu);
+void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy);
int kvmppc_smt_threads(void);
#ifndef CONFIG_USER_ONLY
off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem);
@@ -81,6 +82,10 @@ static inline void kvmppc_set_papr(PowerPCCPU *cpu)
{
}
+static inline void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy)
+{
+}
+
static inline int kvmppc_smt_threads(void)
{
return 1;
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 3f199c4bb9..2d78529273 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8633,9 +8633,9 @@ static const ppc_def_t ppc_defs[] = {
POWERPC_DEF("e500v2_v22", CPU_POWERPC_e500v2_v22, e500v2),
/* PowerPC e500v2 v3.0 core */
POWERPC_DEF("e500v2_v30", CPU_POWERPC_e500v2_v30, e500v2),
- POWERPC_DEF("e500mc", CPU_POWERPC_e500mc, e500mc),
+ POWERPC_DEF_SVR("e500mc", CPU_POWERPC_e500mc, POWERPC_SVR_E500, e500mc),
#ifdef TARGET_PPC64
- POWERPC_DEF("e5500", CPU_POWERPC_e5500, e5500),
+ POWERPC_DEF_SVR("e5500", CPU_POWERPC_e5500, POWERPC_SVR_E500, e5500),
#endif
/* PowerPC e500 microcontrollers */
/* MPC8533 */
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 2ed23127d1..0b68db8305 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -4,6 +4,7 @@
* Copyright (c) 2009 Ulrich Hecht
* Copyright (c) 2011 Alexander Graf
* Copyright (c) 2012 SUSE LINUX Products GmbH
+ * Copyright (c) 2012 IBM Corp.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -18,12 +19,44 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>
+ * Contributions after 2012-12-11 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
*/
#include "cpu.h"
#include "qemu-common.h"
#include "qemu/timer.h"
+#ifndef CONFIG_USER_ONLY
+#include "hw/hw.h"
+#include "sysemu/arch_init.h"
+#endif
+
+#define CR0_RESET 0xE0UL
+#define CR14_RESET 0xC2000000UL;
+
+/* generate CPU information for cpu -? */
+void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf)
+{
+#ifdef CONFIG_KVM
+ (*cpu_fprintf)(f, "s390 %16s\n", "host");
+#endif
+}
+
+#ifndef CONFIG_USER_ONLY
+CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
+{
+ CpuDefinitionInfoList *entry;
+ CpuDefinitionInfo *info;
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strdup("host");
+
+ entry = g_malloc0(sizeof(*entry));
+ entry->value = info;
+
+ return entry;
+}
+#endif
/* CPUClass::reset() */
static void s390_cpu_reset(CPUState *s)
@@ -37,14 +70,33 @@ static void s390_cpu_reset(CPUState *s)
log_cpu_state(env, 0);
}
+ s390_del_running_cpu(env);
+
scc->parent_reset(s);
memset(env, 0, offsetof(CPUS390XState, breakpoints));
- /* FIXME: reset vector? */
+
+ /* architectured initial values for CR 0 and 14 */
+ env->cregs[0] = CR0_RESET;
+ env->cregs[14] = CR14_RESET;
+ /* set halted to 1 to make sure we can add the cpu in
+ * s390_ipl_cpu code, where env->halted is set back to 0
+ * after incrementing the cpu counter */
+#if !defined(CONFIG_USER_ONLY)
+ env->halted = 1;
+#endif
tlb_flush(env, 1);
- s390_add_running_cpu(env);
}
+#if !defined(CONFIG_USER_ONLY)
+static void s390_cpu_machine_reset_cb(void *opaque)
+{
+ S390CPU *cpu = opaque;
+
+ cpu_reset(CPU(cpu));
+}
+#endif
+
static void s390_cpu_initfn(Object *obj)
{
S390CPU *cpu = S390_CPU(obj);
@@ -56,12 +108,17 @@ static void s390_cpu_initfn(Object *obj)
cpu_exec_init(env);
#if !defined(CONFIG_USER_ONLY)
+ qemu_register_reset(s390_cpu_machine_reset_cb, cpu);
qemu_get_timedate(&tm, 0);
env->tod_offset = TOD_UNIX_EPOCH +
(time2tod(mktimegm(&tm)) * 1000000000ULL);
env->tod_basetime = 0;
env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, cpu);
env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, cpu);
+ /* set env->halted state to 1 to avoid decrementing the running
+ * cpu counter in s390_cpu_reset to a negative number at
+ * initial ipl */
+ env->halted = 1;
#endif
env->cpu_num = cpu_num++;
env->ext_index = -1;
@@ -69,6 +126,15 @@ static void s390_cpu_initfn(Object *obj)
cpu_reset(CPU(cpu));
}
+static void s390_cpu_finalize(Object *obj)
+{
+#if !defined(CONFIG_USER_ONLY)
+ S390CPU *cpu = S390_CPU(obj);
+
+ qemu_unregister_reset(s390_cpu_machine_reset_cb, cpu);
+#endif
+}
+
static void s390_cpu_class_init(ObjectClass *oc, void *data)
{
S390CPUClass *scc = S390_CPU_CLASS(oc);
@@ -83,6 +149,7 @@ static const TypeInfo s390_cpu_type_info = {
.parent = TYPE_CPU,
.instance_size = sizeof(S390CPU),
.instance_init = s390_cpu_initfn,
+ .instance_finalize = s390_cpu_finalize,
.abstract = false,
.class_size = sizeof(S390CPUClass),
.class_init = s390_cpu_class_init,
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index bc3fab226b..1f2d94218a 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -13,7 +13,10 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public
+ * Contributions after 2012-10-29 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ *
+ * You should have received a copy of the GNU (Lesser) General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CPU_S390X_H
@@ -302,7 +305,7 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw
void s390x_tod_timer(void *opaque);
void s390x_cpu_timer(void *opaque);
-int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t hypercall);
+int s390_virtio_hypercall(CPUS390XState *env);
#ifdef CONFIG_KVM
void kvm_s390_interrupt(S390CPU *cpu, int type, uint32_t code);
@@ -359,6 +362,9 @@ static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls)
#define cpu_gen_code cpu_s390x_gen_code
#define cpu_signal_handler cpu_s390x_signal_handler
+void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf);
+#define cpu_list s390_cpu_list
+
#include "exec/exec-all.h"
#define EXCP_EXT 1 /* external interrupt */
@@ -769,87 +775,6 @@ struct sysib_322 {
#define SK_F (0x1 << 3)
#define SK_ACC_MASK (0xf << 4)
-
-/* EBCDIC handling */
-static const uint8_t ebcdic2ascii[] = {
- 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
- 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
- 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
- 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
- 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
- 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
- 0x87, 0xA4, 0x5B, 0x2E, 0x3C, 0x28, 0x2B, 0x21,
- 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
- 0x8D, 0xE1, 0x5D, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
- 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
- 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
- 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
- 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
- 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
- 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
- 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
- 0x9B, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
- 0xAB, 0x07, 0xAA, 0x7C, 0x07, 0x07, 0x07, 0x07,
- 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
- 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
- 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
- 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07,
-};
-
-static const uint8_t ascii2ebcdic [] = {
- 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
- 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
- 0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F,
- 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
- 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
- 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
- 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
- 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
- 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
- 0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D,
- 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
- 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
- 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF
-};
-
-static inline void ebcdic_put(uint8_t *p, const char *ascii, int len)
-{
- int i;
-
- for (i = 0; i < len; i++) {
- p[i] = ascii2ebcdic[(int)ascii[i]];
- }
-}
-
#define SIGP_SENSE 0x01
#define SIGP_EXTERNAL_CALL 0x02
#define SIGP_EMERGENCY 0x03
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 6ec5e6d8a6..add6a58f9c 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -2,6 +2,7 @@
* QEMU S390x KVM implementation
*
* Copyright (c) 2009 Alexander Graf <agraf@suse.de>
+ * Copyright IBM Corp. 2012
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -13,7 +14,10 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public
+ * Contributions after 2012-10-29 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ *
+ * You should have received a copy of the GNU (Lesser) General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
@@ -85,7 +89,14 @@ int kvm_arch_init_vcpu(CPUState *cpu)
void kvm_arch_reset_vcpu(CPUState *cpu)
{
- /* FIXME: add code to reset vcpu. */
+ /* The initial reset call is needed here to reset in-kernel
+ * vcpu data that we can't access directly from QEMU
+ * (i.e. with older kernels which don't support sync_regs/ONE_REG).
+ * Before this ioctl cpu_synchronize_state() is called in common kvm
+ * code (kvm-all) */
+ if (kvm_vcpu_ioctl(cpu, KVM_S390_INITIAL_RESET, NULL)) {
+ perror("Can't reset vcpu\n");
+ }
}
int kvm_arch_put_registers(CPUState *cs, int level)
@@ -386,7 +397,7 @@ static int handle_priv(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
static int handle_hypercall(CPUS390XState *env, struct kvm_run *run)
{
cpu_synchronize_state(env);
- env->regs[2] = s390_virtio_hypercall(env, env->regs[2], env->regs[1]);
+ env->regs[2] = s390_virtio_hypercall(env);
return 0;
}
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index 3015bfe3f2..09301d0a6f 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -70,6 +70,87 @@ void HELPER(exception)(CPUS390XState *env, uint32_t excp)
}
#ifndef CONFIG_USER_ONLY
+
+/* EBCDIC handling */
+static const uint8_t ebcdic2ascii[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
+ 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
+ 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
+ 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
+ 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
+ 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
+ 0x87, 0xA4, 0x5B, 0x2E, 0x3C, 0x28, 0x2B, 0x21,
+ 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
+ 0x8D, 0xE1, 0x5D, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
+ 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
+ 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
+ 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
+ 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
+ 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
+ 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
+ 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
+ 0x9B, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
+ 0xAB, 0x07, 0xAA, 0x7C, 0x07, 0x07, 0x07, 0x07,
+ 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
+ 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
+ 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
+ 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07,
+};
+
+static const uint8_t ascii2ebcdic[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
+ 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
+ 0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F,
+ 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
+ 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
+ 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+ 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+ 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
+ 0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D,
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+ 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF
+};
+
+static inline void ebcdic_put(uint8_t *p, const char *ascii, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ p[i] = ascii2ebcdic[(uint8_t)ascii[i]];
+ }
+}
+
void program_interrupt(CPUS390XState *env, uint32_t code, int ilen)
{
qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n",
@@ -107,7 +188,7 @@ uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
switch (num) {
case 0x500:
/* KVM hypercall */
- r = s390_virtio_hypercall(env, mem, code);
+ r = s390_virtio_hypercall(env);
break;
case 0x44:
/* yield */
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index c3ac85e054..d9c33d850f 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -1145,7 +1145,7 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
/* We assume that the offset is contained within 20 bits. */
tlb_offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_read);
- assert(tlb_offset & ~0xfffff == 0);
+ assert((tlb_offset & ~0xfffff) == 0);
if (tlb_offset > 0xfff) {
tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0,
0xa00 | (tlb_offset >> 12));
@@ -1354,7 +1354,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
TCG_AREG0, TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
/* We assume that the offset is contained within 20 bits. */
tlb_offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_write);
- assert(tlb_offset & ~0xfffff == 0);
+ assert((tlb_offset & ~0xfffff) == 0);
if (tlb_offset > 0xfff) {
tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0,
0xa00 | (tlb_offset >> 12));
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 9109b813e0..973d2d679f 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -46,6 +46,7 @@ struct tcg_temp_info {
uint16_t prev_copy;
uint16_t next_copy;
tcg_target_ulong val;
+ tcg_target_ulong mask;
};
static struct tcg_temp_info temps[TCG_MAX_TEMPS];
@@ -63,6 +64,17 @@ static void reset_temp(TCGArg temp)
}
}
temps[temp].state = TCG_TEMP_UNDEF;
+ temps[temp].mask = -1;
+}
+
+/* Reset all temporaries, given that there are NB_TEMPS of them. */
+static void reset_all_temps(int nb_temps)
+{
+ int i;
+ for (i = 0; i < nb_temps; i++) {
+ temps[i].state = TCG_TEMP_UNDEF;
+ temps[i].mask = -1;
+ }
}
static int op_bits(TCGOpcode op)
@@ -139,33 +151,35 @@ static bool temps_are_copies(TCGArg arg1, TCGArg arg2)
static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args,
TCGArg dst, TCGArg src)
{
- reset_temp(dst);
- assert(temps[src].state != TCG_TEMP_CONST);
-
- if (s->temps[src].type == s->temps[dst].type) {
- if (temps[src].state != TCG_TEMP_COPY) {
- temps[src].state = TCG_TEMP_COPY;
- temps[src].next_copy = src;
- temps[src].prev_copy = src;
- }
- temps[dst].state = TCG_TEMP_COPY;
- temps[dst].next_copy = temps[src].next_copy;
- temps[dst].prev_copy = src;
- temps[temps[dst].next_copy].prev_copy = dst;
- temps[src].next_copy = dst;
+ reset_temp(dst);
+ temps[dst].mask = temps[src].mask;
+ assert(temps[src].state != TCG_TEMP_CONST);
+
+ if (s->temps[src].type == s->temps[dst].type) {
+ if (temps[src].state != TCG_TEMP_COPY) {
+ temps[src].state = TCG_TEMP_COPY;
+ temps[src].next_copy = src;
+ temps[src].prev_copy = src;
}
+ temps[dst].state = TCG_TEMP_COPY;
+ temps[dst].next_copy = temps[src].next_copy;
+ temps[dst].prev_copy = src;
+ temps[temps[dst].next_copy].prev_copy = dst;
+ temps[src].next_copy = dst;
+ }
- gen_args[0] = dst;
- gen_args[1] = src;
+ gen_args[0] = dst;
+ gen_args[1] = src;
}
static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val)
{
- reset_temp(dst);
- temps[dst].state = TCG_TEMP_CONST;
- temps[dst].val = val;
- gen_args[0] = dst;
- gen_args[1] = val;
+ reset_temp(dst);
+ temps[dst].state = TCG_TEMP_CONST;
+ temps[dst].val = val;
+ temps[dst].mask = val;
+ gen_args[0] = dst;
+ gen_args[1] = val;
}
static TCGOpcode op_to_mov(TCGOpcode op)
@@ -470,6 +484,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
TCGArg *args, TCGOpDef *tcg_op_defs)
{
int i, nb_ops, op_index, nb_temps, nb_globals, nb_call_args;
+ tcg_target_ulong mask, affected;
TCGOpcode op;
const TCGOpDef *def;
TCGArg *gen_args;
@@ -482,7 +497,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
nb_temps = s->nb_temps;
nb_globals = s->nb_globals;
- memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+ reset_all_temps(nb_temps);
nb_ops = tcg_opc_ptr - s->gen_opc_buf;
gen_args = args;
@@ -612,6 +627,113 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
break;
}
+ /* Simplify using known-zero bits */
+ mask = -1;
+ affected = -1;
+ switch (op) {
+ CASE_OP_32_64(ext8s):
+ if ((temps[args[1]].mask & 0x80) != 0) {
+ break;
+ }
+ CASE_OP_32_64(ext8u):
+ mask = 0xff;
+ goto and_const;
+ CASE_OP_32_64(ext16s):
+ if ((temps[args[1]].mask & 0x8000) != 0) {
+ break;
+ }
+ CASE_OP_32_64(ext16u):
+ mask = 0xffff;
+ goto and_const;
+ case INDEX_op_ext32s_i64:
+ if ((temps[args[1]].mask & 0x80000000) != 0) {
+ break;
+ }
+ case INDEX_op_ext32u_i64:
+ mask = 0xffffffffU;
+ goto and_const;
+
+ CASE_OP_32_64(and):
+ mask = temps[args[2]].mask;
+ if (temps[args[2]].state == TCG_TEMP_CONST) {
+ and_const:
+ affected = temps[args[1]].mask & ~mask;
+ }
+ mask = temps[args[1]].mask & mask;
+ break;
+
+ CASE_OP_32_64(sar):
+ if (temps[args[2]].state == TCG_TEMP_CONST) {
+ mask = ((tcg_target_long)temps[args[1]].mask
+ >> temps[args[2]].val);
+ }
+ break;
+
+ CASE_OP_32_64(shr):
+ if (temps[args[2]].state == TCG_TEMP_CONST) {
+ mask = temps[args[1]].mask >> temps[args[2]].val;
+ }
+ break;
+
+ CASE_OP_32_64(shl):
+ if (temps[args[2]].state == TCG_TEMP_CONST) {
+ mask = temps[args[1]].mask << temps[args[2]].val;
+ }
+ break;
+
+ CASE_OP_32_64(neg):
+ /* Set to 1 all bits to the left of the rightmost. */
+ mask = -(temps[args[1]].mask & -temps[args[1]].mask);
+ break;
+
+ CASE_OP_32_64(deposit):
+ tmp = ((1ull << args[4]) - 1);
+ mask = ((temps[args[1]].mask & ~(tmp << args[3]))
+ | ((temps[args[2]].mask & tmp) << args[3]));
+ break;
+
+ CASE_OP_32_64(or):
+ CASE_OP_32_64(xor):
+ mask = temps[args[1]].mask | temps[args[2]].mask;
+ break;
+
+ CASE_OP_32_64(setcond):
+ mask = 1;
+ break;
+
+ CASE_OP_32_64(movcond):
+ mask = temps[args[3]].mask | temps[args[4]].mask;
+ break;
+
+ default:
+ break;
+ }
+
+ if (mask == 0) {
+ assert(def->nb_oargs == 1);
+ s->gen_opc_buf[op_index] = op_to_movi(op);
+ tcg_opt_gen_movi(gen_args, args[0], 0);
+ args += def->nb_oargs + def->nb_iargs + def->nb_cargs;
+ gen_args += 2;
+ continue;
+ }
+ if (affected == 0) {
+ assert(def->nb_oargs == 1);
+ if (temps_are_copies(args[0], args[1])) {
+ s->gen_opc_buf[op_index] = INDEX_op_nop;
+ } else if (temps[args[1]].state != TCG_TEMP_CONST) {
+ s->gen_opc_buf[op_index] = op_to_mov(op);
+ tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
+ gen_args += 2;
+ } else {
+ s->gen_opc_buf[op_index] = op_to_movi(op);
+ tcg_opt_gen_movi(gen_args, args[0], temps[args[1]].val);
+ gen_args += 2;
+ }
+ args += def->nb_iargs + 1;
+ continue;
+ }
+
/* Simplify expression for "op r, a, 0 => movi r, 0" cases */
switch (op) {
CASE_OP_32_64(and):
@@ -768,7 +890,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
tmp = do_constant_folding_cond(op, args[0], args[1], args[2]);
if (tmp != 2) {
if (tmp) {
- memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+ reset_all_temps(nb_temps);
s->gen_opc_buf[op_index] = INDEX_op_br;
gen_args[0] = args[3];
gen_args += 1;
@@ -861,7 +983,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
tmp = do_constant_folding_cond2(&args[0], &args[2], args[4]);
if (tmp != 2) {
if (tmp) {
- memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+ reset_all_temps(nb_temps);
s->gen_opc_buf[op_index] = INDEX_op_br;
gen_args[0] = args[5];
gen_args += 1;
@@ -875,7 +997,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
&& temps[args[3]].val == 0) {
/* Simplify LT/GE comparisons vs zero to a single compare
vs the high word of the input. */
- memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+ reset_all_temps(nb_temps);
s->gen_opc_buf[op_index] = INDEX_op_brcond_i32;
gen_args[0] = args[1];
gen_args[1] = args[3];
@@ -938,9 +1060,10 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
/* Default case: we know nothing about operation (or were unable
to compute the operation result) so no propagation is done.
We trash everything if the operation is the end of a basic
- block, otherwise we only trash the output args. */
+ block, otherwise we only trash the output args. "mask" is
+ the non-zero bits mask for the first output arg. */
if (def->flags & TCG_OPF_BB_END) {
- memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+ reset_all_temps(nb_temps);
} else {
for (i = 0; i < def->nb_oargs; i++) {
reset_temp(args[i]);
diff --git a/trace-events b/trace-events
index 6eabbac0cc..7de9106664 100644
--- a/trace-events
+++ b/trace-events
@@ -167,6 +167,13 @@ ecc_mem_readl_ecr1(uint32_t ret) "Read event count 2 %08x"
ecc_diag_mem_writeb(uint64_t addr, uint32_t val) "Write diagnostic %"PRId64" = %02x"
ecc_diag_mem_readb(uint64_t addr, uint32_t ret) "Read diagnostic %"PRId64"= %02x"
+# hw/fw_cfg.c
+fw_cfg_write(void *s, uint8_t value) "%p %d"
+fw_cfg_select(void *s, uint16_t key, int ret) "%p key %d = %d"
+fw_cfg_read(void *s, uint8_t ret) "%p = %d"
+fw_cfg_add_file_dupe(void *s, char *name) "%p %s"
+fw_cfg_add_file(void *s, int index, char *name, size_t len) "%p #%d: %s (%zd bytes)"
+
# hw/hd-geometry.c
hd_geometry_lchs_guess(void *bs, int cyls, int heads, int secs) "bs %p LCHS %d %d %d"
hd_geometry_guess(void *bs, uint32_t cyls, uint32_t heads, uint32_t secs, int trans) "bs %p CHS %u %u %u trans %d"
diff --git a/util/path.c b/util/path.c
index 4c5b0f6296..f0c69627c7 100644
--- a/util/path.c
+++ b/util/path.c
@@ -47,10 +47,7 @@ static struct pathelem *new_entry(const char *root,
{
struct pathelem *new = malloc(sizeof(*new));
new->name = strdup(name);
- if (asprintf(&new->pathname, "%s/%s", root, name) == -1) {
- printf("Cannot allocate memory\n");
- exit(1);
- }
+ new->pathname = g_strdup_printf("%s/%s", root, name);
new->num_entries = 0;
return new;
}
diff --git a/vl.c b/vl.c
index 8ce2b10541..4ee1302595 100644
--- a/vl.c
+++ b/vl.c
@@ -1198,15 +1198,15 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev,
* memory pointed by "size" is assigned total length of the array in bytes
*
*/
-char *get_boot_devices_list(uint32_t *size)
+char *get_boot_devices_list(size_t *size)
{
FWBootEntry *i;
- uint32_t total = 0;
+ size_t total = 0;
char *list = NULL;
QTAILQ_FOREACH(i, &fw_boot_order, link) {
char *devpath = NULL, *bootpath;
- int len;
+ size_t len;
if (i->dev) {
devpath = qdev_get_fw_dev_path(i->dev);
@@ -1449,7 +1449,7 @@ void pcmcia_socket_unregister(PCMCIASocket *socket)
}
}
-void pcmcia_info(Monitor *mon)
+void pcmcia_info(Monitor *mon, const QDict *qdict)
{
struct pcmcia_socket_entry_s *iter;