diff options
667 files changed, 5262 insertions, 2346 deletions
diff --git a/arch_init.c b/arch_init.c index f6aba02cb2..e3bb1b3ac4 100644 --- a/arch_init.c +++ b/arch_init.c @@ -31,6 +31,7 @@ #include "qemu/error-report.h" #include "qmp-commands.h" #include "hw/acpi/acpi.h" +#include "qemu/help_option.h" #ifdef TARGET_SPARC int graphic_width = 1024; @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "block/aio.h" #include "block/thread-pool.h" diff --git a/audio/audio.c b/audio/audio.c index e84153293c..e60c124de8 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -27,6 +27,7 @@ #include "monitor/monitor.h" #include "qemu/timer.h" #include "sysemu/sysemu.h" +#include "qemu/cutils.h" #define AUDIO_CAP "audio" #include "audio_int.h" @@ -1869,8 +1870,7 @@ static void audio_init (void) } conf.period.ticks = 1; } else { - conf.period.ticks = - muldiv64 (1, get_ticks_per_sec (), conf.period.hertz); + conf.period.ticks = NANOSECONDS_PER_SECOND / conf.period.hertz; } e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s); diff --git a/audio/noaudio.c b/audio/noaudio.c index 09588b9cd0..b360c199ac 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -49,8 +49,8 @@ static int no_run_out (HWVoiceOut *hw, int live) now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ticks = now - no->old_ticks; - bytes = muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ()); - bytes = audio_MIN (bytes, INT_MAX); + bytes = muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); + bytes = audio_MIN(bytes, INT_MAX); samples = bytes >> hw->info.shift; no->old_ticks = now; @@ -61,7 +61,7 @@ static int no_run_out (HWVoiceOut *hw, int live) static int no_write (SWVoiceOut *sw, void *buf, int len) { - return audio_pcm_sw_write (sw, buf, len); + return audio_pcm_sw_write(sw, buf, len); } static int no_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) @@ -106,7 +106,7 @@ static int no_run_in (HWVoiceIn *hw) int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); int64_t ticks = now - no->old_ticks; int64_t bytes = - muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ()); + muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); no->old_ticks = now; bytes = audio_MIN (bytes, INT_MAX); diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index 297fd416ed..dea71d37af 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -104,11 +104,11 @@ static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate) now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ticks = now - rate->start_ticks; - bytes = muldiv64 (ticks, info->bytes_per_second, get_ticks_per_sec ()); + bytes = muldiv64(ticks, info->bytes_per_second, NANOSECONDS_PER_SECOND); samples = (bytes - rate->bytes_sent) >> info->shift; if (samples < 0 || samples > 65536) { error_report("Resetting rate control (%" PRId64 " samples)", samples); - rate_start (rate); + rate_start(rate); samples = 0; } rate->bytes_sent += samples << info->shift; diff --git a/audio/wavaudio.c b/audio/wavaudio.c index 343b1a10b9..345952e51e 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -51,7 +51,7 @@ static int wav_run_out (HWVoiceOut *hw, int live) int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); int64_t ticks = now - wav->old_ticks; int64_t bytes = - muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ()); + muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); if (bytes > INT_MAX) { samples = INT_MAX >> hw->info.shift; diff --git a/backends/baum.c b/backends/baum.c index eef3467c9f..c537141b22 100644 --- a/backends/baum.c +++ b/backends/baum.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "sysemu/char.h" #include "qemu/timer.h" @@ -336,7 +337,7 @@ static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len) /* Allow 100ms to complete the DisplayData packet */ timer_mod(baum->cellCount_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - get_ticks_per_sec() / 10); + NANOSECONDS_PER_SECOND / 10); for (i = 0; i < baum->x * baum->y ; i++) { EAT(c); cells[i] = c; diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c index fd59482693..c70f268d6f 100644 --- a/backends/hostmem-file.c +++ b/backends/hostmem-file.c @@ -10,6 +10,7 @@ * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "sysemu/hostmem.h" #include "sysemu/sysemu.h" diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c index 44fb3902b8..04a7ac362b 100644 --- a/backends/hostmem-ram.c +++ b/backends/hostmem-ram.c @@ -11,6 +11,7 @@ */ #include "qemu/osdep.h" #include "sysemu/hostmem.h" +#include "qapi/error.h" #include "qom/object_interfaces.h" #define TYPE_MEMORY_BACKEND_RAM "memory-backend-ram" diff --git a/backends/hostmem.c b/backends/hostmem.c index 6c6f0da6d9..6e28be11eb 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -12,6 +12,7 @@ #include "qemu/osdep.h" #include "sysemu/hostmem.h" #include "hw/boards.h" +#include "qapi/error.h" #include "qapi/visitor.h" #include "qapi-types.h" #include "qapi-visit.h" diff --git a/backends/rng-egd.c b/backends/rng-egd.c index 6e0ba22241..7a1b9242d8 100644 --- a/backends/rng-egd.c +++ b/backends/rng-egd.c @@ -13,6 +13,7 @@ #include "qemu/osdep.h" #include "sysemu/rng.h" #include "sysemu/char.h" +#include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "hw/qdev.h" /* just for DEFINE_PROP_CHR */ diff --git a/backends/rng-random.c b/backends/rng-random.c index 122e8d494d..2e44e25190 100644 --- a/backends/rng-random.c +++ b/backends/rng-random.c @@ -13,6 +13,7 @@ #include "qemu/osdep.h" #include "sysemu/rng-random.h" #include "sysemu/rng.h" +#include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "qemu/main-loop.h" diff --git a/backends/rng.c b/backends/rng.c index e57e2b4b52..398ebe4a7d 100644 --- a/backends/rng.c +++ b/backends/rng.c @@ -12,6 +12,7 @@ #include "qemu/osdep.h" #include "sysemu/rng.h" +#include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "qom/object_interfaces.h" diff --git a/backends/tpm.c b/backends/tpm.c index d53da18627..536f262bb7 100644 --- a/backends/tpm.c +++ b/backends/tpm.c @@ -14,6 +14,7 @@ #include "qemu/osdep.h" #include "sysemu/tpm_backend.h" +#include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "sysemu/tpm.h" #include "qemu/thread.h" @@ -22,7 +22,6 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" -#include "qemu-common.h" #include "trace.h" #include "block/block_int.h" #include "block/blockjob.h" @@ -40,6 +39,8 @@ #include "qemu/timer.h" #include "qapi-event.h" #include "block/throttle-groups.h" +#include "qemu/cutils.h" +#include "qemu/id.h" #ifdef CONFIG_BSD #include <sys/ioctl.h> diff --git a/block/archipelago.c b/block/archipelago.c index 0507589063..b9f5e69d4a 100644 --- a/block/archipelago.c +++ b/block/archipelago.c @@ -51,7 +51,7 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qemu/cutils.h" #include "block/block_int.h" #include "qemu/error-report.h" #include "qemu/thread.h" diff --git a/block/backup.c b/block/backup.c index ab3e345e92..9170983ba9 100644 --- a/block/backup.c +++ b/block/backup.c @@ -17,8 +17,10 @@ #include "block/block.h" #include "block/block_int.h" #include "block/blockjob.h" +#include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "qemu/ratelimit.h" +#include "qemu/cutils.h" #include "sysemu/block-backend.h" #include "qemu/bitmap.h" diff --git a/block/blkdebug.c b/block/blkdebug.c index f85c54bdc8..20d25bda67 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -23,7 +23,8 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qapi/error.h" +#include "qemu/cutils.h" #include "qemu/config-file.h" #include "block/block_int.h" #include "qemu/module.h" diff --git a/block/blkverify.c b/block/blkverify.c index 2a885cc08d..9414b7a84e 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -8,10 +8,12 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu/sockets.h" /* for EINPROGRESS on Windows */ #include "block/block_int.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qstring.h" +#include "qemu/cutils.h" typedef struct { BdrvChild *test_file; diff --git a/block/block-backend.c b/block/block-backend.c index dca21d1eeb..adf592e867 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -18,6 +18,7 @@ #include "sysemu/blockdev.h" #include "sysemu/sysemu.h" #include "qapi-event.h" +#include "qemu/id.h" /* Number of coroutines to reserve per attached device model */ #define COROUTINE_POOL_RESERVATION 64 diff --git a/block/bochs.c b/block/bochs.c index 8b953bb44c..af8b7abdfd 100644 --- a/block/bochs.c +++ b/block/bochs.c @@ -23,6 +23,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "block/block_int.h" #include "qemu/module.h" diff --git a/block/cloop.c b/block/cloop.c index 41bdee8d7f..a84f14019c 100644 --- a/block/cloop.c +++ b/block/cloop.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "block/block_int.h" #include "qemu/module.h" diff --git a/block/commit.c b/block/commit.c index 446a3aeadd..cba0e8c1e8 100644 --- a/block/commit.c +++ b/block/commit.c @@ -16,6 +16,7 @@ #include "trace.h" #include "block/block_int.h" #include "block/blockjob.h" +#include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "qemu/ratelimit.h" #include "sysemu/block-backend.h" diff --git a/block/curl.c b/block/curl.c index c70bfb404d..5a8f8b6239 100644 --- a/block/curl.c +++ b/block/curl.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/error-report.h" #include "block/block_int.h" @@ -29,6 +30,7 @@ #include "qapi/qmp/qstring.h" #include "crypto/secret.h" #include <curl/curl.h> +#include "qemu/cutils.h" // #define DEBUG_CURL // #define DEBUG_VERBOSE diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c index 556e1d15c4..4902ca557f 100644 --- a/block/dirty-bitmap.c +++ b/block/dirty-bitmap.c @@ -22,7 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" -#include "config-host.h" +#include "qapi/error.h" #include "qemu-common.h" #include "trace.h" #include "block/block_int.h" diff --git a/block/dmg.c b/block/dmg.c index 1018fd158e..a496eb7c9b 100644 --- a/block/dmg.c +++ b/block/dmg.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "block/block_int.h" #include "qemu/bswap.h" diff --git a/block/gluster.c b/block/gluster.c index 65077a0d0a..51e154c247 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -10,6 +10,7 @@ #include "qemu/osdep.h" #include <glusterfs/api/glfs.h> #include "block/block_int.h" +#include "qapi/error.h" #include "qemu/uri.h" typedef struct GlusterAIOCB { diff --git a/block/io.c b/block/io.c index 41d954cad2..c2611e53c8 100644 --- a/block/io.c +++ b/block/io.c @@ -28,6 +28,8 @@ #include "block/blockjob.h" #include "block/block_int.h" #include "block/throttle-groups.h" +#include "qemu/cutils.h" +#include "qapi/error.h" #include "qemu/error-report.h" #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ diff --git a/block/mirror.c b/block/mirror.c index 9635fa8e62..7bfd0d2996 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -16,6 +16,7 @@ #include "block/blockjob.h" #include "block/block_int.h" #include "sysemu/block-backend.h" +#include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "qemu/ratelimit.h" #include "qemu/bitmap.h" diff --git a/block/nbd.c b/block/nbd.c index 836424c88c..896064a131 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -28,6 +28,7 @@ #include "qemu/osdep.h" #include "block/nbd-client.h" +#include "qapi/error.h" #include "qemu/uri.h" #include "block/block_int.h" #include "qemu/module.h" @@ -35,7 +36,7 @@ #include "qapi/qmp/qjson.h" #include "qapi/qmp/qint.h" #include "qapi/qmp/qstring.h" - +#include "qemu/cutils.h" #define EN_OPTSTR ":exportname=" diff --git a/block/null.c b/block/null.c index d90165dea7..00bc6e478a 100644 --- a/block/null.c +++ b/block/null.c @@ -11,6 +11,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "block/block_int.h" #define NULL_OPT_LATENCY "latency-ns" diff --git a/block/parallels.c b/block/parallels.c index b322d05c08..9bba8b3d06 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -28,6 +28,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "block/block_int.h" #include "sysemu/block-backend.h" diff --git a/block/qapi.c b/block/qapi.c index 6a4869a8d9..089614ee9d 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -32,6 +32,7 @@ #include "qapi/qmp-output-visitor.h" #include "qapi/qmp/types.h" #include "sysemu/block-backend.h" +#include "qemu/cutils.h" BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs, Error **errp) { diff --git a/block/qcow.c b/block/qcow.c index 73cf8a7081..8ea8e5ceef 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "block/block_int.h" #include "sysemu/block-backend.h" diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 3e887e9ab0..31ecc10304 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include <zlib.h> +#include "qapi/error.h" #include "qemu-common.h" #include "block/block_int.h" #include "block/qcow2.h" diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 52a0a9ffc3..ca6094ff5b 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "block/block_int.h" #include "block/qcow2.h" diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 13f88d1b8b..5f4a17e473 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -23,10 +23,11 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qapi/error.h" #include "block/block_int.h" #include "block/qcow2.h" #include "qemu/error-report.h" +#include "qemu/cutils.h" void qcow2_free_snapshots(BlockDriverState *bs) { diff --git a/block/qcow2.c b/block/qcow2.c index cec5bd02f2..642802971c 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -22,7 +22,6 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" -#include "qemu-common.h" #include "block/block_int.h" #include "sysemu/block-backend.h" #include "qemu/module.h" @@ -36,6 +35,7 @@ #include "qapi-event.h" #include "trace.h" #include "qemu/option_int.h" +#include "qemu/cutils.h" /* Differences with QCOW: diff --git a/block/qed.c b/block/qed.c index 5b24a9783f..c1cc625d55 100644 --- a/block/qed.c +++ b/block/qed.c @@ -13,6 +13,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "trace.h" #include "qed.h" @@ -346,7 +347,7 @@ static void qed_start_need_check_timer(BDRVQEDState *s) * migration. */ timer_mod(s->need_check_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - get_ticks_per_sec() * QED_NEED_CHECK_TIMEOUT); + NANOSECONDS_PER_SECOND * QED_NEED_CHECK_TIMEOUT); } /* It's okay to call this multiple times or when no timer is started */ diff --git a/block/qed.h b/block/qed.h index 615e676fc8..22b3198751 100644 --- a/block/qed.h +++ b/block/qed.h @@ -16,6 +16,7 @@ #define BLOCK_QED_H #include "block/block_int.h" +#include "qemu/cutils.h" /* The layout of a QED file is as follows: * diff --git a/block/raw-aio.h b/block/raw-aio.h index 31d791fe67..811e375018 100644 --- a/block/raw-aio.h +++ b/block/raw-aio.h @@ -15,6 +15,8 @@ #ifndef QEMU_RAW_AIO_H #define QEMU_RAW_AIO_H +#include "qemu/iov.h" + /* AIO request types */ #define QEMU_AIO_READ 0x0001 #define QEMU_AIO_WRITE 0x0002 diff --git a/block/raw-posix.c b/block/raw-posix.c index 8866121cf7..c8e2ec40fb 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -22,7 +22,8 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qapi/error.h" +#include "qemu/cutils.h" #include "qemu/error-report.h" #include "qemu/timer.h" #include "qemu/log.h" diff --git a/block/raw-win32.c b/block/raw-win32.c index 21a6cb89d7..fd23891534 100644 --- a/block/raw-win32.c +++ b/block/raw-win32.c @@ -22,7 +22,8 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qapi/error.h" +#include "qemu/cutils.h" #include "qemu/timer.h" #include "block/block_int.h" #include "qemu/module.h" diff --git a/block/raw_bsd.c b/block/raw_bsd.c index ea16a231c0..41dddf8db3 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -28,6 +28,7 @@ #include "qemu/osdep.h" #include "block/block_int.h" +#include "qapi/error.h" #include "qemu/option.h" static QemuOptsList raw_create_opts = { diff --git a/block/rbd.c b/block/rbd.c index abfea612ec..5bc5b32530 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -13,10 +13,11 @@ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qapi/error.h" #include "qemu/error-report.h" #include "block/block_int.h" #include "crypto/secret.h" +#include "qemu/cutils.h" #include <rbd/librbd.h> diff --git a/block/sheepdog.c b/block/sheepdog.c index a3aeae4a67..48fc165422 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -13,13 +13,14 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qapi/error.h" #include "qemu/uri.h" #include "qemu/error-report.h" #include "qemu/sockets.h" #include "block/block_int.h" #include "sysemu/block-backend.h" #include "qemu/bitops.h" +#include "qemu/cutils.h" #define SD_PROTO_VER 0x01 diff --git a/block/snapshot.c b/block/snapshot.c index 17a27b57ad..e9d721df68 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include "block/snapshot.h" #include "block/block_int.h" +#include "qapi/error.h" #include "qapi/qmp/qerror.h" QemuOptsList internal_snapshot_opts = { diff --git a/block/ssh.c b/block/ssh.c index 04deeba1ad..06928ed939 100644 --- a/block/ssh.c +++ b/block/ssh.c @@ -28,6 +28,7 @@ #include <libssh2_sftp.h> #include "block/block_int.h" +#include "qapi/error.h" #include "qemu/error-report.h" #include "qemu/sockets.h" #include "qemu/uri.h" diff --git a/block/stream.c b/block/stream.c index cafaa07a01..9b0b0f3573 100644 --- a/block/stream.c +++ b/block/stream.c @@ -15,6 +15,7 @@ #include "trace.h" #include "block/block_int.h" #include "block/blockjob.h" +#include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "qemu/ratelimit.h" #include "sysemu/block-backend.h" diff --git a/block/vdi.c b/block/vdi.c index df9fa47db1..71f417c461 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -50,12 +50,13 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qapi/error.h" #include "block/block_int.h" #include "sysemu/block-backend.h" #include "qemu/module.h" #include "migration/migration.h" #include "qemu/coroutine.h" +#include "qemu/cutils.h" #if defined(CONFIG_UUID) #include <uuid/uuid.h> diff --git a/block/vhdx-log.c b/block/vhdx-log.c index 369076126e..7ea7187fc4 100644 --- a/block/vhdx-log.c +++ b/block/vhdx-log.c @@ -18,6 +18,7 @@ * */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "block/block_int.h" #include "qemu/error-report.h" diff --git a/block/vhdx.c b/block/vhdx.c index 78fe56ca04..59426d6c0f 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -16,6 +16,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "block/block_int.h" #include "sysemu/block-backend.h" diff --git a/block/vmdk.c b/block/vmdk.c index 29c8fc3d02..a1a9371bf8 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -24,13 +24,14 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qapi/error.h" #include "block/block_int.h" #include "sysemu/block-backend.h" #include "qapi/qmp/qerror.h" #include "qemu/error-report.h" #include "qemu/module.h" #include "migration/migration.h" +#include "qemu/cutils.h" #include <zlib.h> #include <glib.h> diff --git a/block/vpc.c b/block/vpc.c index 8435205a0c..912dfc1a82 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -23,6 +23,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "block/block_int.h" #include "sysemu/block-backend.h" diff --git a/block/vvfat.c b/block/vvfat.c index b8d29e17cd..eb1126cbad 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -24,13 +24,14 @@ */ #include "qemu/osdep.h" #include <dirent.h> -#include "qemu-common.h" +#include "qapi/error.h" #include "block/block_int.h" #include "qemu/module.h" #include "migration/migration.h" #include "qapi/qmp/qint.h" #include "qapi/qmp/qbool.h" #include "qapi/qmp/qstring.h" +#include "qemu/cutils.h" #ifndef S_IWGRP #define S_IWGRP 0 diff --git a/blockdev.c b/blockdev.c index 24c886142a..3eb05d1a90 100644 --- a/blockdev.c +++ b/blockdev.c @@ -50,6 +50,8 @@ #include "qmp-commands.h" #include "trace.h" #include "sysemu/arch_init.h" +#include "qemu/cutils.h" +#include "qemu/help_option.h" static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states = QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states); diff --git a/bootdevice.c b/bootdevice.c index dbc0159392..2e83ff05eb 100644 --- a/bootdevice.c +++ b/bootdevice.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "sysemu/sysemu.h" #include "qapi/visitor.h" #include "qemu/error-report.h" diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c index 0a6092bdf7..898ee05472 100644 --- a/bsd-user/elfload.c +++ b/bsd-user/elfload.c @@ -5,6 +5,7 @@ #include "qemu.h" #include "disas/disas.h" +#include "qemu/path.h" #ifdef _ARCH_PPC64 #undef ARCH_DLINFO diff --git a/bsd-user/main.c b/bsd-user/main.c index 287ec1d369..27854c1f91 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -21,7 +21,8 @@ #include <sys/mman.h> #include "qemu.h" -#include "qemu-common.h" +#include "qemu/path.h" +#include "qemu/help_option.h" /* For tb_lock */ #include "cpu.h" #include "tcg.h" @@ -2836,7 +2836,7 @@ fi # curses probe if test "$curses" != "no" ; then if test "$mingw32" = "yes" ; then - curses_list="-lpdcurses" + curses_list="$($pkg_config --libs ncurses 2>/dev/null):-lpdcurses" else curses_list="$($pkg_config --libs ncurses 2>/dev/null):-lncurses:-lcurses" fi @@ -5942,7 +5942,7 @@ cat <<EOD >config.status EOD printf "exec" >>config.status printf " '%s'" "$0" "$@" >>config.status -echo >>config.status +echo ' "$@"' >>config.status chmod +x config.status rm -r "$TMPDIR1" diff --git a/contrib/ivshmem-server/ivshmem-server.c b/contrib/ivshmem-server/ivshmem-server.c index bfd0fad49a..172db78b37 100644 --- a/contrib/ivshmem-server/ivshmem-server.c +++ b/contrib/ivshmem-server/ivshmem-server.c @@ -12,9 +12,6 @@ #include <sys/mman.h> #include <sys/socket.h> #include <sys/un.h> -#ifdef CONFIG_LINUX -#include <sys/vfs.h> -#endif #include "ivshmem-server.h" @@ -257,7 +254,8 @@ ivshmem_server_ftruncate(int fd, unsigned shmsize) /* Init a new ivshmem server */ int ivshmem_server_init(IvshmemServer *server, const char *unix_sock_path, - const char *shm_path, size_t shm_size, unsigned n_vectors, + const char *shm_path, bool use_shm_open, + size_t shm_size, unsigned n_vectors, bool verbose) { int ret; @@ -278,6 +276,7 @@ ivshmem_server_init(IvshmemServer *server, const char *unix_sock_path, return -1; } + server->use_shm_open = use_shm_open; server->shm_size = shm_size; server->n_vectors = n_vectors; @@ -286,31 +285,6 @@ ivshmem_server_init(IvshmemServer *server, const char *unix_sock_path, return 0; } -#ifdef CONFIG_LINUX - -#define HUGETLBFS_MAGIC 0x958458f6 - -static long gethugepagesize(const char *path) -{ - struct statfs fs; - int ret; - - do { - ret = statfs(path, &fs); - } while (ret != 0 && errno == EINTR); - - if (ret != 0) { - return -1; - } - - if (fs.f_type != HUGETLBFS_MAGIC) { - return -1; - } - - return fs.f_bsize; -} -#endif - /* open shm, create and bind to the unix socket */ int ivshmem_server_start(IvshmemServer *server) @@ -319,27 +293,17 @@ ivshmem_server_start(IvshmemServer *server) int shm_fd, sock_fd, ret; /* open shm file */ -#ifdef CONFIG_LINUX - long hpagesize; - - hpagesize = gethugepagesize(server->shm_path); - if (hpagesize < 0 && errno != ENOENT) { - IVSHMEM_SERVER_DEBUG(server, "cannot stat shm file %s: %s\n", - server->shm_path, strerror(errno)); - } - - if (hpagesize > 0) { + if (server->use_shm_open) { + IVSHMEM_SERVER_DEBUG(server, "Using POSIX shared memory: %s\n", + server->shm_path); + shm_fd = shm_open(server->shm_path, O_CREAT | O_RDWR, S_IRWXU); + } else { gchar *filename = g_strdup_printf("%s/ivshmem.XXXXXX", server->shm_path); - IVSHMEM_SERVER_DEBUG(server, "Using hugepages: %s\n", server->shm_path); + IVSHMEM_SERVER_DEBUG(server, "Using file-backed shared memory: %s\n", + server->shm_path); shm_fd = mkstemp(filename); unlink(filename); g_free(filename); - } else -#endif - { - IVSHMEM_SERVER_DEBUG(server, "Using POSIX shared memory: %s\n", - server->shm_path); - shm_fd = shm_open(server->shm_path, O_CREAT|O_RDWR, S_IRWXU); } if (shm_fd < 0) { diff --git a/contrib/ivshmem-server/ivshmem-server.h b/contrib/ivshmem-server/ivshmem-server.h index e9de8a369d..3851639618 100644 --- a/contrib/ivshmem-server/ivshmem-server.h +++ b/contrib/ivshmem-server/ivshmem-server.h @@ -66,6 +66,7 @@ typedef struct IvshmemServer { char unix_sock_path[PATH_MAX]; /**< path to unix socket */ int sock_fd; /**< unix sock file descriptor */ char shm_path[PATH_MAX]; /**< path to shm */ + bool use_shm_open; size_t shm_size; /**< size of shm */ int shm_fd; /**< shm file descriptor */ unsigned n_vectors; /**< number of vectors */ @@ -89,7 +90,8 @@ typedef struct IvshmemServer { */ int ivshmem_server_init(IvshmemServer *server, const char *unix_sock_path, - const char *shm_path, size_t shm_size, unsigned n_vectors, + const char *shm_path, bool use_shm_open, + size_t shm_size, unsigned n_vectors, bool verbose); /** diff --git a/contrib/ivshmem-server/main.c b/contrib/ivshmem-server/main.c index cca1061f0e..45776d8af4 100644 --- a/contrib/ivshmem-server/main.c +++ b/contrib/ivshmem-server/main.c @@ -7,7 +7,8 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qapi/error.h" +#include "qemu/cutils.h" #include "ivshmem-server.h" @@ -29,35 +30,38 @@ typedef struct IvshmemServerArgs { const char *pid_file; const char *unix_socket_path; const char *shm_path; + bool use_shm_open; uint64_t shm_size; unsigned n_vectors; } IvshmemServerArgs; -/* show ivshmem_server_usage and exit with given error code */ static void -ivshmem_server_usage(const char *name, int code) +ivshmem_server_usage(const char *progname) { - fprintf(stderr, "%s [opts]\n", name); - fprintf(stderr, " -h: show this help\n"); - fprintf(stderr, " -v: verbose mode\n"); - fprintf(stderr, " -F: foreground mode (default is to daemonize)\n"); - fprintf(stderr, " -p <pid_file>: path to the PID file (used in daemon\n" - " mode only).\n" - " Default=%s\n", IVSHMEM_SERVER_DEFAULT_SHM_PATH); - fprintf(stderr, " -S <unix_socket_path>: path to the unix socket\n" - " to listen to.\n" - " Default=%s\n", IVSHMEM_SERVER_DEFAULT_UNIX_SOCK_PATH); - fprintf(stderr, " -m <shm_path>: path to the shared memory.\n" - " The path corresponds to a POSIX shm name or a\n" - " hugetlbfs mount point.\n" - " default=%s\n", IVSHMEM_SERVER_DEFAULT_SHM_PATH); - fprintf(stderr, " -l <size>: size of shared memory in bytes. The suffix\n" - " K, M and G can be used (ex: 1K means 1024).\n" - " default=%u\n", IVSHMEM_SERVER_DEFAULT_SHM_SIZE); - fprintf(stderr, " -n <n_vects>: number of vectors.\n" - " default=%u\n", IVSHMEM_SERVER_DEFAULT_N_VECTORS); - - exit(code); + printf("Usage: %s [OPTION]...\n" + " -h: show this help\n" + " -v: verbose mode\n" + " -F: foreground mode (default is to daemonize)\n" + " -p <pid-file>: path to the PID file (used in daemon mode only)\n" + " default " IVSHMEM_SERVER_DEFAULT_PID_FILE "\n" + " -S <unix-socket-path>: path to the unix socket to listen to\n" + " default " IVSHMEM_SERVER_DEFAULT_UNIX_SOCK_PATH "\n" + " -M <shm-name>: POSIX shared memory object to use\n" + " default " IVSHMEM_SERVER_DEFAULT_SHM_PATH "\n" + " -m <dir-name>: where to create shared memory\n" + " -l <size>: size of shared memory in bytes\n" + " suffixes K, M and G can be used, e.g. 1K means 1024\n" + " default %u\n" + " -n <nvectors>: number of vectors\n" + " default %u\n", + progname, IVSHMEM_SERVER_DEFAULT_SHM_SIZE, + IVSHMEM_SERVER_DEFAULT_N_VECTORS); +} + +static void +ivshmem_server_help(const char *progname) +{ + fprintf(stderr, "Try '%s -h' for more information.\n", progname); } /* parse the program arguments, exit on error */ @@ -68,20 +72,12 @@ ivshmem_server_parse_args(IvshmemServerArgs *args, int argc, char *argv[]) unsigned long long v; Error *err = NULL; - while ((c = getopt(argc, argv, - "h" /* help */ - "v" /* verbose */ - "F" /* foreground */ - "p:" /* pid_file */ - "S:" /* unix_socket_path */ - "m:" /* shm_path */ - "l:" /* shm_size */ - "n:" /* n_vectors */ - )) != -1) { + while ((c = getopt(argc, argv, "hvFp:S:m:M:l:n:")) != -1) { switch (c) { case 'h': /* help */ - ivshmem_server_usage(argv[0], 0); + ivshmem_server_usage(argv[0]); + exit(0); break; case 'v': /* verbose */ @@ -92,36 +88,41 @@ ivshmem_server_parse_args(IvshmemServerArgs *args, int argc, char *argv[]) args->foreground = 1; break; - case 'p': /* pid_file */ + case 'p': /* pid file */ args->pid_file = optarg; break; - case 'S': /* unix_socket_path */ + case 'S': /* unix socket path */ args->unix_socket_path = optarg; break; - case 'm': /* shm_path */ + case 'M': /* shm name */ + case 'm': /* dir name */ args->shm_path = optarg; + args->use_shm_open = c == 'M'; break; - case 'l': /* shm_size */ + case 'l': /* shm size */ parse_option_size("shm_size", optarg, &args->shm_size, &err); if (err) { error_report_err(err); - ivshmem_server_usage(argv[0], 1); + ivshmem_server_help(argv[0]); + exit(1); } break; - case 'n': /* n_vectors */ + case 'n': /* number of vectors */ if (parse_uint_full(optarg, &v, 0) < 0) { fprintf(stderr, "cannot parse n_vectors\n"); - ivshmem_server_usage(argv[0], 1); + ivshmem_server_help(argv[0]); + exit(1); } args->n_vectors = v; break; default: - ivshmem_server_usage(argv[0], 1); + ivshmem_server_usage(argv[0]); + exit(1); break; } } @@ -129,12 +130,14 @@ ivshmem_server_parse_args(IvshmemServerArgs *args, int argc, char *argv[]) if (args->n_vectors > IVSHMEM_SERVER_MAX_VECTORS) { fprintf(stderr, "too many requested vectors (max is %d)\n", IVSHMEM_SERVER_MAX_VECTORS); - ivshmem_server_usage(argv[0], 1); + ivshmem_server_help(argv[0]); + exit(1); } if (args->verbose == 1 && args->foreground == 0) { fprintf(stderr, "cannot use verbose in daemon mode\n"); - ivshmem_server_usage(argv[0], 1); + ivshmem_server_help(argv[0]); + exit(1); } } @@ -192,11 +195,18 @@ main(int argc, char *argv[]) .pid_file = IVSHMEM_SERVER_DEFAULT_PID_FILE, .unix_socket_path = IVSHMEM_SERVER_DEFAULT_UNIX_SOCK_PATH, .shm_path = IVSHMEM_SERVER_DEFAULT_SHM_PATH, + .use_shm_open = true, .shm_size = IVSHMEM_SERVER_DEFAULT_SHM_SIZE, .n_vectors = IVSHMEM_SERVER_DEFAULT_N_VECTORS, }; int ret = 1; + /* + * Do not remove this notice without adding proper error handling! + * Start with handling ivshmem_server_send_one_msg() failure. + */ + printf("*** Example code, do not use in production ***\n"); + /* parse arguments, will exit on error */ ivshmem_server_parse_args(&args, argc, argv); @@ -219,7 +229,8 @@ main(int argc, char *argv[]) } /* init the ivshms structure */ - if (ivshmem_server_init(&server, args.unix_socket_path, args.shm_path, + if (ivshmem_server_init(&server, args.unix_socket_path, + args.shm_path, args.use_shm_open, args.shm_size, args.n_vectors, args.verbose) < 0) { fprintf(stderr, "cannot init server\n"); goto err; diff --git a/cpu-exec.c b/cpu-exec.c index fd92452f16..bbfcbfb543 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -133,10 +133,15 @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu) #endif /* CONFIG USER ONLY */ /* Execute a TB, and fix up the CPU state afterwards if necessary */ -static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr) +static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb) { CPUArchState *env = cpu->env_ptr; uintptr_t next_tb; + uint8_t *tb_ptr = itb->tc_ptr; + + qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc, + "Trace %p [" TARGET_FMT_lx "] %s\n", + itb->tc_ptr, itb->pc, lookup_symbol(itb->pc)); #if defined(DEBUG_DISAS) if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) { @@ -167,6 +172,10 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr) */ CPUClass *cc = CPU_GET_CLASS(cpu); TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK); + qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc, + "Stopped execution of TB chain before %p [" + TARGET_FMT_lx "] %s\n", + itb->tc_ptr, itb->pc, lookup_symbol(itb->pc)); if (cc->synchronize_from_tb) { cc->synchronize_from_tb(cpu, tb); } else { @@ -202,7 +211,7 @@ static void cpu_exec_nocache(CPUState *cpu, int max_cycles, cpu->current_tb = tb; /* execute the generated code */ trace_exec_tb_nocache(tb, tb->pc); - cpu_tb_exec(cpu, tb->tc_ptr); + cpu_tb_exec(cpu, tb); cpu->current_tb = NULL; tb_phys_invalidate(tb, -1); tb_free(tb); @@ -344,7 +353,6 @@ int cpu_exec(CPUState *cpu) #endif int ret, interrupt_request; TranslationBlock *tb; - uint8_t *tc_ptr; uintptr_t next_tb; SyncClocks sc; @@ -500,10 +508,6 @@ int cpu_exec(CPUState *cpu) next_tb = 0; tcg_ctx.tb_ctx.tb_invalidated_flag = 0; } - if (qemu_loglevel_mask(CPU_LOG_EXEC)) { - qemu_log("Trace %p [" TARGET_FMT_lx "] %s\n", - tb->tc_ptr, tb->pc, lookup_symbol(tb->pc)); - } /* see if we can patch the calling TB. When the TB spans two pages, we cannot safely do a direct jump. */ @@ -515,10 +519,9 @@ int cpu_exec(CPUState *cpu) tb_unlock(); if (likely(!cpu->exit_request)) { trace_exec_tb(tb, tb->pc); - tc_ptr = tb->tc_ptr; /* execute the generated code */ cpu->current_tb = tb; - next_tb = cpu_tb_exec(cpu, tc_ptr); + next_tb = cpu_tb_exec(cpu, tb); cpu->current_tb = NULL; switch (next_tb & TB_EXIT_MASK) { case TB_EXIT_REQUESTED: @@ -276,7 +276,7 @@ void cpu_disable_ticks(void) fairly approximate, so ignore small variation. When the guest is idle real and virtual time will be aligned in the IO wait loop. */ -#define ICOUNT_WOBBLE (get_ticks_per_sec() / 10) +#define ICOUNT_WOBBLE (NANOSECONDS_PER_SECOND / 10) static void icount_adjust(void) { @@ -327,7 +327,7 @@ static void icount_adjust_vm(void *opaque) { timer_mod(icount_vm_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - get_ticks_per_sec() / 10); + NANOSECONDS_PER_SECOND / 10); icount_adjust(); } @@ -674,7 +674,7 @@ void configure_icount(QemuOpts *opts, Error **errp) icount_adjust_vm, NULL); timer_mod(icount_vm_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - get_ticks_per_sec() / 10); + NANOSECONDS_PER_SECOND / 10); } /***********************************************************/ @@ -30,8 +30,30 @@ #include "exec/ram_addr.h" #include "tcg/tcg.h" -//#define DEBUG_TLB -//#define DEBUG_TLB_CHECK +/* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */ +/* #define DEBUG_TLB */ +/* #define DEBUG_TLB_LOG */ + +#ifdef DEBUG_TLB +# define DEBUG_TLB_GATE 1 +# ifdef DEBUG_TLB_LOG +# define DEBUG_TLB_LOG_GATE 1 +# else +# define DEBUG_TLB_LOG_GATE 0 +# endif +#else +# define DEBUG_TLB_GATE 0 +# define DEBUG_TLB_LOG_GATE 0 +#endif + +#define tlb_debug(fmt, ...) do { \ + if (DEBUG_TLB_LOG_GATE) { \ + qemu_log_mask(CPU_LOG_MMU, "%s: " fmt, __func__, \ + ## __VA_ARGS__); \ + } else if (DEBUG_TLB_GATE) { \ + fprintf(stderr, "%s: " fmt, __func__, ## __VA_ARGS__); \ + } \ +} while (0) /* statistics */ int tlb_flush_count; @@ -52,9 +74,8 @@ void tlb_flush(CPUState *cpu, int flush_global) { CPUArchState *env = cpu->env_ptr; -#if defined(DEBUG_TLB) - printf("tlb_flush:\n"); -#endif + tlb_debug("(%d)\n", flush_global); + /* must reset current TB so that interrupts cannot modify the links while we are modifying them */ cpu->current_tb = NULL; @@ -73,9 +94,7 @@ static inline void v_tlb_flush_by_mmuidx(CPUState *cpu, va_list argp) { CPUArchState *env = cpu->env_ptr; -#if defined(DEBUG_TLB) - printf("tlb_flush_by_mmuidx:"); -#endif + tlb_debug("start\n"); /* must reset current TB so that interrupts cannot modify the links while we are modifying them */ cpu->current_tb = NULL; @@ -87,18 +106,12 @@ static inline void v_tlb_flush_by_mmuidx(CPUState *cpu, va_list argp) break; } -#if defined(DEBUG_TLB) - printf(" %d", mmu_idx); -#endif + tlb_debug("%d\n", mmu_idx); memset(env->tlb_table[mmu_idx], -1, sizeof(env->tlb_table[0])); memset(env->tlb_v_table[mmu_idx], -1, sizeof(env->tlb_v_table[0])); } -#if defined(DEBUG_TLB) - printf("\n"); -#endif - memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache)); } @@ -128,16 +141,14 @@ void tlb_flush_page(CPUState *cpu, target_ulong addr) int i; int mmu_idx; -#if defined(DEBUG_TLB) - printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr); -#endif + tlb_debug("page :" TARGET_FMT_lx "\n", addr); + /* Check if we need to flush due to large pages. */ if ((addr & env->tlb_flush_mask) == env->tlb_flush_addr) { -#if defined(DEBUG_TLB) - printf("tlb_flush_page: forced full flush (" - TARGET_FMT_lx "/" TARGET_FMT_lx ")\n", - env->tlb_flush_addr, env->tlb_flush_mask); -#endif + tlb_debug("forcing full flush (" + TARGET_FMT_lx "/" TARGET_FMT_lx ")\n", + env->tlb_flush_addr, env->tlb_flush_mask); + tlb_flush(cpu, 1); return; } @@ -170,16 +181,14 @@ void tlb_flush_page_by_mmuidx(CPUState *cpu, target_ulong addr, ...) va_start(argp, addr); -#if defined(DEBUG_TLB) - printf("tlb_flush_page_by_mmu_idx: " TARGET_FMT_lx, addr); -#endif + tlb_debug("addr "TARGET_FMT_lx"\n", addr); + /* Check if we need to flush due to large pages. */ if ((addr & env->tlb_flush_mask) == env->tlb_flush_addr) { -#if defined(DEBUG_TLB) - printf(" forced full flush (" - TARGET_FMT_lx "/" TARGET_FMT_lx ")\n", - env->tlb_flush_addr, env->tlb_flush_mask); -#endif + tlb_debug("forced full flush (" + TARGET_FMT_lx "/" TARGET_FMT_lx ")\n", + env->tlb_flush_addr, env->tlb_flush_mask); + v_tlb_flush_by_mmuidx(cpu, argp); va_end(argp); return; @@ -198,9 +207,7 @@ void tlb_flush_page_by_mmuidx(CPUState *cpu, target_ulong addr, ...) break; } -#if defined(DEBUG_TLB) - printf(" %d", mmu_idx); -#endif + tlb_debug("idx %d\n", mmu_idx); tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr); @@ -211,10 +218,6 @@ void tlb_flush_page_by_mmuidx(CPUState *cpu, target_ulong addr, ...) } va_end(argp); -#if defined(DEBUG_TLB) - printf("\n"); -#endif - tb_flush_jmp_cache(cpu, addr); } @@ -367,12 +370,9 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr, section = address_space_translate_for_iotlb(cpu, asidx, paddr, &xlat, &sz); assert(sz >= TARGET_PAGE_SIZE); -#if defined(DEBUG_TLB) - qemu_log_mask(CPU_LOG_MMU, - "tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx - " prot=%x idx=%d\n", - vaddr, paddr, prot, mmu_idx); -#endif + tlb_debug("vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx + " prot=%x idx=%d\n", + vaddr, paddr, prot, mmu_idx); address = vaddr; if (!memory_region_is_ram(section->mr) && !memory_region_is_romd(section->mr)) { diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 58c1b940e1..439f89230c 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "crypto/block-luks.h" diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c index 9f378e8635..be88c6f0ef 100644 --- a/crypto/block-qcow.c +++ b/crypto/block-qcow.c @@ -25,6 +25,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "crypto/block-qcow.h" #include "crypto/secret.h" diff --git a/crypto/block.c b/crypto/block.c index 524ed91db8..da60eba85f 100644 --- a/crypto/block.c +++ b/crypto/block.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "crypto/blockpriv.h" #include "crypto/block-qcow.h" #include "crypto/block-luks.h" diff --git a/crypto/cipher.c b/crypto/cipher.c index 5402d18525..cafb454363 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "crypto/cipher.h" diff --git a/crypto/hash.c b/crypto/hash.c index 4a8c0caea1..b90af3495a 100644 --- a/crypto/hash.c +++ b/crypto/hash.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "crypto/hash.h" #ifdef CONFIG_GNUTLS_HASH diff --git a/crypto/init.c b/crypto/init.c index 31eea19bc9..1e564d9492 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "crypto/init.h" +#include "qapi/error.h" #include "qemu/thread.h" #ifdef CONFIG_GNUTLS diff --git a/crypto/ivgen-essiv.c b/crypto/ivgen-essiv.c index 5649c01b85..634de63338 100644 --- a/crypto/ivgen-essiv.c +++ b/crypto/ivgen-essiv.c @@ -19,6 +19,8 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/bswap.h" #include "crypto/ivgen-essiv.h" typedef struct QCryptoIVGenESSIV QCryptoIVGenESSIV; diff --git a/crypto/ivgen-plain.c b/crypto/ivgen-plain.c index 6a85256cac..9b9b4ad0bf 100644 --- a/crypto/ivgen-plain.c +++ b/crypto/ivgen-plain.c @@ -19,6 +19,8 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/bswap.h" #include "crypto/ivgen-plain.h" static int qcrypto_ivgen_plain_init(QCryptoIVGen *ivgen, diff --git a/crypto/ivgen-plain64.c b/crypto/ivgen-plain64.c index 9ca6db9df2..6c6b1b44c3 100644 --- a/crypto/ivgen-plain64.c +++ b/crypto/ivgen-plain64.c @@ -19,6 +19,8 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/bswap.h" #include "crypto/ivgen-plain.h" static int qcrypto_ivgen_plain_init(QCryptoIVGen *ivgen, diff --git a/crypto/ivgen.c b/crypto/ivgen.c index 4ffc1eb886..f66435112b 100644 --- a/crypto/ivgen.c +++ b/crypto/ivgen.c @@ -19,6 +19,8 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" + #include "crypto/ivgenpriv.h" #include "crypto/ivgen-plain.h" #include "crypto/ivgen-plain64.h" diff --git a/crypto/pbkdf-gcrypt.c b/crypto/pbkdf-gcrypt.c index 885614dfcc..997b311d84 100644 --- a/crypto/pbkdf-gcrypt.c +++ b/crypto/pbkdf-gcrypt.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "crypto/pbkdf.h" #include "gcrypt.h" diff --git a/crypto/pbkdf-nettle.c b/crypto/pbkdf-nettle.c index 1aa7395ea5..db9fc15780 100644 --- a/crypto/pbkdf-nettle.c +++ b/crypto/pbkdf-nettle.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "crypto/pbkdf.h" #include "nettle/pbkdf2.h" diff --git a/crypto/pbkdf-stub.c b/crypto/pbkdf-stub.c index cfc30d3c2a..266a5051b7 100644 --- a/crypto/pbkdf-stub.c +++ b/crypto/pbkdf-stub.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "crypto/pbkdf.h" bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash G_GNUC_UNUSED) diff --git a/crypto/pbkdf.c b/crypto/pbkdf.c index 90721d85d6..695cc35df1 100644 --- a/crypto/pbkdf.c +++ b/crypto/pbkdf.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "crypto/pbkdf.h" #ifndef _WIN32 #include <sys/resource.h> diff --git a/crypto/secret.c b/crypto/secret.c index be736f2cd5..285ab7a63c 100644 --- a/crypto/secret.c +++ b/crypto/secret.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "crypto/secret.h" #include "crypto/cipher.h" +#include "qapi/error.h" #include "qom/object_interfaces.h" #include "qemu/base64.h" #include "trace.h" diff --git a/crypto/tlscreds.c b/crypto/tlscreds.c index fc99589c22..1620e126ae 100644 --- a/crypto/tlscreds.c +++ b/crypto/tlscreds.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "crypto/tlscredspriv.h" #include "trace.h" diff --git a/crypto/tlscredsanon.c b/crypto/tlscredsanon.c index f36a793d16..1464220080 100644 --- a/crypto/tlscredsanon.c +++ b/crypto/tlscredsanon.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "crypto/tlscredsanon.h" #include "crypto/tlscredspriv.h" +#include "qapi/error.h" #include "qom/object_interfaces.h" #include "trace.h" diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c index 99130433fd..6a0179c2e1 100644 --- a/crypto/tlscredsx509.c +++ b/crypto/tlscredsx509.c @@ -22,6 +22,7 @@ #include "crypto/tlscredsx509.h" #include "crypto/tlscredspriv.h" #include "crypto/secret.h" +#include "qapi/error.h" #include "qom/object_interfaces.h" #include "trace.h" diff --git a/crypto/tlssession.c b/crypto/tlssession.c index e0d9658e80..a543e5a576 100644 --- a/crypto/tlssession.c +++ b/crypto/tlssession.c @@ -22,6 +22,7 @@ #include "crypto/tlssession.h" #include "crypto/tlscredsanon.h" #include "crypto/tlscredsx509.h" +#include "qapi/error.h" #include "qemu/acl.h" #include "trace.h" diff --git a/default-configs/mips-softmmu-common.mak b/default-configs/mips-softmmu-common.mak new file mode 100644 index 0000000000..37009a3637 --- /dev/null +++ b/default-configs/mips-softmmu-common.mak @@ -0,0 +1,32 @@ +# Common mips*-softmmu CONFIG defines + +include pci.mak +include sound.mak +include usb.mak +CONFIG_ESP=y +CONFIG_VGA_ISA=y +CONFIG_VGA_ISA_MM=y +CONFIG_VGA_CIRRUS=y +CONFIG_VMWARE_VGA=y +CONFIG_SERIAL=y +CONFIG_PARALLEL=y +CONFIG_I8254=y +CONFIG_PCSPK=y +CONFIG_PCKBD=y +CONFIG_FDC=y +CONFIG_ACPI=y +CONFIG_ACPI_X86=y +CONFIG_ACPI_MEMORY_HOTPLUG=y +CONFIG_ACPI_CPU_HOTPLUG=y +CONFIG_APM=y +CONFIG_I8257=y +CONFIG_PIIX4=y +CONFIG_IDE_ISA=y +CONFIG_IDE_PIIX=y +CONFIG_NE2000_ISA=y +CONFIG_MIPSNET=y +CONFIG_PFLASH_CFI01=y +CONFIG_I8259=y +CONFIG_MC146818RTC=y +CONFIG_ISA_TESTDEV=y +CONFIG_EMPTY_SLOT=y diff --git a/default-configs/mips-softmmu.mak b/default-configs/mips-softmmu.mak index 44467c37c1..9fede6e00f 100644 --- a/default-configs/mips-softmmu.mak +++ b/default-configs/mips-softmmu.mak @@ -1,32 +1,3 @@ # Default configuration for mips-softmmu -include pci.mak -include sound.mak -include usb.mak -CONFIG_ESP=y -CONFIG_VGA_ISA=y -CONFIG_VGA_ISA_MM=y -CONFIG_VGA_CIRRUS=y -CONFIG_VMWARE_VGA=y -CONFIG_SERIAL=y -CONFIG_PARALLEL=y -CONFIG_I8254=y -CONFIG_PCSPK=y -CONFIG_PCKBD=y -CONFIG_FDC=y -CONFIG_ACPI=y -CONFIG_ACPI_X86=y -CONFIG_ACPI_MEMORY_HOTPLUG=y -CONFIG_ACPI_CPU_HOTPLUG=y -CONFIG_APM=y -CONFIG_I8257=y -CONFIG_PIIX4=y -CONFIG_IDE_ISA=y -CONFIG_IDE_PIIX=y -CONFIG_NE2000_ISA=y -CONFIG_MIPSNET=y -CONFIG_PFLASH_CFI01=y -CONFIG_I8259=y -CONFIG_MC146818RTC=y -CONFIG_ISA_TESTDEV=y -CONFIG_EMPTY_SLOT=y +include mips-softmmu-common.mak diff --git a/default-configs/mips64-softmmu.mak b/default-configs/mips64-softmmu.mak index 66ed5f94c5..bad7496672 100644 --- a/default-configs/mips64-softmmu.mak +++ b/default-configs/mips64-softmmu.mak @@ -1,38 +1,9 @@ # Default configuration for mips64-softmmu -include pci.mak -include sound.mak -include usb.mak -CONFIG_ESP=y -CONFIG_VGA_ISA=y -CONFIG_VGA_ISA_MM=y -CONFIG_VGA_CIRRUS=y -CONFIG_VMWARE_VGA=y -CONFIG_SERIAL=y -CONFIG_PARALLEL=y -CONFIG_I8254=y -CONFIG_PCSPK=y -CONFIG_PCKBD=y -CONFIG_FDC=y -CONFIG_ACPI=y -CONFIG_ACPI_X86=y -CONFIG_ACPI_MEMORY_HOTPLUG=y -CONFIG_ACPI_CPU_HOTPLUG=y -CONFIG_APM=y -CONFIG_I8257=y -CONFIG_PIIX4=y -CONFIG_IDE_ISA=y -CONFIG_IDE_PIIX=y -CONFIG_NE2000_ISA=y +include mips-softmmu-common.mak CONFIG_RC4030=y CONFIG_DP8393X=y CONFIG_DS1225Y=y -CONFIG_MIPSNET=y -CONFIG_PFLASH_CFI01=y CONFIG_JAZZ=y CONFIG_G364FB=y -CONFIG_I8259=y CONFIG_JAZZ_LED=y -CONFIG_MC146818RTC=y -CONFIG_ISA_TESTDEV=y -CONFIG_EMPTY_SLOT=y diff --git a/default-configs/mips64el-softmmu.mak b/default-configs/mips64el-softmmu.mak index bfca2b2b7c..485e218cfc 100644 --- a/default-configs/mips64el-softmmu.mak +++ b/default-configs/mips64el-softmmu.mak @@ -1,41 +1,12 @@ # Default configuration for mips64el-softmmu -include pci.mak -include sound.mak -include usb.mak -CONFIG_ESP=y -CONFIG_VGA_ISA=y -CONFIG_VGA_ISA_MM=y -CONFIG_VGA_CIRRUS=y -CONFIG_VMWARE_VGA=y -CONFIG_SERIAL=y -CONFIG_PARALLEL=y -CONFIG_I8254=y -CONFIG_PCSPK=y -CONFIG_PCKBD=y -CONFIG_FDC=y -CONFIG_ACPI=y -CONFIG_ACPI_X86=y -CONFIG_ACPI_MEMORY_HOTPLUG=y -CONFIG_ACPI_CPU_HOTPLUG=y -CONFIG_APM=y -CONFIG_I8257=y -CONFIG_PIIX4=y -CONFIG_IDE_ISA=y -CONFIG_IDE_PIIX=y +include mips-softmmu-common.mak CONFIG_IDE_VIA=y -CONFIG_NE2000_ISA=y CONFIG_RC4030=y CONFIG_DP8393X=y CONFIG_DS1225Y=y -CONFIG_MIPSNET=y -CONFIG_PFLASH_CFI01=y CONFIG_FULONG=y CONFIG_JAZZ=y CONFIG_G364FB=y -CONFIG_I8259=y CONFIG_JAZZ_LED=y -CONFIG_MC146818RTC=y CONFIG_VT82C686=y -CONFIG_ISA_TESTDEV=y -CONFIG_EMPTY_SLOT=y diff --git a/default-configs/mipsel-softmmu.mak b/default-configs/mipsel-softmmu.mak index 0162ef0249..a7f6059484 100644 --- a/default-configs/mipsel-softmmu.mak +++ b/default-configs/mipsel-softmmu.mak @@ -1,32 +1,3 @@ # Default configuration for mipsel-softmmu -include pci.mak -include sound.mak -include usb.mak -CONFIG_ESP=y -CONFIG_VGA_ISA=y -CONFIG_VGA_ISA_MM=y -CONFIG_VGA_CIRRUS=y -CONFIG_VMWARE_VGA=y -CONFIG_SERIAL=y -CONFIG_PARALLEL=y -CONFIG_I8254=y -CONFIG_PCSPK=y -CONFIG_PCKBD=y -CONFIG_FDC=y -CONFIG_ACPI=y -CONFIG_ACPI_X86=y -CONFIG_ACPI_MEMORY_HOTPLUG=y -CONFIG_ACPI_CPU_HOTPLUG=y -CONFIG_APM=y -CONFIG_I8257=y -CONFIG_PIIX4=y -CONFIG_IDE_ISA=y -CONFIG_IDE_PIIX=y -CONFIG_NE2000_ISA=y -CONFIG_MIPSNET=y -CONFIG_PFLASH_CFI01=y -CONFIG_I8259=y -CONFIG_MC146818RTC=y -CONFIG_ISA_TESTDEV=y -CONFIG_EMPTY_SLOT=y +include mips-softmmu-common.mak diff --git a/default-configs/pci.mak b/default-configs/pci.mak index 4fa9a28ef6..9c8bc68c4c 100644 --- a/default-configs/pci.mak +++ b/default-configs/pci.mak @@ -36,5 +36,5 @@ CONFIG_SDHCI=y CONFIG_EDU=y CONFIG_VGA=y CONFIG_VGA_PCI=y -CONFIG_IVSHMEM=$(CONFIG_POSIX) +CONFIG_IVSHMEM=$(CONFIG_EVENTFD) CONFIG_ROCKER=y diff --git a/device_tree.c b/device_tree.c index 6204af88c8..ccba1fd4a4 100644 --- a/device_tree.c +++ b/device_tree.c @@ -17,6 +17,7 @@ #include <dirent.h> #endif +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/error-report.h" #include "sysemu/device_tree.h" diff --git a/disas/i386.c b/disas/i386.c index d40b72ab10..c0e717abe3 100644 --- a/disas/i386.c +++ b/disas/i386.c @@ -33,6 +33,8 @@ #include "qemu/osdep.h" #include "disas/bfd.h" +#include "qemu/cutils.h" + /* include/opcode/i386.h r1.78 */ /* opcode/i386.h -- Intel 80386 opcode macros @@ -153,8 +155,6 @@ /* opcodes/i386-dis.c r1.126 */ #include "qemu-common.h" -#include <setjmp.h> - static int fetch_data2(struct disassemble_info *, bfd_byte *); static int fetch_data(struct disassemble_info *, bfd_byte *); static void ckprefix (void); diff --git a/disas/m68k.c b/disas/m68k.c index 0412ecd4b6..8f74ae1157 100644 --- a/disas/m68k.c +++ b/disas/m68k.c @@ -615,8 +615,6 @@ static const char *const reg_half_names[] = /* Maximum length of an instruction. */ #define MAXLEN 22 -#include <setjmp.h> - struct private { /* Points to first byte not fetched. */ diff --git a/docs/specs/ivshmem-spec.txt b/docs/specs/ivshmem-spec.txt new file mode 100644 index 0000000000..a1f5499796 --- /dev/null +++ b/docs/specs/ivshmem-spec.txt @@ -0,0 +1,254 @@ += Device Specification for Inter-VM shared memory device = + +The Inter-VM shared memory device (ivshmem) is designed to share a +memory region between multiple QEMU processes running different guests +and the host. In order for all guests to be able to pick up the +shared memory area, it is modeled by QEMU as a PCI device exposing +said memory to the guest as a PCI BAR. + +The device can use a shared memory object on the host directly, or it +can obtain one from an ivshmem server. + +In the latter case, the device can additionally interrupt its peers, and +get interrupted by its peers. + + +== Configuring the ivshmem PCI device == + +There are two basic configurations: + +- Just shared memory: -device ivshmem-plain,memdev=HMB,... + + This uses host memory backend HMB. It should have option "share" + set. + +- Shared memory plus interrupts: -device ivshmem,chardev=CHR,vectors=N,... + + An ivshmem server must already be running on the host. The device + connects to the server's UNIX domain socket via character device + CHR. + + Each peer gets assigned a unique ID by the server. IDs must be + between 0 and 65535. + + Interrupts are message-signaled (MSI-X). vectors=N configures the + number of vectors to use. + +For more details on ivshmem device properties, see The QEMU Emulator +User Documentation (qemu-doc.*). + + +== The ivshmem PCI device's guest interface == + +The device has vendor ID 1af4, device ID 1110, revision 1. Before +QEMU 2.6.0, it had revision 0. + +=== PCI BARs === + +The ivshmem PCI device has two or three BARs: + +- BAR0 holds device registers (256 Byte MMIO) +- BAR1 holds MSI-X table and PBA (only ivshmem-doorbell) +- BAR2 maps the shared memory object + +There are two ways to use this device: + +- If you only need the shared memory part, BAR2 suffices. This way, + you have access to the shared memory in the guest and can use it as + you see fit. Memnic, for example, uses ivshmem this way from guest + user space (see http://dpdk.org/browse/memnic). + +- If you additionally need the capability for peers to interrupt each + other, you need BAR0 and BAR1. You will most likely want to write a + kernel driver to handle interrupts. Requires the device to be + configured for interrupts, obviously. + +Before QEMU 2.6.0, BAR2 can initially be invalid if the device is +configured for interrupts. It becomes safely accessible only after +the ivshmem server provided the shared memory. These devices have PCI +revision 0 rather than 1. Guest software should wait for the +IVPosition register (described below) to become non-negative before +accessing BAR2. + +Revision 0 of the device is not capable to tell guest software whether +it is configured for interrupts. + +=== PCI device registers === + +BAR 0 contains the following registers: + + Offset Size Access On reset Function + 0 4 read/write 0 Interrupt Mask + bit 0: peer interrupt (rev 0) + reserved (rev 1) + bit 1..31: reserved + 4 4 read/write 0 Interrupt Status + bit 0: peer interrupt (rev 0) + reserved (rev 1) + bit 1..31: reserved + 8 4 read-only 0 or ID IVPosition + 12 4 write-only N/A Doorbell + bit 0..15: vector + bit 16..31: peer ID + 16 240 none N/A reserved + +Software should only access the registers as specified in column +"Access". Reserved bits should be ignored on read, and preserved on +write. + +In revision 0 of the device, Interrupt Status and Mask Register +together control the legacy INTx interrupt when the device has no +MSI-X capability: INTx is asserted when the bit-wise AND of Status and +Mask is non-zero and the device has no MSI-X capability. Interrupt +Status Register bit 0 becomes 1 when an interrupt request from a peer +is received. Reading the register clears it. + +IVPosition Register: if the device is not configured for interrupts, +this is zero. Else, it is the device's ID (between 0 and 65535). + +Before QEMU 2.6.0, the register may read -1 for a short while after +reset. These devices have PCI revision 0 rather than 1. + +There is no good way for software to find out whether the device is +configured for interrupts. A positive IVPosition means interrupts, +but zero could be either. + +Doorbell Register: writing this register requests to interrupt a peer. +The written value's high 16 bits are the ID of the peer to interrupt, +and its low 16 bits select an interrupt vector. + +If the device is not configured for interrupts, the write is ignored. + +If the interrupt hasn't completed setup, the write is ignored. The +device is not capable to tell guest software whether setup is +complete. Interrupts can regress to this state on migration. + +If the peer with the requested ID isn't connected, or it has fewer +interrupt vectors connected, the write is ignored. The device is not +capable to tell guest software what peers are connected, or how many +interrupt vectors are connected. + +The peer's interrupt for this vector then becomes pending. There is +no way for software to clear the pending bit, and a polling mode of +operation is therefore impossible. + +If the peer is a revision 0 device without MSI-X capability, its +Interrupt Status register is set to 1. This asserts INTx unless +masked by the Interrupt Mask register. The device is not capable to +communicate the interrupt vector to guest software then. + +With multiple MSI-X vectors, different vectors can be used to indicate +different events have occurred. The semantics of interrupt vectors +are left to the application. + + +== Interrupt infrastructure == + +When configured for interrupts, the peers share eventfd objects in +addition to shared memory. The shared resources are managed by an +ivshmem server. + +=== The ivshmem server === + +The server listens on a UNIX domain socket. + +For each new client that connects to the server, the server +- picks an ID, +- creates eventfd file descriptors for the interrupt vectors, +- sends the ID and the file descriptor for the shared memory to the + new client, +- sends connect notifications for the new client to the other clients + (these contain file descriptors for sending interrupts), +- sends connect notifications for the other clients to the new client, + and +- sends interrupt setup messages to the new client (these contain file + descriptors for receiving interrupts). + +The first client to connect to the server receives ID zero. + +When a client disconnects from the server, the server sends disconnect +notifications to the other clients. + +The next section describes the protocol in detail. + +If the server terminates without sending disconnect notifications for +its connected clients, the clients can elect to continue. They can +communicate with each other normally, but won't receive disconnect +notification on disconnect, and no new clients can connect. There is +no way for the clients to connect to a restarted server. The device +is not capable to tell guest software whether the server is still up. + +Example server code is in contrib/ivshmem-server/. Not to be used in +production. It assumes all clients use the same number of interrupt +vectors. + +A standalone client is in contrib/ivshmem-client/. It can be useful +for debugging. + +=== The ivshmem Client-Server Protocol === + +An ivshmem device configured for interrupts connects to an ivshmem +server. This section details the protocol between the two. + +The connection is one-way: the server sends messages to the client. +Each message consists of a single 8 byte little-endian signed number, +and may be accompanied by a file descriptor via SCM_RIGHTS. Both +client and server close the connection on error. + +Note: QEMU currently doesn't close the connection right on error, but +only when the character device is destroyed. + +On connect, the server sends the following messages in order: + +1. The protocol version number, currently zero. The client should + close the connection on receipt of versions it can't handle. + +2. The client's ID. This is unique among all clients of this server. + IDs must be between 0 and 65535, because the Doorbell register + provides only 16 bits for them. + +3. The number -1, accompanied by the file descriptor for the shared + memory. + +4. Connect notifications for existing other clients, if any. This is + a peer ID (number between 0 and 65535 other than the client's ID), + repeated N times. Each repetition is accompanied by one file + descriptor. These are for interrupting the peer with that ID using + vector 0,..,N-1, in order. If the client is configured for fewer + vectors, it closes the extra file descriptors. If it is configured + for more, the extra vectors remain unconnected. + +5. Interrupt setup. This is the client's own ID, repeated N times. + Each repetition is accompanied by one file descriptor. These are + for receiving interrupts from peers using vector 0,..,N-1, in + order. If the client is configured for fewer vectors, it closes + the extra file descriptors. If it is configured for more, the + extra vectors remain unconnected. + +From then on, the server sends these kinds of messages: + +6. Connection / disconnection notification. This is a peer ID. + + - If the number comes with a file descriptor, it's a connection + notification, exactly like in step 4. + + - Else, it's a disconnection notification for the peer with that ID. + +Known bugs: + +* The protocol changed incompatibly in QEMU 2.5. Before, messages + were native endian long, and there was no version number. + +* The protocol is poorly designed. + +=== The ivshmem Client-Client Protocol === + +An ivshmem device configured for interrupts receives eventfd file +descriptors for interrupting peers and getting interrupted by peers +from the server, as explained in the previous section. + +To interrupt a peer, the device writes the 8-byte integer 1 in native +byte order to the respective file descriptor. + +To receive an interrupt, the device reads and discards as many 8-byte +integers as it can. diff --git a/docs/specs/ivshmem_device_spec.txt b/docs/specs/ivshmem_device_spec.txt deleted file mode 100644 index d318d65c32..0000000000 --- a/docs/specs/ivshmem_device_spec.txt +++ /dev/null @@ -1,161 +0,0 @@ - -Device Specification for Inter-VM shared memory device ------------------------------------------------------- - -The Inter-VM shared memory device is designed to share a memory region (created -on the host via the POSIX shared memory API) between multiple QEMU processes -running different guests. In order for all guests to be able to pick up the -shared memory area, it is modeled by QEMU as a PCI device exposing said memory -to the guest as a PCI BAR. -The memory region does not belong to any guest, but is a POSIX memory object on -the host. The host can access this shared memory if needed. - -The device also provides an optional communication mechanism between guests -sharing the same memory object. More details about that in the section 'Guest to -guest communication' section. - - -The Inter-VM PCI device ------------------------ - -From the VM point of view, the ivshmem PCI device supports three BARs. - -- BAR0 is a 1 Kbyte MMIO region to support registers and interrupts when MSI is - not used. -- BAR1 is used for MSI-X when it is enabled in the device. -- BAR2 is used to access the shared memory object. - -It is your choice how to use the device but you must choose between two -behaviors : - -- basically, if you only need the shared memory part, you will map BAR2. - This way, you have access to the shared memory in guest and can use it as you - see fit (memnic, for example, uses it in userland - http://dpdk.org/browse/memnic). - -- BAR0 and BAR1 are used to implement an optional communication mechanism - through interrupts in the guests. If you need an event mechanism between the - guests accessing the shared memory, you will most likely want to write a - kernel driver that will handle interrupts. See details in the section 'Guest - to guest communication' section. - -The behavior is chosen when starting your QEMU processes: -- no communication mechanism needed, the first QEMU to start creates the shared - memory on the host, subsequent QEMU processes will use it. - -- communication mechanism needed, an ivshmem server must be started before any - QEMU processes, then each QEMU process connects to the server unix socket. - -For more details on the QEMU ivshmem parameters, see qemu-doc documentation. - - -Guest to guest communication ----------------------------- - -This section details the communication mechanism between the guests accessing -the ivhsmem shared memory. - -*ivshmem server* - -This server code is available in qemu.git/contrib/ivshmem-server. - -The server must be started on the host before any guest. -It creates a shared memory object then waits for clients to connect on a unix -socket. All the messages are little-endian int64_t integer. - -For each client (QEMU process) that connects to the server: -- the server sends a protocol version, if client does not support it, the client - closes the communication, -- the server assigns an ID for this client and sends this ID to him as the first - message, -- the server sends a fd to the shared memory object to this client, -- the server creates a new set of host eventfds associated to the new client and - sends this set to all already connected clients, -- finally, the server sends all the eventfds sets for all clients to the new - client. - -The server signals all clients when one of them disconnects. - -The client IDs are limited to 16 bits because of the current implementation (see -Doorbell register in 'PCI device registers' subsection). Hence only 65536 -clients are supported. - -All the file descriptors (fd to the shared memory, eventfds for each client) -are passed to clients using SCM_RIGHTS over the server unix socket. - -Apart from the current ivshmem implementation in QEMU, an ivshmem client has -been provided in qemu.git/contrib/ivshmem-client for debug. - -*QEMU as an ivshmem client* - -At initialisation, when creating the ivshmem device, QEMU first receives a -protocol version and closes communication with server if it does not match. -Then, QEMU gets its ID from the server then makes it available through BAR0 -IVPosition register for the VM to use (see 'PCI device registers' subsection). -QEMU then uses the fd to the shared memory to map it to BAR2. -eventfds for all other clients received from the server are stored to implement -BAR0 Doorbell register (see 'PCI device registers' subsection). -Finally, eventfds assigned to this QEMU process are used to send interrupts in -this VM. - -*PCI device registers* - -From the VM point of view, the ivshmem PCI device supports 4 registers of -32-bits each. - -enum ivshmem_registers { - IntrMask = 0, - IntrStatus = 4, - IVPosition = 8, - Doorbell = 12 -}; - -The first two registers are the interrupt mask and status registers. Mask and -status are only used with pin-based interrupts. They are unused with MSI -interrupts. - -Status Register: The status register is set to 1 when an interrupt occurs. - -Mask Register: The mask register is bitwise ANDed with the interrupt status -and the result will raise an interrupt if it is non-zero. However, since 1 is -the only value the status will be set to, it is only the first bit of the mask -that has any effect. Therefore interrupts can be masked by setting the first -bit to 0 and unmasked by setting the first bit to 1. - -IVPosition Register: The IVPosition register is read-only and reports the -guest's ID number. The guest IDs are non-negative integers. When using the -server, since the server is a separate process, the VM ID will only be set when -the device is ready (shared memory is received from the server and accessible -via the device). If the device is not ready, the IVPosition will return -1. -Applications should ensure that they have a valid VM ID before accessing the -shared memory. - -Doorbell Register: To interrupt another guest, a guest must write to the -Doorbell register. The doorbell register is 32-bits, logically divided into -two 16-bit fields. The high 16-bits are the guest ID to interrupt and the low -16-bits are the interrupt vector to trigger. The semantics of the value -written to the doorbell depends on whether the device is using MSI or a regular -pin-based interrupt. In short, MSI uses vectors while regular interrupts set -the status register. - -Regular Interrupts - -If regular interrupts are used (due to either a guest not supporting MSI or the -user specifying not to use them on startup) then the value written to the lower -16-bits of the Doorbell register results is arbitrary and will trigger an -interrupt in the destination guest. - -Message Signalled Interrupts - -An ivshmem device may support multiple MSI vectors. If so, the lower 16-bits -written to the Doorbell register must be between 0 and the maximum number of -vectors the guest supports. The lower 16 bits written to the doorbell is the -MSI vector that will be raised in the destination guest. The number of MSI -vectors is configurable but it is set when the VM is started. - -The important thing to remember with MSI is that it is only a signal, no status -is set (since MSI interrupts are not shared). All information other than the -interrupt itself should be communicated via the shared memory region. Devices -supporting multiple MSI vectors can use different vectors to indicate different -events have occurred. The semantics of interrupt vectors are left to the -user's discretion. @@ -12,7 +12,7 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qemu/cutils.h" #include "elf.h" #include "cpu.h" #include "exec/cpu-all.h" @@ -17,11 +17,12 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" +#include "qapi/error.h" #ifndef _WIN32 #include <sys/mman.h> #endif -#include "qemu-common.h" +#include "qemu/cutils.h" #include "cpu.h" #include "tcg.h" #include "hw/hw.h" @@ -1238,7 +1239,7 @@ static void *file_ram_alloc(RAMBlock *block, char *sanitized_name; char *c; void *area; - int fd; + int fd = -1; int64_t page_size; if (kvm_enabled() && !kvm_has_sync_mmu()) { @@ -1320,7 +1321,6 @@ static void *file_ram_alloc(RAMBlock *block, if (area == MAP_FAILED) { error_setg_errno(errp, errno, "unable to map backing store for guest RAM"); - close(fd); goto error; } @@ -1335,7 +1335,9 @@ error: if (unlink_on_error) { unlink(path); } - close(fd); + if (fd != -1) { + close(fd); + } return NULL; } #endif diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index 0875436b83..a4cbdad452 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -113,7 +113,7 @@ const float16 float16_default_nan = const_float16(0xFE00); #if defined(TARGET_SPARC) const float32 float32_default_nan = const_float32(0x7FFFFFFF); #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \ - defined(TARGET_XTENSA) || defined(TARGET_S390X) + defined(TARGET_XTENSA) || defined(TARGET_S390X) || defined(TARGET_TRICORE) const float32 float32_default_nan = const_float32(0x7FC00000); #elif SNAN_BIT_IS_ONE const float32 float32_default_nan = const_float32(0x7FBFFFFF); @@ -17,9 +17,10 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" -#include "qemu-common.h" -#ifdef CONFIG_USER_ONLY +#include "qapi/error.h" +#include "qemu/cutils.h" +#ifdef CONFIG_USER_ONLY #include "qemu.h" #else #include "monitor/monitor.h" @@ -34,6 +34,7 @@ #include "ui/console.h" #include "block/qapi.h" #include "qemu-io.h" +#include "qemu/cutils.h" #ifdef CONFIG_SPICE #include <spice/enums.h> diff --git a/hw/9pfs/9p-handle.c b/hw/9pfs/9p-handle.c index 5088ef5dcb..894041488a 100644 --- a/hw/9pfs/9p-handle.c +++ b/hw/9pfs/9p-handle.c @@ -20,6 +20,7 @@ #include <sys/socket.h> #include <sys/un.h> #include "qemu/xattr.h" +#include "qemu/cutils.h" #include "qemu/error-report.h" #include <linux/fs.h> #ifdef CONFIG_LINUX_MAGIC_H diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c index ca995a79db..16f45f4854 100644 --- a/hw/9pfs/9p-local.c +++ b/hw/9pfs/9p-local.c @@ -21,6 +21,7 @@ #include <sys/socket.h> #include <sys/un.h> #include "qemu/xattr.h" +#include "qemu/cutils.h" #include "qemu/error-report.h" #include <libgen.h> #include <linux/fs.h> diff --git a/hw/9pfs/9p-proxy.c b/hw/9pfs/9p-proxy.c index 0805c9cab4..00a4eb2a7b 100644 --- a/hw/9pfs/9p-proxy.c +++ b/hw/9pfs/9p-proxy.c @@ -13,6 +13,7 @@ #include <sys/socket.h> #include <sys/un.h> #include "9p.h" +#include "qemu/cutils.h" #include "qemu/error-report.h" #include "fsdev/qemu-fsdev.h" #include "9p-proxy.h" diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c index 365623e8f3..f1475dfd6d 100644 --- a/hw/9pfs/9p-synth.c +++ b/hw/9pfs/9p-synth.c @@ -20,6 +20,7 @@ #include "9p-synth.h" #include "qemu/rcu.h" #include "qemu/rcu_queue.h" +#include "qemu/cutils.h" /* Root node for synth file system */ static V9fsSynthNode v9fs_synth_root = { diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index db5f4780dc..f5e30125fc 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -14,6 +14,7 @@ #include "qemu/osdep.h" #include "hw/virtio/virtio.h" #include "hw/i386/pc.h" +#include "qapi/error.h" #include "qemu/error-report.h" #include "qemu/iov.h" #include "qemu/sockets.h" diff --git a/hw/acpi/core.c b/hw/acpi/core.c index 31ead6490f..7925a1a45b 100644 --- a/hw/acpi/core.c +++ b/hw/acpi/core.c @@ -389,7 +389,7 @@ uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar) acpi_pm_tmr_update function uses ns for setting the timer. */ int64_t d = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); if (d >= muldiv64(ar->tmr.overflow_time, - get_ticks_per_sec(), PM_TIMER_FREQUENCY)) { + NANOSECONDS_PER_SECOND, PM_TIMER_FREQUENCY)) { ar->pm1.evt.sts |= ACPI_BITMASK_TIMER_STATUS; } return ar->pm1.evt.sts; @@ -483,7 +483,7 @@ void acpi_pm_tmr_update(ACPIREGS *ar, bool enable) /* schedule a timer interruption if needed */ if (enable) { - expire_time = muldiv64(ar->tmr.overflow_time, get_ticks_per_sec(), + expire_time = muldiv64(ar->tmr.overflow_time, NANOSECONDS_PER_SECOND, PM_TIMER_FREQUENCY); timer_mod(ar->tmr.timer, expire_time); } else { diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c index 5a410a5287..4d86743fde 100644 --- a/hw/acpi/cpu_hotplug.c +++ b/hw/acpi/cpu_hotplug.c @@ -12,6 +12,7 @@ #include "qemu/osdep.h" #include "hw/hw.h" #include "hw/acpi/cpu_hotplug.h" +#include "qapi/error.h" #include "qom/cpu.h" static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned int size) diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 72202545e0..27e978f5fd 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -25,6 +25,7 @@ */ #include "qemu/osdep.h" #include "hw/hw.h" +#include "qapi/error.h" #include "qapi/visitor.h" #include "hw/i386/pc.h" #include "hw/pci/pci.h" diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index 3e338b5ec2..71f4c4e14b 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -35,6 +35,7 @@ #include "exec/ioport.h" #include "exec/address-spaces.h" #include "hw/pci/pci_bus.h" +#include "qapi/error.h" #include "qom/qom-qobject.h" #include "qapi/qmp/qint.h" diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 9694e5238f..16abdf1624 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -26,6 +26,7 @@ #include "hw/pci/pci.h" #include "hw/acpi/acpi.h" #include "sysemu/sysemu.h" +#include "qapi/error.h" #include "qemu/range.h" #include "exec/ioport.h" #include "hw/nvram/fw_cfg.h" diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c index 7c5989bdc7..f1267b5441 100644 --- a/hw/alpha/dp264.c +++ b/hw/alpha/dp264.c @@ -7,6 +7,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "elf.h" #include "hw/loader.h" @@ -18,6 +20,7 @@ #include "hw/ide.h" #include "hw/timer/i8254.h" #include "hw/char/serial.h" +#include "qemu/cutils.h" #define MAX_IDE_BUS 2 diff --git a/hw/alpha/pci.c b/hw/alpha/pci.c index fb902bb92d..5baa0eaf15 100644 --- a/hw/alpha/pci.c +++ b/hw/alpha/pci.c @@ -7,6 +7,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "alpha_sys.h" #include "qemu/log.h" #include "sysemu/sysemu.h" diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c index b86ff5ea9b..97721b535d 100644 --- a/hw/alpha/typhoon.c +++ b/hw/alpha/typhoon.c @@ -7,6 +7,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "hw/hw.h" #include "hw/devices.h" diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index 02c8caa191..ca15d1c8cc 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -16,6 +16,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/devices.h" #include "hw/arm/allwinner-a10.h" diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index ed7d97fc21..bb2a22d967 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -8,6 +8,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/arm/arm.h" #include "hw/loader.h" diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c index daa5518c92..03f993863b 100644 --- a/hw/arm/ast2400.c +++ b/hw/arm/ast2400.c @@ -11,6 +11,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "exec/address-spaces.h" #include "hw/arm/ast2400.h" #include "hw/char/serial.h" diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c index 8099a8a92e..234d518430 100644 --- a/hw/arm/bcm2835_peripherals.c +++ b/hw/arm/bcm2835_peripherals.c @@ -9,6 +9,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/arm/bcm2835_peripherals.h" #include "hw/misc/bcm2835_mbox_defs.h" #include "hw/arm/raspi_platform.h" diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c index 89a6b35b81..af29dd1f19 100644 --- a/hw/arm/bcm2836.c +++ b/hw/arm/bcm2836.c @@ -9,6 +9,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/arm/bcm2836.h" #include "hw/arm/raspi_platform.h" #include "hw/sysbus.h" diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 8ba0e4272a..5975fbfa8c 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -8,6 +8,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/arm/arm.h" #include "hw/arm/linux-boot-if.h" diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c index 2382c59158..fbd78ed01c 100644 --- a/hw/arm/cubieboard.c +++ b/hw/arm/cubieboard.c @@ -16,6 +16,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/devices.h" #include "hw/boards.h" diff --git a/hw/arm/digic.c b/hw/arm/digic.c index 82087bacb8..e0f9730325 100644 --- a/hw/arm/digic.c +++ b/hw/arm/digic.c @@ -21,6 +21,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/arm/digic.h" #define DIGIC4_TIMER_BASE(n) (0xc0210000 + (n) * 0x100) diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c index e5308f47ab..520c8e9ff1 100644 --- a/hw/arm/digic_boards.c +++ b/hw/arm/digic_boards.c @@ -24,6 +24,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/boards.h" #include "exec/address-spaces.h" #include "qemu/error-report.h" diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index 6a8f0b54ce..be3c96d21e 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -22,6 +22,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/boards.h" #include "sysemu/sysemu.h" #include "hw/sysbus.h" diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c index 5b11cd9b4d..0efa194054 100644 --- a/hw/arm/exynos4_boards.c +++ b/hw/arm/exynos4_boards.c @@ -22,6 +22,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "sysemu/sysemu.h" #include "sysemu/qtest.h" #include "hw/sysbus.h" diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c index 1fbc317b74..2f878b935d 100644 --- a/hw/arm/fsl-imx25.c +++ b/hw/arm/fsl-imx25.c @@ -23,6 +23,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/arm/fsl-imx25.h" #include "sysemu/sysemu.h" #include "exec/address-spaces.h" diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c index 0d69a2c70b..31a3a87911 100644 --- a/hw/arm/fsl-imx31.c +++ b/hw/arm/fsl-imx31.c @@ -20,6 +20,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/arm/fsl-imx31.h" #include "sysemu/sysemu.h" #include "exec/address-spaces.h" diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c index e37378c69f..d9930c0d34 100644 --- a/hw/arm/highbank.c +++ b/hw/arm/highbank.c @@ -18,6 +18,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/sysbus.h" #include "hw/arm/arm.h" #include "hw/devices.h" diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c index e3cffd190c..025b60843e 100644 --- a/hw/arm/imx25_pdk.c +++ b/hw/arm/imx25_pdk.c @@ -24,6 +24,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/arm/fsl-imx25.h" #include "hw/boards.h" #include "qemu/error-report.h" diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c index c6656a817c..e31bca6e72 100644 --- a/hw/arm/integratorcp.c +++ b/hw/arm/integratorcp.c @@ -8,6 +8,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/devices.h" #include "hw/boards.h" diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c index 2eeb9d8973..2c96ee33b6 100644 --- a/hw/arm/kzm.c +++ b/hw/arm/kzm.c @@ -14,6 +14,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/arm/fsl-imx31.h" #include "hw/boards.h" #include "qemu/error-report.h" diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c index 98a892ff62..454acc5d2b 100644 --- a/hw/arm/mainstone.c +++ b/hw/arm/mainstone.c @@ -12,6 +12,7 @@ * GNU GPL, version 2 or (at your option) any later version. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/arm/pxa.h" #include "hw/arm/arm.h" diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index 54548f38bb..7a4cc07dd5 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c @@ -10,6 +10,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/arm/arm.h" #include "hw/devices.h" diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c index 49da6e360d..23d792837f 100644 --- a/hw/arm/netduino2.c +++ b/hw/arm/netduino2.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/boards.h" #include "qemu/error-report.h" #include "hw/arm/stm32f205_soc.h" diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c index 9a5f33bd8a..5382505559 100644 --- a/hw/arm/nseries.c +++ b/hw/arm/nseries.c @@ -19,7 +19,8 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qapi/error.h" +#include "qemu/cutils.h" #include "sysemu/sysemu.h" #include "hw/arm/omap.h" #include "hw/arm/arm.h" diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c index 6f68130419..b3cf0ec690 100644 --- a/hw/arm/omap1.c +++ b/hw/arm/omap1.c @@ -18,6 +18,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/boards.h" #include "hw/hw.h" #include "hw/arm/arm.h" @@ -28,6 +31,8 @@ #include "sysemu/blockdev.h" #include "qemu/range.h" #include "hw/sysbus.h" +#include "qemu/cutils.h" +#include "qemu/bcd.h" /* Should signal the TCMI/GPMC */ uint32_t omap_badwidth_read8(void *opaque, hwaddr addr) @@ -107,7 +112,7 @@ static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer) if (timer->st && timer->enable && timer->rate) return timer->val - muldiv64(distance >> (timer->ptv + 1), - timer->rate, get_ticks_per_sec()); + timer->rate, NANOSECONDS_PER_SECOND); else return timer->val; } @@ -125,7 +130,7 @@ static inline void omap_timer_update(struct omap_mpu_timer_s *timer) if (timer->enable && timer->st && timer->rate) { timer->val = timer->reset_val; /* Should skip this on clk enable */ expires = muldiv64((uint64_t) timer->val << (timer->ptv + 1), - get_ticks_per_sec(), timer->rate); + NANOSECONDS_PER_SECOND, timer->rate); /* If timer expiry would be sooner than in about 1 ms and * auto-reload isn't set, then fire immediately. This is a hack @@ -133,10 +138,11 @@ static inline void omap_timer_update(struct omap_mpu_timer_s *timer) * sets the interval to a very low value and polls the status bit * in a busy loop when it wants to sleep just a couple of CPU * ticks. */ - if (expires > (get_ticks_per_sec() >> 10) || timer->ar) + if (expires > (NANOSECONDS_PER_SECOND >> 10) || timer->ar) { timer_mod(timer->timer, timer->time + expires); - else + } else { qemu_bh_schedule(timer->tick); + } } else timer_del(timer->timer); } @@ -613,14 +619,14 @@ static void omap_ulpd_pm_write(void *opaque, hwaddr addr, now -= s->ulpd_gauge_start; /* 32-kHz ticks */ - ticks = muldiv64(now, 32768, get_ticks_per_sec()); + ticks = muldiv64(now, 32768, NANOSECONDS_PER_SECOND); s->ulpd_pm_regs[0x00 >> 2] = (ticks >> 0) & 0xffff; s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff; if (ticks >> 32) /* OVERFLOW_32K */ s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2; /* High frequency ticks */ - ticks = muldiv64(now, 12000000, get_ticks_per_sec()); + ticks = muldiv64(now, 12000000, NANOSECONDS_PER_SECOND); s->ulpd_pm_regs[0x08 >> 2] = (ticks >> 0) & 0xffff; s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff; if (ticks >> 32) /* OVERFLOW_HI_FREQ */ @@ -3026,7 +3032,7 @@ static void omap_mcbsp_source_tick(void *opaque) omap_mcbsp_rx_newdata(s); timer_mod(s->source_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - get_ticks_per_sec()); + NANOSECONDS_PER_SECOND); } static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s) @@ -3072,7 +3078,7 @@ static void omap_mcbsp_sink_tick(void *opaque) omap_mcbsp_tx_newdata(s); timer_mod(s->sink_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - get_ticks_per_sec()); + NANOSECONDS_PER_SECOND); } static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s) diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c index d11224e81e..3a0d77714a 100644 --- a/hw/arm/omap2.c +++ b/hw/arm/omap2.c @@ -19,6 +19,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" #include "hw/boards.h" diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c index cd50691d8b..5d74026cb2 100644 --- a/hw/arm/omap_sx1.c +++ b/hw/arm/omap_sx1.c @@ -26,6 +26,7 @@ * with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "ui/console.h" #include "hw/arm/omap.h" diff --git a/hw/arm/palm.c b/hw/arm/palm.c index cae0a46561..7f460732e3 100644 --- a/hw/arm/palm.c +++ b/hw/arm/palm.c @@ -17,6 +17,7 @@ * with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "audio/audio.h" #include "sysemu/sysemu.h" diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c index 55d741918b..89ebd92b93 100644 --- a/hw/arm/palmetto-bmc.c +++ b/hw/arm/palmetto-bmc.c @@ -10,6 +10,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "exec/address-spaces.h" #include "hw/arm/arm.h" #include "hw/arm/ast2400.h" diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c index ff6ac7a60a..1a8c36033a 100644 --- a/hw/arm/pxa2xx.c +++ b/hw/arm/pxa2xx.c @@ -8,6 +8,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/arm/pxa.h" #include "sysemu/sysemu.h" @@ -17,6 +20,7 @@ #include "sysemu/char.h" #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" +#include "qemu/cutils.h" static struct { hwaddr io_base; diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c index 8a39b1caca..7e51532cde 100644 --- a/hw/arm/pxa2xx_pic.c +++ b/hw/arm/pxa2xx_pic.c @@ -9,6 +9,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/arm/pxa.h" #include "hw/sysbus.h" diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 83fe8097e5..2b295f14c4 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -9,6 +9,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/arm/bcm2836.h" #include "qemu/error-report.h" #include "hw/boards.h" diff --git a/hw/arm/realview.c b/hw/arm/realview.c index 481ae00fbc..3222b360e4 100644 --- a/hw/arm/realview.c +++ b/hw/arm/realview.c @@ -8,6 +8,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/arm/arm.h" #include "hw/arm/primecell.h" diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c index c3048f3ea6..bf61d63b58 100644 --- a/hw/arm/spitz.c +++ b/hw/arm/spitz.c @@ -11,6 +11,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/arm/pxa.h" #include "hw/arm/arm.h" @@ -404,7 +405,7 @@ static void spitz_keyboard_tick(void *opaque) } timer_mod(s->kbdtimer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - get_ticks_per_sec() / 32); + NANOSECONDS_PER_SECOND / 32); } static void spitz_keyboard_pre_map(SpitzKeyboardState *s) diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index c3c72f1b49..c1766f856a 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -8,6 +8,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/sysbus.h" #include "hw/ssi/ssi.h" #include "hw/arm/arm.h" @@ -100,7 +101,7 @@ static void gptm_reload(gptm_state *s, int n, int reset) tick += (int64_t)count * system_clock_scale; } else if (s->config == 1) { /* 32-bit RTC. 1Hz tick. */ - tick += get_ticks_per_sec(); + tick += NANOSECONDS_PER_SECOND; } else if (s->mode[n] == 0xa) { /* PWM mode. Not implemented. */ } else { diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c index 79bfe6d10f..a5ea1e2370 100644 --- a/hw/arm/stm32f205_soc.c +++ b/hw/arm/stm32f205_soc.c @@ -23,6 +23,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/arm/arm.h" #include "exec/address-spaces.h" #include "hw/arm/stm32f205_soc.h" diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c index 3b17a2126a..1eeb1ab391 100644 --- a/hw/arm/strongarm.c +++ b/hw/arm/strongarm.c @@ -28,6 +28,7 @@ */ #include "qemu/osdep.h" +#include "cpu.h" #include "hw/boards.h" #include "hw/sysbus.h" #include "strongarm.h" @@ -36,6 +37,7 @@ #include "sysemu/char.h" #include "sysemu/sysemu.h" #include "hw/ssi/ssi.h" +#include "qemu/cutils.h" //#define DEBUG @@ -1024,7 +1026,7 @@ static void strongarm_uart_update_parameters(StrongARMUARTState *s) ssp.parity = parity; ssp.data_bits = data_bits; ssp.stop_bits = stop_bits; - s->char_transmit_time = (get_ticks_per_sec() / speed) * frame_size; + s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size; if (s->chr) { qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); } diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c index 49bd212d07..5debb3348c 100644 --- a/hw/arm/sysbus-fdt.c +++ b/hw/arm/sysbus-fdt.c @@ -22,6 +22,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include <libfdt.h> #include "qemu-common.h" #ifdef CONFIG_LINUX diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c index d83c1e1785..4e9494f94c 100644 --- a/hw/arm/tosa.c +++ b/hw/arm/tosa.c @@ -12,6 +12,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/arm/pxa.h" #include "hw/arm/arm.h" diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index 5f7523e355..e5a80c2d2c 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -8,6 +8,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/arm/arm.h" #include "hw/devices.h" diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index 769390c6c1..70b3e701e0 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -22,6 +22,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/arm/arm.h" #include "hw/arm/primecell.h" diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 6a86b2ca2c..f51fe396ce 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -27,6 +27,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "hw/arm/virt-acpi-build.h" #include "qemu/bitmap.h" diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 95331a5662..a5e787dec6 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -29,6 +29,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/sysbus.h" #include "hw/arm/arm.h" #include "hw/arm/primecell.h" diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c index a35983a9ec..98b17c9aed 100644 --- a/hw/arm/xilinx_zynq.c +++ b/hw/arm/xilinx_zynq.c @@ -16,6 +16,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/arm/arm.h" #include "net/net.h" diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c index a1bd283a52..5f480182b2 100644 --- a/hw/arm/xlnx-ep108.c +++ b/hw/arm/xlnx-ep108.c @@ -16,6 +16,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/arm/xlnx-zynqmp.h" #include "hw/boards.h" #include "qemu/error-report.h" diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index 4fbb63550b..4d504da643 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -16,6 +16,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/arm/xlnx-zynqmp.h" #include "hw/intc/arm_gic_common.h" #include "exec/address-spaces.h" diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c index 1270b19cc6..7836446fc8 100644 --- a/hw/audio/adlib.c +++ b/hw/audio/adlib.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/audio/audio.h" #include "audio/audio.h" @@ -169,7 +170,7 @@ static void timer_handler (int c, double interval_Sec) s->ticking[n] = 1; #ifdef DEBUG - interval = get_ticks_per_sec () * interval_Sec; + interval = NANOSECONDS_PER_SECOND * interval_Sec; exp = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + interval; s->exp[n] = exp; #endif diff --git a/hw/audio/gus.c b/hw/audio/gus.c index b416a54909..9dd6947bee 100644 --- a/hw/audio/gus.c +++ b/hw/audio/gus.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/audio/audio.h" #include "audio/audio.h" diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c index 6f8816cf64..3a4a57ac31 100644 --- a/hw/audio/sb16.c +++ b/hw/audio/sb16.c @@ -762,8 +762,8 @@ static void complete (SB16State *s) freq = s->freq > 0 ? s->freq : 11025; samples = dsp_get_lohi (s) + 1; bytes = samples << s->fmt_stereo << (s->fmt_bits == 16); - ticks = muldiv64 (bytes, get_ticks_per_sec (), freq); - if (ticks < get_ticks_per_sec () / 1024) { + ticks = muldiv64(bytes, NANOSECONDS_PER_SECOND, freq); + if (ticks < NANOSECONDS_PER_SECOND / 1024) { qemu_irq_raise (s->pic); } else { diff --git a/hw/block/block.c b/hw/block/block.c index 960df2b9d0..97a59d4fa2 100644 --- a/hw/block/block.c +++ b/hw/block/block.c @@ -11,6 +11,7 @@ #include "sysemu/blockdev.h" #include "sysemu/block-backend.h" #include "hw/block/block.h" +#include "qapi/error.h" #include "qemu/error-report.h" void blkconf_serial(BlockConf *conf, char **serial) diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index 36f3d2b813..e666dd4ff0 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -13,6 +13,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "trace.h" #include "qemu/iov.h" #include "qemu/thread.h" diff --git a/hw/block/fdc.c b/hw/block/fdc.c index fc3aef9cd1..372227569e 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -30,6 +30,7 @@ #include "qemu/osdep.h" #include "hw/hw.h" #include "hw/block/fdc.h" +#include "qapi/error.h" #include "qemu/error-report.h" #include "qemu/timer.h" #include "hw/isa/isa.h" @@ -1938,8 +1939,8 @@ static void fdctrl_handle_readid(FDCtrl *fdctrl, int direction) FDrive *cur_drv = get_cur_drv(fdctrl); cur_drv->head = (fdctrl->fifo[1] >> 2) & 1; - timer_mod(fdctrl->result_timer, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() / 50)); + timer_mod(fdctrl->result_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + (NANOSECONDS_PER_SECOND / 50)); } static void fdctrl_handle_format_track(FDCtrl *fdctrl, int direction) diff --git a/hw/block/nand.c b/hw/block/nand.c index f51e13fcac..29c6596810 100644 --- a/hw/block/nand.c +++ b/hw/block/nand.c @@ -23,6 +23,7 @@ #include "hw/block/flash.h" #include "sysemu/block-backend.h" #include "hw/qdev.h" +#include "qapi/error.h" #include "qemu/error-report.h" # define NAND_CMD_READ0 0x00 diff --git a/hw/block/nvme.c b/hw/block/nvme.c index c68b62521a..173988ee84 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -26,6 +26,7 @@ #include <hw/pci/msix.h> #include <hw/pci/pci.h> #include "sysemu/sysemu.h" +#include "qapi/error.h" #include "qapi/visitor.h" #include "sysemu/block-backend.h" diff --git a/hw/block/nvme.h b/hw/block/nvme.h index bf3a3ccac8..8fb0c10756 100644 --- a/hw/block/nvme.h +++ b/hw/block/nvme.h @@ -1,5 +1,6 @@ #ifndef HW_NVME_H #define HW_NVME_H +#include "qemu/cutils.h" typedef struct NvmeBar { uint64_t cap; diff --git a/hw/block/onenand.c b/hw/block/onenand.c index 91896851f5..883f4b1faa 100644 --- a/hw/block/onenand.c +++ b/hw/block/onenand.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "hw/hw.h" #include "hw/block/flash.h" diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index a4c4fa1c69..c475c2aea7 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -40,6 +40,7 @@ #include "hw/hw.h" #include "hw/block/flash.h" #include "sysemu/block-backend.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "qemu/bitops.h" #include "exec/address-spaces.h" diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index aaa697adbb..b13172c6e1 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -38,6 +38,7 @@ #include "qemu/osdep.h" #include "hw/hw.h" #include "hw/block/flash.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "sysemu/block-backend.h" #include "exec/address-spaces.h" @@ -431,8 +432,8 @@ static void pflash_write (pflash_t *pfl, hwaddr offset, } pfl->status = 0x00; /* Let's wait 5 seconds before chip erase is done */ - timer_mod(pfl->timer, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() * 5)); + timer_mod(pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + (NANOSECONDS_PER_SECOND * 5)); break; case 0x30: /* Sector erase */ @@ -446,8 +447,8 @@ static void pflash_write (pflash_t *pfl, hwaddr offset, } pfl->status = 0x00; /* Let's wait 1/2 second before sector erase is done */ - timer_mod(pfl->timer, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() / 2)); + timer_mod(pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + (NANOSECONDS_PER_SECOND / 2)); break; default: DPRINTF("%s: invalid command %02x (wc 5)\n", __func__, cmd); diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index cb710f16fa..870d345244 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -12,6 +12,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/iov.h" #include "qemu/error-report.h" diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index 635328fa69..e619a1f7d9 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -29,6 +29,7 @@ #include "xen_blkif.h" #include "sysemu/blockdev.h" #include "sysemu/block-backend.h" +#include "qapi/error.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qstring.h" diff --git a/hw/bt/hci-csr.c b/hw/bt/hci-csr.c index 0189b0ae28..2e970b6561 100644 --- a/hw/bt/hci-csr.c +++ b/hw/bt/hci-csr.c @@ -363,7 +363,7 @@ static int csrhci_ioctl(struct CharDriverState *chr, int cmd, void *arg) switch (cmd) { case CHR_IOCTL_SERIAL_SET_PARAMS: ssp = (QEMUSerialSetParams *) arg; - s->baud_delay = get_ticks_per_sec() / ssp->speed; + s->baud_delay = NANOSECONDS_PER_SECOND / ssp->speed; /* Moments later... (but shorter than 100ms) */ s->modem_state |= CHR_TIOCM_CTS; break; @@ -389,7 +389,7 @@ static void csrhci_reset(struct csrhci_s *s) s->out_len = 0; s->out_size = FIFO_LEN; s->in_len = 0; - s->baud_delay = get_ticks_per_sec(); + s->baud_delay = NANOSECONDS_PER_SECOND; s->enable = 0; s->in_hdr = INT_MAX; s->in_data = INT_MAX; diff --git a/hw/bt/hci.c b/hw/bt/hci.c index 8bc33b50a5..7d52205093 100644 --- a/hw/bt/hci.c +++ b/hw/bt/hci.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/timer.h" #include "hw/usb.h" @@ -26,6 +27,7 @@ #include "hw/bt.h" #include "qapi/qmp/qerror.h" #include "sysemu/replay.h" +#include "qemu/cutils.h" struct bt_hci_s { uint8_t *(*evt_packet)(void *opaque); diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index b590d990d4..486591bf07 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -205,7 +205,7 @@ static void uart_parameters_setup(CadenceUARTState *s) } packet_size += ssp.data_bits + ssp.stop_bits; - s->char_tx_time = (get_ticks_per_sec() / ssp.speed) * packet_size; + s->char_tx_time = (NANOSECONDS_PER_SECOND / ssp.speed) * packet_size; if (s->chr) { qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); } @@ -479,7 +479,7 @@ static void cadence_uart_init(Object *obj) sysbus_init_mmio(sbd, &s->iomem); sysbus_init_irq(sbd, &s->irq); - s->char_tx_time = (get_ticks_per_sec() / 9600) * 10; + s->char_tx_time = (NANOSECONDS_PER_SECOND / 9600) * 10; } static int cadence_uart_post_load(void *opaque, int version_id) diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c index 148632e686..e7f025ec67 100644 --- a/hw/char/debugcon.c +++ b/hw/char/debugcon.c @@ -25,6 +25,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "sysemu/char.h" #include "hw/isa/isa.h" diff --git a/hw/char/parallel.c b/hw/char/parallel.c index f6ba76fd60..11c78fed88 100644 --- a/hw/char/parallel.c +++ b/hw/char/parallel.c @@ -23,6 +23,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "sysemu/char.h" #include "hw/isa/isa.h" diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c index b9b5bc6db2..1594ec4db3 100644 --- a/hw/char/serial-isa.c +++ b/hw/char/serial-isa.c @@ -24,6 +24,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/char/serial.h" #include "hw/isa/isa.h" diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c index 8f1b6f3d84..303104dd19 100644 --- a/hw/char/serial-pci.c +++ b/hw/char/serial-pci.c @@ -26,6 +26,7 @@ /* see docs/specs/pci-serial.txt */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/char/serial.h" #include "hw/pci/pci.h" diff --git a/hw/char/serial.c b/hw/char/serial.c index 39e07db088..6d815b5c69 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "hw/char/serial.h" #include "sysemu/char.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "exec/address-spaces.h" #include "qemu/error-report.h" @@ -178,7 +179,7 @@ static void serial_update_parameters(SerialState *s) ssp.parity = parity; ssp.data_bits = data_bits; ssp.stop_bits = stop_bits; - s->char_transmit_time = (get_ticks_per_sec() / speed) * frame_size; + s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size; qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); DPRINTF("speed=%d parity=%c data=%d stop=%d\n", @@ -216,8 +217,10 @@ static void serial_update_msl(SerialState *s) /* The real 16550A apparently has a 250ns response latency to line status changes. We'll be lazy and poll only every 10ms, and only poll it at all if MSI interrupts are turned on */ - if (s->poll_msl) - timer_mod(s->modem_status_poll, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + get_ticks_per_sec() / 100); + if (s->poll_msl) { + timer_mod(s->modem_status_poll, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + NANOSECONDS_PER_SECOND / 100); + } } static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) @@ -823,7 +826,7 @@ static void serial_reset(void *opaque) s->mcr = UART_MCR_OUT2; s->scr = 0; s->tsr_retry = 0; - s->char_transmit_time = (get_ticks_per_sec() / 9600) * 10; + s->char_transmit_time = (NANOSECONDS_PER_SECOND / 9600) * 10; s->poll_msl = 0; s->timeout_ipending = 0; diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c index 747c69d12d..3498d7b052 100644 --- a/hw/char/spapr_vty.c +++ b/hw/char/spapr_vty.c @@ -1,4 +1,7 @@ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/qdev.h" #include "sysemu/char.h" #include "hw/ppc/spapr.h" diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index 99cb6836ad..6e5de6dec2 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu/iov.h" #include "monitor/monitor.h" #include "qemu/error-report.h" diff --git a/hw/core/loader.c b/hw/core/loader.c index 8e8031ca3c..6b949fe44f 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -43,6 +43,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "disas/disas.h" #include "monitor/monitor.h" @@ -53,6 +54,7 @@ #include "exec/memory.h" #include "exec/address-spaces.h" #include "hw/boards.h" +#include "qemu/cutils.h" #include <zlib.h> diff --git a/hw/core/machine.c b/hw/core/machine.c index a8c4680b0c..6dbbc85b97 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -12,11 +12,13 @@ #include "qemu/osdep.h" #include "hw/boards.h" +#include "qapi/error.h" #include "qapi-visit.h" #include "qapi/visitor.h" #include "hw/sysbus.h" #include "sysemu/sysemu.h" #include "qemu/error-report.h" +#include "qemu/cutils.h" static char *machine_get_accel(Object *obj, Error **errp) { diff --git a/hw/core/nmi.c b/hw/core/nmi.c index 6ca569bd7f..e8bcc4177b 100644 --- a/hw/core/nmi.c +++ b/hw/core/nmi.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "hw/nmi.h" +#include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "monitor/monitor.h" diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index e10cede749..891219ae05 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -13,6 +13,7 @@ #include "qemu/osdep.h" #include "net/net.h" #include "hw/qdev.h" +#include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index bc89800246..737d29c632 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -1,6 +1,8 @@ #include "qemu/osdep.h" #include "net/net.h" #include "hw/qdev.h" +#include "qapi/error.h" +#include "hw/pci/pci.h" #include "qapi/qmp/qerror.h" #include "qemu/error-report.h" #include "sysemu/block-backend.h" @@ -516,6 +518,16 @@ PropertyInfo qdev_prop_macaddr = { .set = set_mac, }; +/* --- on/off/auto --- */ + +PropertyInfo qdev_prop_on_off_auto = { + .name = "OnOffAuto", + .description = "on/off/auto", + .enum_table = OnOffAuto_lookup, + .get = get_enum, + .set = set_enum, +}; + /* --- lost tick policy --- */ QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int)); diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c index a221b8fe7b..bc05152fd3 100644 --- a/hw/cpu/a15mpcore.c +++ b/hw/cpu/a15mpcore.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/cpu/a15mpcore.h" #include "sysemu/kvm.h" #include "kvm_arm.h" diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c index 23c882fe9a..5459ae8c1b 100644 --- a/hw/cpu/a9mpcore.c +++ b/hw/cpu/a9mpcore.c @@ -9,6 +9,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/cpu/a9mpcore.h" static void a9mp_priv_set_irq(void *opaque, int irq, int level) diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c index 5f4ca31927..eb244658b9 100644 --- a/hw/cpu/arm11mpcore.c +++ b/hw/cpu/arm11mpcore.c @@ -8,6 +8,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/cpu/arm11mpcore.h" #include "hw/intc/realview_gic.h" diff --git a/hw/cpu/realview_mpcore.c b/hw/cpu/realview_mpcore.c index c5c4dfced5..39d4ebeb1d 100644 --- a/hw/cpu/realview_mpcore.c +++ b/hw/cpu/realview_mpcore.c @@ -9,6 +9,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/cpu/arm11mpcore.h" #include "hw/intc/realview_gic.h" diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c index f2ba1d0775..9f58658741 100644 --- a/hw/cris/axis_dev88.c +++ b/hw/cris/axis_dev88.c @@ -23,6 +23,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "net/net.h" #include "hw/block/flash.h" diff --git a/hw/cris/boot.c b/hw/cris/boot.c index 42485a4ca0..f896ed7f86 100644 --- a/hw/cris/boot.c +++ b/hw/cris/boot.c @@ -23,10 +23,13 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/loader.h" #include "elf.h" #include "boot.h" +#include "qemu/cutils.h" static void main_cpu_reset(void *opaque) { diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c index 779b56f07b..506f1d3d90 100644 --- a/hw/display/bcm2835_fb.c +++ b/hw/display/bcm2835_fb.c @@ -24,6 +24,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/display/bcm2835_fb.h" #include "hw/display/framebuffer.h" #include "ui/pixel_ops.h" diff --git a/hw/display/cg3.c b/hw/display/cg3.c index 321a25157b..fc0d97fa4b 100644 --- a/hw/display/cg3.c +++ b/hw/display/cg3.c @@ -24,6 +24,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/error-report.h" #include "ui/console.h" diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 57b91a77ca..3d712d592f 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -27,6 +27,7 @@ * available at http://home.worldonline.dk/~finth/ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/pci/pci.h" #include "ui/console.h" diff --git a/hw/display/sm501.c b/hw/display/sm501.c index 29572437e4..5f71012108 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -23,6 +23,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/char/serial.h" #include "ui/console.h" diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c index 31043b1783..da3ceceb0a 100644 --- a/hw/display/tc6393xb.c +++ b/hw/display/tc6393xb.c @@ -11,6 +11,7 @@ * GNU GPL, version 2 or (at your option) any later version. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/devices.h" #include "hw/block/flash.h" diff --git a/hw/display/tcx.c b/hw/display/tcx.c index 8afc2f33c6..8e26aae801 100644 --- a/hw/display/tcx.c +++ b/hw/display/tcx.c @@ -23,7 +23,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" +#include "cpu.h" /* FIXME shouldn't use TARGET_PAGE_SIZE */ #include "ui/console.h" #include "ui/pixel_ops.h" #include "hw/loader.h" diff --git a/hw/display/vga.c b/hw/display/vga.c index 555cac64c7..657e9f196d 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "vga.h" #include "ui/console.h" @@ -235,9 +236,9 @@ static void vga_precise_update_retrace_info(VGACommonState *s) r->total_chars = vtotal_lines * htotal_chars; if (r->freq) { - r->ticks_per_char = get_ticks_per_sec() / (r->total_chars * r->freq); + r->ticks_per_char = NANOSECONDS_PER_SECOND / (r->total_chars * r->freq); } else { - r->ticks_per_char = get_ticks_per_sec() / chars_per_sec; + r->ticks_per_char = NANOSECONDS_PER_SECOND / chars_per_sec; } r->vstart = vretr_start_line; @@ -265,7 +266,7 @@ static void vga_precise_update_retrace_info(VGACommonState *s) "dots = %d\n" "ticks/char = %" PRId64 "\n" "\n", - (double) get_ticks_per_sec() / (r->ticks_per_char * r->total_chars), + (double) NANOSECONDS_PER_SECOND / (r->ticks_per_char * r->total_chars), htotal_chars, hretr_start_char, hretr_skew_chars, diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index 17bba630eb..0c63fa8513 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/loader.h" #include "trace.h" diff --git a/hw/dma/bcm2835_dma.c b/hw/dma/bcm2835_dma.c index c7ce4e4881..5421175998 100644 --- a/hw/dma/bcm2835_dma.c +++ b/hw/dma/bcm2835_dma.c @@ -4,6 +4,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/dma/bcm2835_dma.h" /* DMA CS Control and Status bits */ diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index 6078893efb..f345c54762 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -381,7 +381,7 @@ out: } static void i8257_dma_register_channel(IsaDma *obj, int nchan, - DMA_transfer_handler transfer_handler, + IsaDmaTransferHandler transfer_handler, void *opaque) { I8257State *d = I8257(obj); diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c index 37ea7e41ff..ea89ecb00e 100644 --- a/hw/dma/pl330.c +++ b/hw/dma/pl330.c @@ -16,6 +16,7 @@ #include "qemu/osdep.h" #include "hw/sysbus.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "sysemu/dma.h" diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c index 1c4f8df16b..a06c2359a7 100644 --- a/hw/dma/rc4030.c +++ b/hw/dma/rc4030.c @@ -112,7 +112,7 @@ static void set_next_tick(rc4030State *s) tm_hz = 1000 / (s->itr + 1); timer_mod(s->periodic_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - get_ticks_per_sec() / tm_hz); + NANOSECONDS_PER_SECOND / tm_hz); } /* called for accesses to rc4030 */ diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c index ce5c1e6fbd..a4753e55a2 100644 --- a/hw/dma/xilinx_axidma.c +++ b/hw/dma/xilinx_axidma.c @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "hw/sysbus.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "hw/ptimer.h" #include "qemu/log.h" diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 325d8ce13c..35180efe0c 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -21,6 +21,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "acpi-build.h" #include <glib.h> #include "qemu-common.h" diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h index 148c0f9977..007332e51c 100644 --- a/hw/i386/acpi-build.h +++ b/hw/i386/acpi-build.h @@ -2,8 +2,6 @@ #ifndef HW_I386_ACPI_BUILD_H #define HW_I386_ACPI_BUILD_H -#include "qemu/typedefs.h" - void acpi_setup(void); #endif diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c index e43b5c4461..a4462e5ca9 100644 --- a/hw/i386/kvm/i8254.c +++ b/hw/i386/kvm/i8254.c @@ -23,6 +23,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "sysemu/sysemu.h" #include "hw/timer/i8254.h" diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c index d4089e7cc2..bf425a2b9f 100644 --- a/hw/i386/kvm/pci-assign.c +++ b/hw/i386/kvm/pci-assign.c @@ -21,6 +21,7 @@ * Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com) */ #include "qemu/osdep.h" +#include "qapi/error.h" #include <sys/mman.h> #include "hw/hw.h" #include "hw/i386/pc.h" diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c index 9e164e65d9..387caa67d4 100644 --- a/hw/i386/multiboot.c +++ b/hw/i386/multiboot.c @@ -23,6 +23,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/nvram/fw_cfg.h" #include "multiboot.h" diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c index 2324e700b0..f915ad0a36 100644 --- a/hw/i386/pc_sysfw.c +++ b/hw/i386/pc_sysfw.c @@ -24,6 +24,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "sysemu/block-backend.h" #include "qemu/error-report.h" #include "hw/sysbus.h" diff --git a/hw/i386/pci-assign-load-rom.c b/hw/i386/pci-assign-load-rom.c index bff979a4d0..4bbb08c955 100644 --- a/hw/i386/pci-assign-load-rom.c +++ b/hw/i386/pci-assign-load-rom.c @@ -2,6 +2,7 @@ * This is splited from hw/i386/kvm/pci-assign.c */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/i386/pc.h" #include "qemu/error-report.h" diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c index a2247b917a..aa7839324c 100644 --- a/hw/i386/xen/xen_platform.c +++ b/hw/i386/xen/xen_platform.c @@ -24,6 +24,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/i386/pc.h" #include "hw/ide.h" diff --git a/hw/i386/xen/xen_pvdevice.c b/hw/i386/xen/xen_pvdevice.c index 1095c65d41..c093b34458 100644 --- a/hw/i386/xen/xen_pvdevice.c +++ b/hw/i386/xen/xen_pvdevice.c @@ -30,6 +30,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/pci/pci.h" #include "trace.h" diff --git a/hw/ide/core.c b/hw/ide/core.c index 241e840de0..90524d5e16 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -33,6 +33,7 @@ #include "sysemu/dma.h" #include "hw/block/block.h" #include "sysemu/block-backend.h" +#include "qemu/cutils.h" #include <hw/ide/internal.h> @@ -975,8 +976,8 @@ static void ide_sector_write_cb(void *opaque, int ret) that at the expense of slower write performances. Use this option _only_ to install Windows 2000. You must disable it for normal use. */ - timer_mod(s->sector_write_timer, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() / 1000)); + timer_mod(s->sector_write_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + (NANOSECONDS_PER_SECOND / 1000)); } else { ide_set_irq(s->bus); } diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index 2d14a768f1..4bc74a32d2 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -19,6 +19,7 @@ #include "qemu/osdep.h" #include <hw/hw.h> #include "sysemu/dma.h" +#include "qapi/error.h" #include "qemu/error-report.h" #include <hw/ide/internal.h> #include "sysemu/block-backend.h" diff --git a/hw/input/hid.c b/hw/input/hid.c index 59126776f5..d92c7463ba 100644 --- a/hw/input/hid.c +++ b/hw/input/hid.c @@ -96,7 +96,7 @@ void hid_set_next_idle(HIDState *hs) { if (hs->idle) { uint64_t expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - get_ticks_per_sec() * hs->idle * 4 / 1000; + NANOSECONDS_PER_SECOND * hs->idle * 4 / 1000; if (!hs->idle_timer) { hs->idle_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, hid_idle_timer, hs); } diff --git a/hw/input/milkymist-softusb.c b/hw/input/milkymist-softusb.c index 64b929281e..40dfca157f 100644 --- a/hw/input/milkymist-softusb.c +++ b/hw/input/milkymist-softusb.c @@ -22,6 +22,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/sysbus.h" #include "trace.h" diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c index 8da48876c1..9b359aaec0 100644 --- a/hw/input/tsc2005.c +++ b/hw/input/tsc2005.c @@ -291,7 +291,8 @@ static void tsc2005_pin_update(TSC2005State *s) s->precision = s->nextprecision; s->function = s->nextfunction; s->pdst = !s->pnd0; /* Synchronised on internal clock */ - expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() >> 7); + expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + (NANOSECONDS_PER_SECOND >> 7); timer_mod(s->timer, expires); } diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c index d11ef048a1..93ca374fcd 100644 --- a/hw/input/tsc210x.c +++ b/hw/input/tsc210x.c @@ -835,7 +835,8 @@ static void tsc210x_pin_update(TSC210xState *s) s->busy = 1; s->precision = s->nextprecision; s->function = s->nextfunction; - expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() >> 10); + expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + (NANOSECONDS_PER_SECOND >> 10); timer_mod(s->timer, expires); } diff --git a/hw/input/virtio-input-host.c b/hw/input/virtio-input-host.c index ddee54cb7d..9e0f46d88f 100644 --- a/hw/input/virtio-input-host.c +++ b/hw/input/virtio-input-host.c @@ -5,6 +5,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/sockets.h" diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c index 5061f4cf7a..672c207eb5 100644 --- a/hw/input/virtio-input.c +++ b/hw/input/virtio-input.c @@ -5,6 +5,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu/iov.h" #include "hw/qdev.h" diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index 659f377e55..4abe145c68 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -18,6 +18,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/> */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/i386/apic.h" #include "hw/i386/apic_internal.h" #include "trace.h" diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 0834c2f1a7..f55124174d 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "hw/sysbus.h" #include "gic_internal.h" +#include "qapi/error.h" #include "qom/cpu.h" //#define DEBUG_GIC diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c index 707d00ded4..0a1f56af19 100644 --- a/hw/intc/arm_gic_common.c +++ b/hw/intc/arm_gic_common.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "gic_internal.h" #include "hw/arm/linux-boot-if.h" diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c index e61c5d9d47..bc85ab769f 100644 --- a/hw/intc/arm_gic_kvm.c +++ b/hw/intc/arm_gic_kvm.c @@ -20,6 +20,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/sysbus.h" #include "migration/migration.h" #include "sysemu/kvm.h" diff --git a/hw/intc/arm_gicv2m.c b/hw/intc/arm_gicv2m.c index ebd368bbad..e8b5177dcc 100644 --- a/hw/intc/arm_gicv2m.c +++ b/hw/intc/arm_gicv2m.c @@ -26,6 +26,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/sysbus.h" #include "hw/pci/msi.h" diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c index e4f0f5a589..b9d3824f2b 100644 --- a/hw/intc/arm_gicv3_common.c +++ b/hw/intc/arm_gicv3_common.c @@ -21,6 +21,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/intc/arm_gicv3_common.h" static void gicv3_pre_save(void *opaque) diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c index 90c7950704..acc1730048 100644 --- a/hw/intc/arm_gicv3_kvm.c +++ b/hw/intc/arm_gicv3_kvm.c @@ -20,6 +20,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/intc/arm_gicv3_common.h" #include "hw/sysbus.h" #include "sysemu/kvm.h" diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 92f6a44eec..669e82adfc 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -11,6 +11,8 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" #include "hw/sysbus.h" #include "qemu/timer.h" #include "hw/arm/arm.h" diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c index 6f3a86350c..bb43669b93 100644 --- a/hw/intc/i8259.c +++ b/hw/intc/i8259.c @@ -230,7 +230,7 @@ int pic_read_irq(DeviceState *d) printf("IRQ%d latency=%0.3fus\n", irq, (double)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - - irq_time[irq]) * 1000000.0 / get_ticks_per_sec()); + irq_time[irq]) * 1000000.0 / NANOSECONDS_PER_SECOND); #endif DPRINTF("pic_interrupt: irq=%d\n", irq); return intno; diff --git a/hw/intc/ioapic_common.c b/hw/intc/ioapic_common.c index 0a48de29b9..1b7ec5ec20 100644 --- a/hw/intc/ioapic_common.c +++ b/hw/intc/ioapic_common.c @@ -20,6 +20,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "monitor/monitor.h" #include "hw/i386/ioapic.h" #include "hw/i386/ioapic_internal.h" diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c index 7685250bf4..2d3769310f 100644 --- a/hw/intc/openpic.c +++ b/hw/intc/openpic.c @@ -41,6 +41,7 @@ #include "hw/ppc/ppc_e500.h" #include "hw/sysbus.h" #include "hw/pci/msi.h" +#include "qapi/error.h" #include "qemu/bitops.h" #include "qapi/qmp/qerror.h" diff --git a/hw/intc/openpic_kvm.c b/hw/intc/openpic_kvm.c index 778af4a7d4..e47e94f2cf 100644 --- a/hw/intc/openpic_kvm.c +++ b/hw/intc/openpic_kvm.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include <sys/ioctl.h> #include "exec/address-spaces.h" #include "hw/hw.h" diff --git a/hw/intc/realview_gic.c b/hw/intc/realview_gic.c index 291f196637..50bbab66ee 100644 --- a/hw/intc/realview_gic.c +++ b/hw/intc/realview_gic.c @@ -8,6 +8,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/intc/realview_gic.h" static void realview_gic_set_irq(void *opaque, int irq, int level) diff --git a/hw/intc/sh_intc.c b/hw/intc/sh_intc.c index f3cdfaf428..6ce2a8084f 100644 --- a/hw/intc/sh_intc.c +++ b/hw/intc/sh_intc.c @@ -9,6 +9,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sh4/sh_intc.h" #include "hw/hw.h" #include "hw/sh4/sh.h" diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 213a370925..8659be0171 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -26,6 +26,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "trace.h" #include "qemu/timer.h" diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index 9fe06677f9..9029d9ee0b 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -26,6 +26,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "trace.h" #include "hw/ppc/spapr.h" diff --git a/hw/ipack/ipack.c b/hw/ipack/ipack.c index 7c5c30de55..5f99ed9a79 100644 --- a/hw/ipack/ipack.c +++ b/hw/ipack/ipack.c @@ -9,6 +9,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/ipack/ipack.h" IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot) diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c index c31a3a02c2..fe12112a2f 100644 --- a/hw/ipmi/ipmi_bmc_extern.c +++ b/hw/ipmi/ipmi_bmc_extern.c @@ -28,6 +28,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "sysemu/char.h" #include "sysemu/sysemu.h" diff --git a/hw/ipmi/isa_ipmi_bt.c b/hw/ipmi/isa_ipmi_bt.c index ace2dc0a80..aaea12ecdd 100644 --- a/hw/ipmi/isa_ipmi_bt.c +++ b/hw/ipmi/isa_ipmi_bt.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/ipmi/ipmi.h" #include "hw/isa/isa.h" diff --git a/hw/ipmi/isa_ipmi_kcs.c b/hw/ipmi/isa_ipmi_kcs.c index 9841b7f3d5..2742ce06c4 100644 --- a/hw/ipmi/isa_ipmi_kcs.c +++ b/hw/ipmi/isa_ipmi_kcs.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/ipmi/ipmi.h" #include "hw/isa/isa.h" diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c index c3b7388529..7aa115caf2 100644 --- a/hw/isa/isa-bus.c +++ b/hw/isa/isa-bus.c @@ -17,6 +17,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "monitor/monitor.h" #include "hw/sysbus.h" diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 0ee29c0ad2..99cd3ba9e1 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -29,6 +29,7 @@ */ #include "qemu/osdep.h" #include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "qapi/visitor.h" #include "qemu/range.h" diff --git a/hw/isa/pc87312.c b/hw/isa/pc87312.c index 6b5c7a2e02..c3ebf3e7a0 100644 --- a/hw/isa/pc87312.c +++ b/hw/isa/pc87312.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include "hw/isa/pc87312.h" +#include "qapi/error.h" #include "qemu/error-report.h" #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c index 5b61b76f2e..c0290560fc 100644 --- a/hw/lm32/lm32_boards.c +++ b/hw/lm32/lm32_boards.c @@ -18,6 +18,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/hw.h" #include "hw/block/flash.h" diff --git a/hw/lm32/lm32_hwsetup.h b/hw/lm32/lm32_hwsetup.h index 838754d5d8..b71e6eafba 100644 --- a/hw/lm32/lm32_hwsetup.h +++ b/hw/lm32/lm32_hwsetup.h @@ -26,6 +26,7 @@ #define QEMU_HW_LM32_HWSETUP_H #include "qemu-common.h" +#include "qemu/cutils.h" #include "hw/loader.h" typedef struct { diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c index f71492ef7e..96e6f4dc2e 100644 --- a/hw/lm32/milkymist.c +++ b/hw/lm32/milkymist.c @@ -18,6 +18,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/hw.h" #include "hw/block/flash.h" @@ -31,6 +33,7 @@ #include "milkymist-hw.h" #include "lm32.h" #include "exec/address-spaces.h" +#include "qemu/cutils.h" #define BIOS_FILENAME "mmone-bios.bin" #define BIOS_OFFSET 0x00860000 diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c index 85f72770d7..142bab98c9 100644 --- a/hw/m68k/an5206.c +++ b/hw/m68k/an5206.c @@ -7,6 +7,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/m68k/mcf.h" #include "hw/boards.h" diff --git a/hw/m68k/dummy_m68k.c b/hw/m68k/dummy_m68k.c index 3c2174b505..0b11d2074a 100644 --- a/hw/m68k/dummy_m68k.c +++ b/hw/m68k/dummy_m68k.c @@ -7,6 +7,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/boards.h" #include "hw/loader.h" diff --git a/hw/m68k/mcf5206.c b/hw/m68k/mcf5206.c index 7fd3275b05..e14896e529 100644 --- a/hw/m68k/mcf5206.c +++ b/hw/m68k/mcf5206.c @@ -6,6 +6,8 @@ * This code is licensed under the GPL */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/m68k/mcf.h" #include "qemu/timer.h" diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c index 4f49d34a8f..24155574f2 100644 --- a/hw/m68k/mcf5208.c +++ b/hw/m68k/mcf5208.c @@ -6,6 +6,9 @@ * This code is licensed under the GPL */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/m68k/mcf.h" #include "qemu/timer.h" diff --git a/hw/m68k/mcf_intc.c b/hw/m68k/mcf_intc.c index ff95513582..cf581324eb 100644 --- a/hw/m68k/mcf_intc.c +++ b/hw/m68k/mcf_intc.c @@ -6,6 +6,8 @@ * This code is licensed under the GPL */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/m68k/mcf.h" #include "exec/address-spaces.h" diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index c4b44300eb..9e7de56829 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "hw/mem/pc-dimm.h" +#include "qapi/error.h" #include "qemu/config-file.h" #include "qapi/visitor.h" #include "qemu/range.h" diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c index c24014a1f3..9eebb1a521 100644 --- a/hw/microblaze/boot.c +++ b/hw/microblaze/boot.c @@ -25,6 +25,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "qemu/option.h" #include "qemu/config-file.h" #include "qemu/error-report.h" @@ -33,6 +35,7 @@ #include "sysemu/sysemu.h" #include "hw/loader.h" #include "elf.h" +#include "qemu/cutils.h" #include "boot.h" diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c index 85e974b72a..07527b677b 100644 --- a/hw/microblaze/petalogix_ml605_mmu.c +++ b/hw/microblaze/petalogix_ml605_mmu.c @@ -26,6 +26,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/hw.h" #include "net/net.h" diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c index 606ba1f01a..f821e1cfef 100644 --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c @@ -24,6 +24,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/hw.h" #include "net/net.h" diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c index 4e5581b167..bdb716e725 100644 --- a/hw/mips/mips_fulong2e.c +++ b/hw/mips/mips_fulong2e.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/i386/pc.h" #include "hw/char/serial.h" diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c index 4931cb1bf4..ac7c641258 100644 --- a/hw/mips/mips_jazz.c +++ b/hw/mips/mips_jazz.c @@ -45,6 +45,7 @@ #include "exec/address-spaces.h" #include "sysemu/qtest.h" #include "qemu/error-report.h" +#include "qemu/help_option.h" enum jazz_model_e { diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index f5173c42de..4ff1bb2562 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -23,6 +23,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/i386/pc.h" #include "hw/char/serial.h" diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c index 1ecff44a54..a2c2a1646e 100644 --- a/hw/mips/mips_mipssim.c +++ b/hw/mips/mips_mipssim.c @@ -25,6 +25,9 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/mips/mips.h" #include "hw/mips/cpudevs.h" diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c index 724b1e9d51..21aca981c2 100644 --- a/hw/mips/mips_r4k.c +++ b/hw/mips/mips_r4k.c @@ -8,6 +8,9 @@ * the standard PC ISA addresses. */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/mips/mips.h" #include "hw/mips/cpudevs.h" diff --git a/hw/misc/arm_sysctl.c b/hw/misc/arm_sysctl.c index 339205b5c3..34d90d5230 100644 --- a/hw/misc/arm_sysctl.c +++ b/hw/misc/arm_sysctl.c @@ -171,7 +171,8 @@ static uint64_t arm_sysctl_read(void *opaque, hwaddr offset, case 0x58: /* BOOTCS */ return 0; case 0x5c: /* 24MHz */ - return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24000000, get_ticks_per_sec()); + return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24000000, + NANOSECONDS_PER_SECOND); case 0x60: /* MISC */ return 0; case 0x84: /* PROCID0 */ diff --git a/hw/misc/bcm2835_mbox.c b/hw/misc/bcm2835_mbox.c index 106585a7bf..263280fd49 100644 --- a/hw/misc/bcm2835_mbox.c +++ b/hw/misc/bcm2835_mbox.c @@ -9,6 +9,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/misc/bcm2835_mbox.h" #define MAIL0_PEEK 0x90 diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c index 15dcc02f99..530411f841 100644 --- a/hw/misc/bcm2835_property.c +++ b/hw/misc/bcm2835_property.c @@ -4,6 +4,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/misc/bcm2835_property.h" #include "hw/misc/bcm2835_mbox_defs.h" #include "sysemu/dma.h" diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c index fafe0709ec..0c207e3104 100644 --- a/hw/misc/cbus.c +++ b/hw/misc/cbus.c @@ -21,7 +21,7 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "hw/hw.h" #include "hw/irq.h" #include "hw/devices.h" #include "sysemu/sysemu.h" diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c index 1838bc8506..2eb866899a 100644 --- a/hw/misc/ivshmem.c +++ b/hw/misc/ivshmem.c @@ -17,6 +17,8 @@ * GNU GPL, version 2 or (at your option) any later version. */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/cutils.h" #include "hw/hw.h" #include "hw/i386/pc.h" #include "hw/pci/pci.h" @@ -26,9 +28,10 @@ #include "migration/migration.h" #include "qemu/error-report.h" #include "qemu/event_notifier.h" -#include "qemu/fifo8.h" +#include "qom/object_interfaces.h" #include "sysemu/char.h" #include "sysemu/hostmem.h" +#include "sysemu/qtest.h" #include "qapi/visitor.h" #include "exec/ram_addr.h" @@ -39,22 +42,31 @@ #define PCI_VENDOR_ID_IVSHMEM PCI_VENDOR_ID_REDHAT_QUMRANET #define PCI_DEVICE_ID_IVSHMEM 0x1110 -#define IVSHMEM_MAX_PEERS G_MAXUINT16 +#define IVSHMEM_MAX_PEERS UINT16_MAX #define IVSHMEM_IOEVENTFD 0 #define IVSHMEM_MSI 1 -#define IVSHMEM_PEER 0 -#define IVSHMEM_MASTER 1 - #define IVSHMEM_REG_BAR_SIZE 0x100 -//#define DEBUG_IVSHMEM -#ifdef DEBUG_IVSHMEM -#define IVSHMEM_DPRINTF(fmt, ...) \ - do {printf("IVSHMEM: " fmt, ## __VA_ARGS__); } while (0) -#else -#define IVSHMEM_DPRINTF(fmt, ...) -#endif +#define IVSHMEM_DEBUG 0 +#define IVSHMEM_DPRINTF(fmt, ...) \ + do { \ + if (IVSHMEM_DEBUG) { \ + printf("IVSHMEM: " fmt, ## __VA_ARGS__); \ + } \ + } while (0) + +#define TYPE_IVSHMEM_COMMON "ivshmem-common" +#define IVSHMEM_COMMON(obj) \ + OBJECT_CHECK(IVShmemState, (obj), TYPE_IVSHMEM_COMMON) + +#define TYPE_IVSHMEM_PLAIN "ivshmem-plain" +#define IVSHMEM_PLAIN(obj) \ + OBJECT_CHECK(IVShmemState, (obj), TYPE_IVSHMEM_PLAIN) + +#define TYPE_IVSHMEM_DOORBELL "ivshmem-doorbell" +#define IVSHMEM_DOORBELL(obj) \ + OBJECT_CHECK(IVShmemState, (obj), TYPE_IVSHMEM_DOORBELL) #define TYPE_IVSHMEM "ivshmem" #define IVSHMEM(obj) \ @@ -75,38 +87,40 @@ typedef struct IVShmemState { PCIDevice parent_obj; /*< public >*/ - HostMemoryBackend *hostmem; + uint32_t features; + + /* exactly one of these two may be set */ + HostMemoryBackend *hostmem; /* with interrupts */ + CharDriverState *server_chr; /* without interrupts */ + + /* registers */ uint32_t intrmask; uint32_t intrstatus; + int vm_id; - CharDriverState **eventfd_chr; - CharDriverState *server_chr; - Fifo8 incoming_fifo; - MemoryRegion ivshmem_mmio; - - /* We might need to register the BAR before we actually have the memory. - * So prepare a container MemoryRegion for the BAR immediately and - * add a subregion when we have the memory. - */ - MemoryRegion bar; - MemoryRegion ivshmem; - uint64_t ivshmem_size; /* size of shared memory region */ - uint32_t ivshmem_64bit; + /* BARs */ + MemoryRegion ivshmem_mmio; /* BAR 0 (registers) */ + MemoryRegion *ivshmem_bar2; /* BAR 2 (shared memory) */ + MemoryRegion server_bar2; /* used with server_chr */ + /* interrupt support */ Peer *peers; - int nb_peers; /* how many peers we have space for */ - - int vm_id; + int nb_peers; /* space in @peers[] */ uint32_t vectors; - uint32_t features; MSIVector *msi_vectors; + uint64_t msg_buf; /* buffer for receiving server messages */ + int msg_buffered_bytes; /* #bytes in @msg_buf */ + /* migration stuff */ + OnOffAuto master; Error *migration_blocker; - char * shmobj; - char * sizearg; - char * role; - int role_val; /* scalar to avoid multiple string comparisons */ + /* legacy cruft */ + char *role; + char *shmobj; + char *sizearg; + size_t legacy_size; + uint32_t not_legacy_32bit; } IVShmemState; /* registers for the Inter-VM shared memory device */ @@ -122,12 +136,34 @@ static inline uint32_t ivshmem_has_feature(IVShmemState *ivs, return (ivs->features & (1 << feature)); } -/* accessing registers - based on rtl8139 */ +static inline bool ivshmem_is_master(IVShmemState *s) +{ + assert(s->master != ON_OFF_AUTO_AUTO); + return s->master == ON_OFF_AUTO_ON; +} + static void ivshmem_update_irq(IVShmemState *s) { PCIDevice *d = PCI_DEVICE(s); - int isr; - isr = (s->intrstatus & s->intrmask) & 0xffffffff; + uint32_t isr = s->intrstatus & s->intrmask; + + /* + * Do nothing unless the device actually uses INTx. Here's how + * the device variants signal interrupts, what they put in PCI + * config space: + * Device variant Interrupt Interrupt Pin MSI-X cap. + * ivshmem-plain none 0 no + * ivshmem-doorbell MSI-X 1 yes(1) + * ivshmem,msi=off INTx 1 no + * ivshmem,msi=on MSI-X 1(2) yes(1) + * (1) if guest enabled MSI-X + * (2) the device lies + * Leads to the condition for doing nothing: + */ + if (ivshmem_has_feature(s, IVSHMEM_MSI) + || !d->config[PCI_INTERRUPT_PIN]) { + return; + } /* don't print ISR resets */ if (isr) { @@ -135,7 +171,7 @@ static void ivshmem_update_irq(IVShmemState *s) isr ? 1 : 0, s->intrstatus, s->intrmask); } - pci_set_irq(d, (isr != 0)); + pci_set_irq(d, isr != 0); } static void ivshmem_IntrMask_write(IVShmemState *s, uint32_t val) @@ -143,7 +179,6 @@ static void ivshmem_IntrMask_write(IVShmemState *s, uint32_t val) IVSHMEM_DPRINTF("IntrMask write(w) val = 0x%04x\n", val); s->intrmask = val; - ivshmem_update_irq(s); } @@ -152,7 +187,6 @@ static uint32_t ivshmem_IntrMask_read(IVShmemState *s) uint32_t ret = s->intrmask; IVSHMEM_DPRINTF("intrmask read(w) val = 0x%04x\n", ret); - return ret; } @@ -161,7 +195,6 @@ static void ivshmem_IntrStatus_write(IVShmemState *s, uint32_t val) IVSHMEM_DPRINTF("IntrStatus write(w) val = 0x%04x\n", val); s->intrstatus = val; - ivshmem_update_irq(s); } @@ -171,9 +204,7 @@ static uint32_t ivshmem_IntrStatus_read(IVShmemState *s) /* reading ISR clears all interrupts */ s->intrstatus = 0; - ivshmem_update_irq(s); - return ret; } @@ -237,12 +268,7 @@ static uint64_t ivshmem_io_read(void *opaque, hwaddr addr, break; case IVPOSITION: - /* return my VM ID if the memory is mapped */ - if (memory_region_is_mapped(&s->ivshmem)) { - ret = s->vm_id; - } else { - ret = -1; - } + ret = s->vm_id; break; default: @@ -263,21 +289,11 @@ static const MemoryRegionOps ivshmem_mmio_ops = { }, }; -static int ivshmem_can_receive(void * opaque) -{ - return sizeof(int64_t); -} - -static void ivshmem_event(void *opaque, int event) -{ - IVSHMEM_DPRINTF("ivshmem_event %d\n", event); -} - static void ivshmem_vector_notify(void *opaque) { MSIVector *entry = opaque; PCIDevice *pdev = entry->pdev; - IVShmemState *s = IVSHMEM(pdev); + IVShmemState *s = IVSHMEM_COMMON(pdev); int vector = entry - s->msi_vectors; EventNotifier *n = &s->peers[s->vm_id].eventfds[vector]; @@ -287,7 +303,9 @@ static void ivshmem_vector_notify(void *opaque) IVSHMEM_DPRINTF("interrupt on vector %p %d\n", pdev, vector); if (ivshmem_has_feature(s, IVSHMEM_MSI)) { - msix_notify(pdev, vector); + if (msix_enabled(pdev)) { + msix_notify(pdev, vector); + } } else { ivshmem_IntrStatus_write(s, 1); } @@ -296,7 +314,7 @@ static void ivshmem_vector_notify(void *opaque) static int ivshmem_vector_unmask(PCIDevice *dev, unsigned vector, MSIMessage msg) { - IVShmemState *s = IVSHMEM(dev); + IVShmemState *s = IVSHMEM_COMMON(dev); EventNotifier *n = &s->peers[s->vm_id].eventfds[vector]; MSIVector *v = &s->msi_vectors[vector]; int ret; @@ -313,7 +331,7 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned vector, static void ivshmem_vector_mask(PCIDevice *dev, unsigned vector) { - IVShmemState *s = IVSHMEM(dev); + IVShmemState *s = IVSHMEM_COMMON(dev); EventNotifier *n = &s->peers[s->vm_id].eventfds[vector]; int ret; @@ -330,7 +348,7 @@ static void ivshmem_vector_poll(PCIDevice *dev, unsigned int vector_start, unsigned int vector_end) { - IVShmemState *s = IVSHMEM(dev); + IVShmemState *s = IVSHMEM_COMMON(dev); unsigned int vector; IVSHMEM_DPRINTF("vector poll %p %d-%d\n", dev, vector_start, vector_end); @@ -355,61 +373,13 @@ static void watch_vector_notifier(IVShmemState *s, EventNotifier *n, { int eventfd = event_notifier_get_fd(n); - /* if MSI is supported we need multiple interrupts */ + assert(!s->msi_vectors[vector].pdev); s->msi_vectors[vector].pdev = PCI_DEVICE(s); qemu_set_fd_handler(eventfd, ivshmem_vector_notify, NULL, &s->msi_vectors[vector]); } -static int check_shm_size(IVShmemState *s, int fd, Error **errp) -{ - /* check that the guest isn't going to try and map more memory than the - * the object has allocated return -1 to indicate error */ - - struct stat buf; - - if (fstat(fd, &buf) < 0) { - error_setg(errp, "exiting: fstat on fd %d failed: %s", - fd, strerror(errno)); - return -1; - } - - if (s->ivshmem_size > buf.st_size) { - error_setg(errp, "Requested memory size greater" - " than shared object size (%" PRIu64 " > %" PRIu64")", - s->ivshmem_size, (uint64_t)buf.st_size); - return -1; - } else { - return 0; - } -} - -/* create the shared memory BAR when we are not using the server, so we can - * create the BAR and map the memory immediately */ -static int create_shared_memory_BAR(IVShmemState *s, int fd, uint8_t attr, - Error **errp) -{ - void * ptr; - - ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (ptr == MAP_FAILED) { - error_setg_errno(errp, errno, "Failed to mmap shared memory"); - return -1; - } - - memory_region_init_ram_ptr(&s->ivshmem, OBJECT(s), "ivshmem.bar2", - s->ivshmem_size, ptr); - qemu_set_ram_fd(memory_region_get_ram_addr(&s->ivshmem), fd); - vmstate_register_ram(&s->ivshmem, DEVICE(s)); - memory_region_add_subregion(&s->bar, 0, &s->ivshmem); - - /* region for shared memory */ - pci_register_bar(PCI_DEVICE(s), 2, attr, &s->bar); - - return 0; -} - static void ivshmem_add_eventfd(IVShmemState *s, int posn, int i) { memory_region_add_eventfd(&s->ivshmem_mmio, @@ -434,21 +404,17 @@ static void close_peer_eventfds(IVShmemState *s, int posn) { int i, n; - if (!ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { - return; - } - if (posn < 0 || posn >= s->nb_peers) { - error_report("invalid peer %d", posn); - return; - } - + assert(posn >= 0 && posn < s->nb_peers); n = s->peers[posn].nb_eventfds; - memory_region_transaction_begin(); - for (i = 0; i < n; i++) { - ivshmem_del_eventfd(s, posn, i); + if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { + memory_region_transaction_begin(); + for (i = 0; i < n; i++) { + ivshmem_del_eventfd(s, posn, i); + } + memory_region_transaction_commit(); } - memory_region_transaction_commit(); + for (i = 0; i < n; i++) { event_notifier_cleanup(&s->peers[posn].eventfds[i]); } @@ -457,286 +423,320 @@ static void close_peer_eventfds(IVShmemState *s, int posn) s->peers[posn].nb_eventfds = 0; } -/* this function increase the dynamic storage need to store data about other - * peers */ -static int resize_peers(IVShmemState *s, int new_min_size) -{ - - int j, old_size; - - /* limit number of max peers */ - if (new_min_size <= 0 || new_min_size > IVSHMEM_MAX_PEERS) { - return -1; - } - if (new_min_size <= s->nb_peers) { - return 0; - } - - old_size = s->nb_peers; - s->nb_peers = new_min_size; - - IVSHMEM_DPRINTF("bumping storage to %d peers\n", s->nb_peers); - - s->peers = g_realloc(s->peers, s->nb_peers * sizeof(Peer)); - - for (j = old_size; j < s->nb_peers; j++) { - s->peers[j].eventfds = g_new0(EventNotifier, s->vectors); - s->peers[j].nb_eventfds = 0; - } - - return 0; -} - -static bool fifo_update_and_get(IVShmemState *s, const uint8_t *buf, int size, - void *data, size_t len) +static void resize_peers(IVShmemState *s, int nb_peers) { - const uint8_t *p; - uint32_t num; - - assert(len <= sizeof(int64_t)); /* limitation of the fifo */ - if (fifo8_is_empty(&s->incoming_fifo) && size == len) { - memcpy(data, buf, size); - return true; - } - - IVSHMEM_DPRINTF("short read of %d bytes\n", size); - - num = MIN(size, sizeof(int64_t) - fifo8_num_used(&s->incoming_fifo)); - fifo8_push_all(&s->incoming_fifo, buf, num); - - if (fifo8_num_used(&s->incoming_fifo) < len) { - assert(num == 0); - return false; - } - - size -= num; - buf += num; - p = fifo8_pop_buf(&s->incoming_fifo, len, &num); - assert(num == len); - - memcpy(data, p, len); + int old_nb_peers = s->nb_peers; + int i; - if (size > 0) { - fifo8_push_all(&s->incoming_fifo, buf, size); - } + assert(nb_peers > old_nb_peers); + IVSHMEM_DPRINTF("bumping storage to %d peers\n", nb_peers); - return true; -} + s->peers = g_realloc(s->peers, nb_peers * sizeof(Peer)); + s->nb_peers = nb_peers; -static bool fifo_update_and_get_i64(IVShmemState *s, - const uint8_t *buf, int size, int64_t *i64) -{ - if (fifo_update_and_get(s, buf, size, i64, sizeof(*i64))) { - *i64 = GINT64_FROM_LE(*i64); - return true; + for (i = old_nb_peers; i < nb_peers; i++) { + s->peers[i].eventfds = g_new0(EventNotifier, s->vectors); + s->peers[i].nb_eventfds = 0; } - - return false; } -static int ivshmem_add_kvm_msi_virq(IVShmemState *s, int vector) +static void ivshmem_add_kvm_msi_virq(IVShmemState *s, int vector, + Error **errp) { PCIDevice *pdev = PCI_DEVICE(s); MSIMessage msg = msix_get_message(pdev, vector); int ret; IVSHMEM_DPRINTF("ivshmem_add_kvm_msi_virq vector:%d\n", vector); - - if (s->msi_vectors[vector].pdev != NULL) { - return 0; - } + assert(!s->msi_vectors[vector].pdev); ret = kvm_irqchip_add_msi_route(kvm_state, msg, pdev); if (ret < 0) { - error_report("ivshmem: kvm_irqchip_add_msi_route failed"); - return -1; + error_setg(errp, "kvm_irqchip_add_msi_route failed"); + return; } s->msi_vectors[vector].virq = ret; s->msi_vectors[vector].pdev = pdev; - - return 0; } -static void setup_interrupt(IVShmemState *s, int vector) +static void setup_interrupt(IVShmemState *s, int vector, Error **errp) { EventNotifier *n = &s->peers[s->vm_id].eventfds[vector]; bool with_irqfd = kvm_msi_via_irqfd_enabled() && ivshmem_has_feature(s, IVSHMEM_MSI); PCIDevice *pdev = PCI_DEVICE(s); + Error *err = NULL; IVSHMEM_DPRINTF("setting up interrupt for vector: %d\n", vector); if (!with_irqfd) { - IVSHMEM_DPRINTF("with eventfd"); + IVSHMEM_DPRINTF("with eventfd\n"); watch_vector_notifier(s, n, vector); } else if (msix_enabled(pdev)) { - IVSHMEM_DPRINTF("with irqfd"); - if (ivshmem_add_kvm_msi_virq(s, vector) < 0) { + IVSHMEM_DPRINTF("with irqfd\n"); + ivshmem_add_kvm_msi_virq(s, vector, &err); + if (err) { + error_propagate(errp, err); return; } if (!msix_is_masked(pdev, vector)) { kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, s->msi_vectors[vector].virq); + /* TODO handle error */ } } else { /* it will be delayed until msix is enabled, in write_config */ - IVSHMEM_DPRINTF("with irqfd, delayed until msix enabled"); + IVSHMEM_DPRINTF("with irqfd, delayed until msix enabled\n"); } } -static void ivshmem_read(void *opaque, const uint8_t *buf, int size) +static void process_msg_shmem(IVShmemState *s, int fd, Error **errp) { - IVShmemState *s = opaque; - int incoming_fd; - int new_eventfd; - int64_t incoming_posn; - Error *err = NULL; - Peer *peer; + struct stat buf; + size_t size; + void *ptr; - if (!fifo_update_and_get_i64(s, buf, size, &incoming_posn)) { + if (s->ivshmem_bar2) { + error_setg(errp, "server sent unexpected shared memory message"); + close(fd); return; } - if (incoming_posn < -1) { - IVSHMEM_DPRINTF("invalid incoming_posn %" PRId64 "\n", incoming_posn); + if (fstat(fd, &buf) < 0) { + error_setg_errno(errp, errno, + "can't determine size of shared memory sent by server"); + close(fd); return; } - /* pick off s->server_chr->msgfd and store it, posn should accompany msg */ - incoming_fd = qemu_chr_fe_get_msgfd(s->server_chr); - IVSHMEM_DPRINTF("posn is %" PRId64 ", fd is %d\n", - incoming_posn, incoming_fd); - - /* make sure we have enough space for this peer */ - if (incoming_posn >= s->nb_peers) { - if (resize_peers(s, incoming_posn + 1) < 0) { - error_report("failed to resize peers array"); - if (incoming_fd != -1) { - close(incoming_fd); - } + size = buf.st_size; + + /* Legacy cruft */ + if (s->legacy_size != SIZE_MAX) { + if (size < s->legacy_size) { + error_setg(errp, "server sent only %zd bytes of shared memory", + (size_t)buf.st_size); + close(fd); return; } + size = s->legacy_size; } - peer = &s->peers[incoming_posn]; + /* mmap the region and map into the BAR2 */ + ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (ptr == MAP_FAILED) { + error_setg_errno(errp, errno, "Failed to mmap shared memory"); + close(fd); + return; + } + memory_region_init_ram_ptr(&s->server_bar2, OBJECT(s), + "ivshmem.bar2", size, ptr); + qemu_set_ram_fd(memory_region_get_ram_addr(&s->server_bar2), fd); + s->ivshmem_bar2 = &s->server_bar2; +} - if (incoming_fd == -1) { - /* if posn is positive and unseen before then this is our posn*/ - if (incoming_posn >= 0 && s->vm_id == -1) { - /* receive our posn */ - s->vm_id = incoming_posn; - } else { - /* otherwise an fd == -1 means an existing peer has gone away */ - IVSHMEM_DPRINTF("posn %" PRId64 " has gone away\n", incoming_posn); - close_peer_eventfds(s, incoming_posn); - } +static void process_msg_disconnect(IVShmemState *s, uint16_t posn, + Error **errp) +{ + IVSHMEM_DPRINTF("posn %d has gone away\n", posn); + if (posn >= s->nb_peers || posn == s->vm_id) { + error_setg(errp, "invalid peer %d", posn); return; } + close_peer_eventfds(s, posn); +} - /* if the position is -1, then it's shared memory region fd */ - if (incoming_posn == -1) { - void * map_ptr; +static void process_msg_connect(IVShmemState *s, uint16_t posn, int fd, + Error **errp) +{ + Peer *peer = &s->peers[posn]; + int vector; - if (memory_region_is_mapped(&s->ivshmem)) { - error_report("shm already initialized"); - close(incoming_fd); - return; - } + /* + * The N-th connect message for this peer comes with the file + * descriptor for vector N-1. Count messages to find the vector. + */ + if (peer->nb_eventfds >= s->vectors) { + error_setg(errp, "Too many eventfd received, device has %d vectors", + s->vectors); + close(fd); + return; + } + vector = peer->nb_eventfds++; - if (check_shm_size(s, incoming_fd, &err) == -1) { - error_report_err(err); - close(incoming_fd); - return; - } + IVSHMEM_DPRINTF("eventfds[%d][%d] = %d\n", posn, vector, fd); + event_notifier_init_fd(&peer->eventfds[vector], fd); + fcntl_setfl(fd, O_NONBLOCK); /* msix/irqfd poll non block */ - /* mmap the region and map into the BAR2 */ - map_ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, - incoming_fd, 0); - if (map_ptr == MAP_FAILED) { - error_report("Failed to mmap shared memory %s", strerror(errno)); - close(incoming_fd); - return; - } - memory_region_init_ram_ptr(&s->ivshmem, OBJECT(s), - "ivshmem.bar2", s->ivshmem_size, map_ptr); - qemu_set_ram_fd(memory_region_get_ram_addr(&s->ivshmem), - incoming_fd); - vmstate_register_ram(&s->ivshmem, DEVICE(s)); + if (posn == s->vm_id) { + setup_interrupt(s, vector, errp); + /* TODO do we need to handle the error? */ + } - IVSHMEM_DPRINTF("guest h/w addr = %p, size = %" PRIu64 "\n", - map_ptr, s->ivshmem_size); + if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { + ivshmem_add_eventfd(s, posn, vector); + } +} - memory_region_add_subregion(&s->bar, 0, &s->ivshmem); +static void process_msg(IVShmemState *s, int64_t msg, int fd, Error **errp) +{ + IVSHMEM_DPRINTF("posn is %" PRId64 ", fd is %d\n", msg, fd); + if (msg < -1 || msg > IVSHMEM_MAX_PEERS) { + error_setg(errp, "server sent invalid message %" PRId64, msg); + close(fd); return; } - /* each peer has an associated array of eventfds, and we keep - * track of how many eventfds received so far */ - /* get a new eventfd: */ - if (peer->nb_eventfds >= s->vectors) { - error_report("Too many eventfd received, device has %d vectors", - s->vectors); - close(incoming_fd); + if (msg == -1) { + process_msg_shmem(s, fd, errp); return; } - new_eventfd = peer->nb_eventfds++; + if (msg >= s->nb_peers) { + resize_peers(s, msg + 1); + } - /* this is an eventfd for a particular peer VM */ - IVSHMEM_DPRINTF("eventfds[%" PRId64 "][%d] = %d\n", incoming_posn, - new_eventfd, incoming_fd); - event_notifier_init_fd(&peer->eventfds[new_eventfd], incoming_fd); - fcntl_setfl(incoming_fd, O_NONBLOCK); /* msix/irqfd poll non block */ + if (fd >= 0) { + process_msg_connect(s, msg, fd, errp); + } else { + process_msg_disconnect(s, msg, errp); + } +} + +static int ivshmem_can_receive(void *opaque) +{ + IVShmemState *s = opaque; + + assert(s->msg_buffered_bytes < sizeof(s->msg_buf)); + return sizeof(s->msg_buf) - s->msg_buffered_bytes; +} + +static void ivshmem_read(void *opaque, const uint8_t *buf, int size) +{ + IVShmemState *s = opaque; + Error *err = NULL; + int fd; + int64_t msg; - if (incoming_posn == s->vm_id) { - setup_interrupt(s, new_eventfd); + assert(size >= 0 && s->msg_buffered_bytes + size <= sizeof(s->msg_buf)); + memcpy((unsigned char *)&s->msg_buf + s->msg_buffered_bytes, buf, size); + s->msg_buffered_bytes += size; + if (s->msg_buffered_bytes < sizeof(s->msg_buf)) { + return; } + msg = le64_to_cpu(s->msg_buf); + s->msg_buffered_bytes = 0; - if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { - ivshmem_add_eventfd(s, incoming_posn, new_eventfd); + fd = qemu_chr_fe_get_msgfd(s->server_chr); + IVSHMEM_DPRINTF("posn is %" PRId64 ", fd is %d\n", msg, fd); + + process_msg(s, msg, fd, &err); + if (err) { + error_report_err(err); } } -static void ivshmem_check_version(void *opaque, const uint8_t * buf, int size) +static int64_t ivshmem_recv_msg(IVShmemState *s, int *pfd, Error **errp) { - IVShmemState *s = opaque; - int tmp; - int64_t version; + int64_t msg; + int n, ret; + + n = 0; + do { + ret = qemu_chr_fe_read_all(s->server_chr, (uint8_t *)&msg + n, + sizeof(msg) - n); + if (ret < 0 && ret != -EINTR) { + error_setg_errno(errp, -ret, "read from server failed"); + return INT64_MIN; + } + n += ret; + } while (n < sizeof(msg)); - if (!fifo_update_and_get_i64(s, buf, size, &version)) { + *pfd = qemu_chr_fe_get_msgfd(s->server_chr); + return msg; +} + +static void ivshmem_recv_setup(IVShmemState *s, Error **errp) +{ + Error *err = NULL; + int64_t msg; + int fd; + + msg = ivshmem_recv_msg(s, &fd, &err); + if (err) { + error_propagate(errp, err); + return; + } + if (msg != IVSHMEM_PROTOCOL_VERSION) { + error_setg(errp, "server sent version %" PRId64 ", expecting %d", + msg, IVSHMEM_PROTOCOL_VERSION); + return; + } + if (fd != -1) { + error_setg(errp, "server sent invalid version message"); return; } - tmp = qemu_chr_fe_get_msgfd(s->server_chr); - if (tmp != -1 || version != IVSHMEM_PROTOCOL_VERSION) { - fprintf(stderr, "incompatible version, you are connecting to a ivshmem-" - "server using a different protocol please check your setup\n"); - qemu_chr_delete(s->server_chr); - s->server_chr = NULL; + /* + * ivshmem-server sends the remaining initial messages in a fixed + * order, but the device has always accepted them in any order. + * Stay as compatible as practical, just in case people use + * servers that behave differently. + */ + + /* + * ivshmem_device_spec.txt has always required the ID message + * right here, and ivshmem-server has always complied. However, + * older versions of the device accepted it out of order, but + * broke when an interrupt setup message arrived before it. + */ + msg = ivshmem_recv_msg(s, &fd, &err); + if (err) { + error_propagate(errp, err); return; } + if (fd != -1 || msg < 0 || msg > IVSHMEM_MAX_PEERS) { + error_setg(errp, "server sent invalid ID message"); + return; + } + s->vm_id = msg; + + /* + * Receive more messages until we got shared memory. + */ + do { + msg = ivshmem_recv_msg(s, &fd, &err); + if (err) { + error_propagate(errp, err); + return; + } + process_msg(s, msg, fd, &err); + if (err) { + error_propagate(errp, err); + return; + } + } while (msg != -1); - IVSHMEM_DPRINTF("version check ok, switch to real chardev handler\n"); - qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive, ivshmem_read, - ivshmem_event, s); + /* + * This function must either map the shared memory or fail. The + * loop above ensures that: it terminates normally only after it + * successfully processed the server's shared memory message. + * Assert that actually mapped the shared memory: + */ + assert(s->ivshmem_bar2); } /* Select the MSI-X vectors used by device. * ivshmem maps events to vectors statically, so * we just enable all vectors on init and after reset. */ -static void ivshmem_use_msix(IVShmemState * s) +static void ivshmem_msix_vector_use(IVShmemState *s) { PCIDevice *d = PCI_DEVICE(s); int i; - IVSHMEM_DPRINTF("%s, msix present: %d\n", __func__, msix_present(d)); - if (!msix_present(d)) { - return; - } - for (i = 0; i < s->vectors; i++) { msix_vector_use(d, i); } @@ -744,11 +744,13 @@ static void ivshmem_use_msix(IVShmemState * s) static void ivshmem_reset(DeviceState *d) { - IVShmemState *s = IVSHMEM(d); + IVShmemState *s = IVSHMEM_COMMON(d); s->intrstatus = 0; s->intrmask = 0; - ivshmem_use_msix(s); + if (ivshmem_has_feature(s, IVSHMEM_MSI)) { + ivshmem_msix_vector_use(s); + } } static int ivshmem_setup_interrupts(IVShmemState *s) @@ -762,7 +764,7 @@ static int ivshmem_setup_interrupts(IVShmemState *s) } IVSHMEM_DPRINTF("msix initialized (%d vectors)\n", s->vectors); - ivshmem_use_msix(s); + ivshmem_msix_vector_use(s); } return 0; @@ -774,7 +776,13 @@ static void ivshmem_enable_irqfd(IVShmemState *s) int i; for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) { - ivshmem_add_kvm_msi_virq(s, i); + Error *err = NULL; + + ivshmem_add_kvm_msi_virq(s, i, &err); + if (err) { + error_report_err(err); + /* TODO do we need to handle the error? */ + } } if (msix_set_vector_notifiers(pdev, @@ -814,13 +822,13 @@ static void ivshmem_disable_irqfd(IVShmemState *s) static void ivshmem_write_config(PCIDevice *pdev, uint32_t address, uint32_t val, int len) { - IVShmemState *s = IVSHMEM(pdev); + IVShmemState *s = IVSHMEM_COMMON(pdev); int is_enabled, was_enabled = msix_enabled(pdev); pci_default_write_config(pdev, address, val, len); is_enabled = msix_enabled(pdev); - if (kvm_msi_via_irqfd_enabled() && s->vm_id != -1) { + if (kvm_msi_via_irqfd_enabled()) { if (!was_enabled && is_enabled) { ivshmem_enable_irqfd(s); } else if (was_enabled && !is_enabled) { @@ -829,42 +837,14 @@ static void ivshmem_write_config(PCIDevice *pdev, uint32_t address, } } -static void pci_ivshmem_realize(PCIDevice *dev, Error **errp) +static void ivshmem_common_realize(PCIDevice *dev, Error **errp) { - IVShmemState *s = IVSHMEM(dev); + IVShmemState *s = IVSHMEM_COMMON(dev); + Error *err = NULL; uint8_t *pci_conf; uint8_t attr = PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_PREFETCH; - if (!!s->server_chr + !!s->shmobj + !!s->hostmem != 1) { - error_setg(errp, - "You must specify either 'shm', 'chardev' or 'x-memdev'"); - return; - } - - if (s->hostmem) { - MemoryRegion *mr; - - if (s->sizearg) { - g_warning("size argument ignored with hostmem"); - } - - mr = host_memory_backend_get_memory(s->hostmem, errp); - s->ivshmem_size = memory_region_size(mr); - } else if (s->sizearg == NULL) { - s->ivshmem_size = 4 << 20; /* 4 MB default */ - } else { - char *end; - int64_t size = qemu_strtosz(s->sizearg, &end); - if (size < 0 || *end != '\0' || !is_power_of_2(size)) { - error_setg(errp, "Invalid size %s", s->sizearg); - return; - } - s->ivshmem_size = size; - } - - fifo8_create(&s->incoming_fifo, sizeof(int64_t)); - /* IRQFD requires MSI */ if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD) && !ivshmem_has_feature(s, IVSHMEM_MSI)) { @@ -872,31 +852,9 @@ static void pci_ivshmem_realize(PCIDevice *dev, Error **errp) return; } - /* check that role is reasonable */ - if (s->role) { - if (strncmp(s->role, "peer", 5) == 0) { - s->role_val = IVSHMEM_PEER; - } else if (strncmp(s->role, "master", 7) == 0) { - s->role_val = IVSHMEM_MASTER; - } else { - error_setg(errp, "'role' must be 'peer' or 'master'"); - return; - } - } else { - s->role_val = IVSHMEM_MASTER; /* default */ - } - - if (s->role_val == IVSHMEM_PEER) { - error_setg(&s->migration_blocker, - "Migration is disabled when using feature 'peer mode' in device 'ivshmem'"); - migrate_add_blocker(s->migration_blocker); - } - pci_conf = dev->config; pci_conf[PCI_COMMAND] = PCI_COMMAND_IO | PCI_COMMAND_MEMORY; - pci_config_set_interrupt_pin(pci_conf, 1); - memory_region_init_io(&s->ivshmem_mmio, OBJECT(s), &ivshmem_mmio_ops, s, "ivshmem-mmio", IVSHMEM_REG_BAR_SIZE); @@ -904,116 +862,87 @@ static void pci_ivshmem_realize(PCIDevice *dev, Error **errp) pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem_mmio); - memory_region_init(&s->bar, OBJECT(s), "ivshmem-bar2-container", s->ivshmem_size); - if (s->ivshmem_64bit) { + if (!s->not_legacy_32bit) { attr |= PCI_BASE_ADDRESS_MEM_TYPE_64; } if (s->hostmem != NULL) { - MemoryRegion *mr; - IVSHMEM_DPRINTF("using hostmem\n"); - mr = host_memory_backend_get_memory(MEMORY_BACKEND(s->hostmem), errp); - vmstate_register_ram(mr, DEVICE(s)); - memory_region_add_subregion(&s->bar, 0, mr); - pci_register_bar(PCI_DEVICE(s), 2, attr, &s->bar); - } else if (s->server_chr != NULL) { - /* FIXME do not rely on what chr drivers put into filename */ - if (strncmp(s->server_chr->filename, "unix:", 5)) { - error_setg(errp, "chardev is not a unix client socket"); - return; - } - - /* if we get a UNIX socket as the parameter we will talk - * to the ivshmem server to receive the memory region */ - + s->ivshmem_bar2 = host_memory_backend_get_memory(s->hostmem, + &error_abort); + } else { IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n", s->server_chr->filename); - if (ivshmem_setup_interrupts(s) < 0) { - error_setg(errp, "failed to initialize interrupts"); - return; - } - /* we allocate enough space for 16 peers and grow as needed */ resize_peers(s, 16); - s->vm_id = -1; - pci_register_bar(dev, 2, attr, &s->bar); + /* + * Receive setup messages from server synchronously. + * Older versions did it asynchronously, but that creates a + * number of entertaining race conditions. + */ + ivshmem_recv_setup(s, &err); + if (err) { + error_propagate(errp, err); + return; + } - s->eventfd_chr = g_malloc0(s->vectors * sizeof(CharDriverState *)); + if (s->master == ON_OFF_AUTO_ON && s->vm_id != 0) { + error_setg(errp, + "master must connect to the server before any peers"); + return; + } qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive, - ivshmem_check_version, ivshmem_event, s); - } else { - /* just map the file immediately, we're not using a server */ - int fd; - - IVSHMEM_DPRINTF("using shm_open (shm object = %s)\n", s->shmobj); - - /* try opening with O_EXCL and if it succeeds zero the memory - * by truncating to 0 */ - if ((fd = shm_open(s->shmobj, O_CREAT|O_RDWR|O_EXCL, - S_IRWXU|S_IRWXG|S_IRWXO)) > 0) { - /* truncate file to length PCI device's memory */ - if (ftruncate(fd, s->ivshmem_size) != 0) { - error_report("could not truncate shared file"); - } + ivshmem_read, NULL, s); - } else if ((fd = shm_open(s->shmobj, O_CREAT|O_RDWR, - S_IRWXU|S_IRWXG|S_IRWXO)) < 0) { - error_setg(errp, "could not open shared file"); + if (ivshmem_setup_interrupts(s) < 0) { + error_setg(errp, "failed to initialize interrupts"); return; } + } - if (check_shm_size(s, fd, errp) == -1) { - return; - } + vmstate_register_ram(s->ivshmem_bar2, DEVICE(s)); + pci_register_bar(PCI_DEVICE(s), 2, attr, s->ivshmem_bar2); - create_shared_memory_BAR(s, fd, attr, errp); + if (s->master == ON_OFF_AUTO_AUTO) { + s->master = s->vm_id == 0 ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; + } + + if (!ivshmem_is_master(s)) { + error_setg(&s->migration_blocker, + "Migration is disabled when using feature 'peer mode' in device 'ivshmem'"); + migrate_add_blocker(s->migration_blocker); } } -static void pci_ivshmem_exit(PCIDevice *dev) +static void ivshmem_exit(PCIDevice *dev) { - IVShmemState *s = IVSHMEM(dev); + IVShmemState *s = IVSHMEM_COMMON(dev); int i; - fifo8_destroy(&s->incoming_fifo); - if (s->migration_blocker) { migrate_del_blocker(s->migration_blocker); error_free(s->migration_blocker); } - if (memory_region_is_mapped(&s->ivshmem)) { + if (memory_region_is_mapped(s->ivshmem_bar2)) { if (!s->hostmem) { - void *addr = memory_region_get_ram_ptr(&s->ivshmem); + void *addr = memory_region_get_ram_ptr(s->ivshmem_bar2); int fd; - if (munmap(addr, s->ivshmem_size) == -1) { + if (munmap(addr, memory_region_size(s->ivshmem_bar2) == -1)) { error_report("Failed to munmap shared memory %s", strerror(errno)); } - fd = qemu_get_ram_fd(memory_region_get_ram_addr(&s->ivshmem)); - if (fd != -1) { - close(fd); - } + fd = qemu_get_ram_fd(memory_region_get_ram_addr(s->ivshmem_bar2)); + close(fd); } - vmstate_unregister_ram(&s->ivshmem, DEVICE(dev)); - memory_region_del_subregion(&s->bar, &s->ivshmem); - } - - if (s->eventfd_chr) { - for (i = 0; i < s->vectors; i++) { - if (s->eventfd_chr[i]) { - qemu_chr_free(s->eventfd_chr[i]); - } - } - g_free(s->eventfd_chr); + vmstate_unregister_ram(s->ivshmem_bar2, DEVICE(dev)); } if (s->peers) { @@ -1030,23 +959,11 @@ static void pci_ivshmem_exit(PCIDevice *dev) g_free(s->msi_vectors); } -static bool test_msix(void *opaque, int version_id) -{ - IVShmemState *s = opaque; - - return ivshmem_has_feature(s, IVSHMEM_MSI); -} - -static bool test_no_msix(void *opaque, int version_id) -{ - return !test_msix(opaque, version_id); -} - static int ivshmem_pre_load(void *opaque) { IVShmemState *s = opaque; - if (s->role_val == IVSHMEM_PEER) { + if (!ivshmem_is_master(s)) { error_report("'peer' devices are not migratable"); return -EINVAL; } @@ -1059,12 +976,145 @@ static int ivshmem_post_load(void *opaque, int version_id) IVShmemState *s = opaque; if (ivshmem_has_feature(s, IVSHMEM_MSI)) { - ivshmem_use_msix(s); + ivshmem_msix_vector_use(s); } - return 0; } +static void ivshmem_common_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->realize = ivshmem_common_realize; + k->exit = ivshmem_exit; + k->config_write = ivshmem_write_config; + k->vendor_id = PCI_VENDOR_ID_IVSHMEM; + k->device_id = PCI_DEVICE_ID_IVSHMEM; + k->class_id = PCI_CLASS_MEMORY_RAM; + k->revision = 1; + dc->reset = ivshmem_reset; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + dc->desc = "Inter-VM shared memory"; +} + +static const TypeInfo ivshmem_common_info = { + .name = TYPE_IVSHMEM_COMMON, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(IVShmemState), + .abstract = true, + .class_init = ivshmem_common_class_init, +}; + +static void ivshmem_check_memdev_is_busy(Object *obj, const char *name, + Object *val, Error **errp) +{ + MemoryRegion *mr; + + mr = host_memory_backend_get_memory(MEMORY_BACKEND(val), &error_abort); + if (memory_region_is_mapped(mr)) { + char *path = object_get_canonical_path_component(val); + error_setg(errp, "can't use already busy memdev: %s", path); + g_free(path); + } else { + qdev_prop_allow_set_link_before_realize(obj, name, val, errp); + } +} + +static const VMStateDescription ivshmem_plain_vmsd = { + .name = TYPE_IVSHMEM_PLAIN, + .version_id = 0, + .minimum_version_id = 0, + .pre_load = ivshmem_pre_load, + .post_load = ivshmem_post_load, + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE(parent_obj, IVShmemState), + VMSTATE_UINT32(intrstatus, IVShmemState), + VMSTATE_UINT32(intrmask, IVShmemState), + VMSTATE_END_OF_LIST() + }, +}; + +static Property ivshmem_plain_properties[] = { + DEFINE_PROP_ON_OFF_AUTO("master", IVShmemState, master, ON_OFF_AUTO_OFF), + DEFINE_PROP_END_OF_LIST(), +}; + +static void ivshmem_plain_init(Object *obj) +{ + IVShmemState *s = IVSHMEM_PLAIN(obj); + + object_property_add_link(obj, "memdev", TYPE_MEMORY_BACKEND, + (Object **)&s->hostmem, + ivshmem_check_memdev_is_busy, + OBJ_PROP_LINK_UNREF_ON_RELEASE, + &error_abort); +} + +static void ivshmem_plain_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->props = ivshmem_plain_properties; + dc->vmsd = &ivshmem_plain_vmsd; +} + +static const TypeInfo ivshmem_plain_info = { + .name = TYPE_IVSHMEM_PLAIN, + .parent = TYPE_IVSHMEM_COMMON, + .instance_size = sizeof(IVShmemState), + .instance_init = ivshmem_plain_init, + .class_init = ivshmem_plain_class_init, +}; + +static const VMStateDescription ivshmem_doorbell_vmsd = { + .name = TYPE_IVSHMEM_DOORBELL, + .version_id = 0, + .minimum_version_id = 0, + .pre_load = ivshmem_pre_load, + .post_load = ivshmem_post_load, + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE(parent_obj, IVShmemState), + VMSTATE_MSIX(parent_obj, IVShmemState), + VMSTATE_UINT32(intrstatus, IVShmemState), + VMSTATE_UINT32(intrmask, IVShmemState), + VMSTATE_END_OF_LIST() + }, +}; + +static Property ivshmem_doorbell_properties[] = { + DEFINE_PROP_CHR("chardev", IVShmemState, server_chr), + DEFINE_PROP_UINT32("vectors", IVShmemState, vectors, 1), + DEFINE_PROP_BIT("ioeventfd", IVShmemState, features, IVSHMEM_IOEVENTFD, + true), + DEFINE_PROP_ON_OFF_AUTO("master", IVShmemState, master, ON_OFF_AUTO_OFF), + DEFINE_PROP_END_OF_LIST(), +}; + +static void ivshmem_doorbell_init(Object *obj) +{ + IVShmemState *s = IVSHMEM_DOORBELL(obj); + + s->features |= (1 << IVSHMEM_MSI); + s->legacy_size = SIZE_MAX; /* whatever the server sends */ +} + +static void ivshmem_doorbell_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->props = ivshmem_doorbell_properties; + dc->vmsd = &ivshmem_doorbell_vmsd; +} + +static const TypeInfo ivshmem_doorbell_info = { + .name = TYPE_IVSHMEM_DOORBELL, + .parent = TYPE_IVSHMEM_COMMON, + .instance_size = sizeof(IVShmemState), + .instance_init = ivshmem_doorbell_init, + .class_init = ivshmem_doorbell_class_init, +}; + static int ivshmem_load_old(QEMUFile *f, void *opaque, int version_id) { IVShmemState *s = opaque; @@ -1077,9 +1127,9 @@ static int ivshmem_load_old(QEMUFile *f, void *opaque, int version_id) return -EINVAL; } - if (s->role_val == IVSHMEM_PEER) { - error_report("'peer' devices are not migratable"); - return -EINVAL; + ret = ivshmem_pre_load(s); + if (ret) { + return ret; } ret = pci_device_load(pdev, f); @@ -1089,7 +1139,7 @@ static int ivshmem_load_old(QEMUFile *f, void *opaque, int version_id) if (ivshmem_has_feature(s, IVSHMEM_MSI)) { msix_load(pdev, f); - ivshmem_use_msix(s); + ivshmem_msix_vector_use(s); } else { s->intrstatus = qemu_get_be32(f); s->intrmask = qemu_get_be32(f); @@ -1098,6 +1148,18 @@ static int ivshmem_load_old(QEMUFile *f, void *opaque, int version_id) return 0; } +static bool test_msix(void *opaque, int version_id) +{ + IVShmemState *s = opaque; + + return ivshmem_has_feature(s, IVSHMEM_MSI); +} + +static bool test_no_msix(void *opaque, int version_id) +{ + return !test_msix(opaque, version_id); +} + static const VMStateDescription ivshmem_vmsd = { .name = "ivshmem", .version_id = 1, @@ -1121,68 +1183,110 @@ static Property ivshmem_properties[] = { DEFINE_PROP_CHR("chardev", IVShmemState, server_chr), DEFINE_PROP_STRING("size", IVShmemState, sizearg), DEFINE_PROP_UINT32("vectors", IVShmemState, vectors, 1), - DEFINE_PROP_BIT("ioeventfd", IVShmemState, features, IVSHMEM_IOEVENTFD, false), + DEFINE_PROP_BIT("ioeventfd", IVShmemState, features, IVSHMEM_IOEVENTFD, + false), DEFINE_PROP_BIT("msi", IVShmemState, features, IVSHMEM_MSI, true), DEFINE_PROP_STRING("shm", IVShmemState, shmobj), DEFINE_PROP_STRING("role", IVShmemState, role), - DEFINE_PROP_UINT32("use64", IVShmemState, ivshmem_64bit, 1), + DEFINE_PROP_UINT32("use64", IVShmemState, not_legacy_32bit, 1), DEFINE_PROP_END_OF_LIST(), }; -static void ivshmem_class_init(ObjectClass *klass, void *data) +static void desugar_shm(IVShmemState *s) { - DeviceClass *dc = DEVICE_CLASS(klass); - PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - - k->realize = pci_ivshmem_realize; - k->exit = pci_ivshmem_exit; - k->config_write = ivshmem_write_config; - k->vendor_id = PCI_VENDOR_ID_IVSHMEM; - k->device_id = PCI_DEVICE_ID_IVSHMEM; - k->class_id = PCI_CLASS_MEMORY_RAM; - dc->reset = ivshmem_reset; - dc->props = ivshmem_properties; - dc->vmsd = &ivshmem_vmsd; - set_bit(DEVICE_CATEGORY_MISC, dc->categories); - dc->desc = "Inter-VM shared memory"; + Object *obj; + char *path; + + obj = object_new("memory-backend-file"); + path = g_strdup_printf("/dev/shm/%s", s->shmobj); + object_property_set_str(obj, path, "mem-path", &error_abort); + g_free(path); + object_property_set_int(obj, s->legacy_size, "size", &error_abort); + object_property_set_bool(obj, true, "share", &error_abort); + object_property_add_child(OBJECT(s), "internal-shm-backend", obj, + &error_abort); + user_creatable_complete(obj, &error_abort); + s->hostmem = MEMORY_BACKEND(obj); } -static void ivshmem_check_memdev_is_busy(Object *obj, const char *name, - Object *val, Error **errp) +static void ivshmem_realize(PCIDevice *dev, Error **errp) { - MemoryRegion *mr; + IVShmemState *s = IVSHMEM_COMMON(dev); - mr = host_memory_backend_get_memory(MEMORY_BACKEND(val), errp); - if (memory_region_is_mapped(mr)) { - char *path = object_get_canonical_path_component(val); - error_setg(errp, "can't use already busy memdev: %s", path); - g_free(path); + if (!qtest_enabled()) { + error_report("ivshmem is deprecated, please use ivshmem-plain" + " or ivshmem-doorbell instead"); + } + + if (!!s->server_chr + !!s->shmobj != 1) { + error_setg(errp, "You must specify either 'shm' or 'chardev'"); + return; + } + + if (s->sizearg == NULL) { + s->legacy_size = 4 << 20; /* 4 MB default */ } else { - qdev_prop_allow_set_link_before_realize(obj, name, val, errp); + char *end; + int64_t size = qemu_strtosz(s->sizearg, &end); + if (size < 0 || (size_t)size != size || *end != '\0' + || !is_power_of_2(size)) { + error_setg(errp, "Invalid size %s", s->sizearg); + return; + } + s->legacy_size = size; } + + /* check that role is reasonable */ + if (s->role) { + if (strncmp(s->role, "peer", 5) == 0) { + s->master = ON_OFF_AUTO_OFF; + } else if (strncmp(s->role, "master", 7) == 0) { + s->master = ON_OFF_AUTO_ON; + } else { + error_setg(errp, "'role' must be 'peer' or 'master'"); + return; + } + } else { + s->master = ON_OFF_AUTO_AUTO; + } + + if (s->shmobj) { + desugar_shm(s); + } + + /* + * Note: we don't use INTx with IVSHMEM_MSI at all, so this is a + * bald-faced lie then. But it's a backwards compatible lie. + */ + pci_config_set_interrupt_pin(dev->config, 1); + + ivshmem_common_realize(dev, errp); } -static void ivshmem_init(Object *obj) +static void ivshmem_class_init(ObjectClass *klass, void *data) { - IVShmemState *s = IVSHMEM(obj); + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - object_property_add_link(obj, "x-memdev", TYPE_MEMORY_BACKEND, - (Object **)&s->hostmem, - ivshmem_check_memdev_is_busy, - OBJ_PROP_LINK_UNREF_ON_RELEASE, - &error_abort); + k->realize = ivshmem_realize; + k->revision = 0; + dc->desc = "Inter-VM shared memory (legacy)"; + dc->props = ivshmem_properties; + dc->vmsd = &ivshmem_vmsd; } static const TypeInfo ivshmem_info = { .name = TYPE_IVSHMEM, - .parent = TYPE_PCI_DEVICE, + .parent = TYPE_IVSHMEM_COMMON, .instance_size = sizeof(IVShmemState), - .instance_init = ivshmem_init, .class_init = ivshmem_class_init, }; static void ivshmem_register_types(void) { + type_register_static(&ivshmem_common_info); + type_register_static(&ivshmem_plain_info); + type_register_static(&ivshmem_doorbell_info); type_register_static(&ivshmem_info); } diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index 481abdb754..c7472aaa9d 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -28,6 +28,7 @@ #include "hw/input/adb.h" #include "qemu/timer.h" #include "sysemu/sysemu.h" +#include "qemu/cutils.h" /* XXX: implement all timer modes */ @@ -145,7 +146,7 @@ static void cuda_update_irq(CUDAState *s) static uint64_t get_tb(uint64_t time, uint64_t freq) { - return muldiv64(time, freq, get_ticks_per_sec()); + return muldiv64(time, freq, NANOSECONDS_PER_SECOND); } static unsigned int get_counter(CUDATimer *ti) @@ -189,7 +190,7 @@ static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time) /* current counter value */ d = muldiv64(current_time - s->load_time, - CUDA_TIMER_FREQ, get_ticks_per_sec()); + CUDA_TIMER_FREQ, NANOSECONDS_PER_SECOND); /* the timer goes down from latch to -1 (period of latch + 2) */ if (d <= (s->counter_value + 1)) { counter = (s->counter_value - d) & 0xffff; @@ -208,7 +209,7 @@ static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time) } CUDA_DPRINTF("latch=%d counter=%" PRId64 " delta_next=%" PRId64 "\n", s->latch, d, next_time - d); - next_time = muldiv64(next_time, get_ticks_per_sec(), CUDA_TIMER_FREQ) + + next_time = muldiv64(next_time, NANOSECONDS_PER_SECOND, CUDA_TIMER_FREQ) + s->load_time; if (next_time <= current_time) next_time = current_time + 1; @@ -531,7 +532,7 @@ static void cuda_adb_poll(void *opaque) } timer_mod(s->adb_poll_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - (get_ticks_per_sec() / (1000 / s->autopoll_rate_ms))); + (NANOSECONDS_PER_SECOND / (1000 / s->autopoll_rate_ms))); } /* description of commands */ @@ -559,7 +560,7 @@ static bool cuda_cmd_autopoll(CUDAState *s, if (autopoll) { timer_mod(s->adb_poll_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - (get_ticks_per_sec() / (1000 / s->autopoll_rate_ms))); + (NANOSECONDS_PER_SECOND / (1000 / s->autopoll_rate_ms))); } else { timer_del(s->adb_poll_timer); } @@ -585,7 +586,7 @@ static bool cuda_cmd_set_autorate(CUDAState *s, if (s->autopoll) { timer_mod(s->adb_poll_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - (get_ticks_per_sec() / (1000 / s->autopoll_rate_ms))); + (NANOSECONDS_PER_SECOND / (1000 / s->autopoll_rate_ms))); } return true; } @@ -665,7 +666,7 @@ static bool cuda_cmd_get_time(CUDAState *s, } ti = s->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - / get_ticks_per_sec()); + / NANOSECONDS_PER_SECOND); out_data[0] = ti >> 24; out_data[1] = ti >> 16; out_data[2] = ti >> 8; @@ -687,7 +688,7 @@ static bool cuda_cmd_set_time(CUDAState *s, ti = (((uint32_t)in_data[1]) << 24) + (((uint32_t)in_data[2]) << 16) + (((uint32_t)in_data[3]) << 8) + in_data[4]; s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - / get_ticks_per_sec()); + / NANOSECONDS_PER_SECOND); return true; } diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c index 42325bff50..be03926b96 100644 --- a/hw/misc/macio/macio.c +++ b/hw/misc/macio/macio.c @@ -23,6 +23,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/ppc/mac.h" #include "hw/pci/pci.h" @@ -253,7 +254,7 @@ static uint64_t timer_read(void *opaque, hwaddr addr, unsigned size) uint64_t systime = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); uint64_t kltime; - kltime = muldiv64(systime, 4194300, get_ticks_per_sec() * 4); + kltime = muldiv64(systime, 4194300, NANOSECONDS_PER_SECOND * 4); kltime = muldiv64(kltime, 18432000, 1048575); switch (addr) { diff --git a/hw/misc/tmp105.c b/hw/misc/tmp105.c index b53f6babad..f5c2472b5b 100644 --- a/hw/misc/tmp105.c +++ b/hw/misc/tmp105.c @@ -22,6 +22,7 @@ #include "hw/hw.h" #include "hw/i2c/i2c.h" #include "tmp105.h" +#include "qapi/error.h" #include "qapi/visitor.h" static void tmp105_interrupt_update(TMP105State *s) diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c index d88c9428e0..3069834cf4 100644 --- a/hw/moxie/moxiesim.c +++ b/hw/moxie/moxiesim.c @@ -25,6 +25,9 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/hw.h" #include "hw/i386/pc.h" diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c index e847b77cf4..0fa652c392 100644 --- a/hw/net/dp8393x.c +++ b/hw/net/dp8393x.c @@ -21,6 +21,7 @@ #include "hw/sysbus.h" #include "hw/devices.h" #include "net/net.h" +#include "qapi/error.h" #include "qemu/timer.h" #include <zlib.h> @@ -293,7 +294,7 @@ static void dp8393x_set_next_tick(dp8393xState *s) ticks = s->regs[SONIC_WT1] << 16 | s->regs[SONIC_WT0]; s->wt_last_update = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - delay = get_ticks_per_sec() * ticks / 5000000; + delay = NANOSECONDS_PER_SECOND * ticks / 5000000; timer_mod(s->watchdog, s->wt_last_update + delay); } diff --git a/hw/net/milkymist-minimac2.c b/hw/net/milkymist-minimac2.c index d35d39a0e5..1e147c33c5 100644 --- a/hw/net/milkymist-minimac2.c +++ b/hw/net/milkymist-minimac2.c @@ -23,6 +23,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" /* FIXME: why does this use TARGET_PAGE_ALIGN? */ #include "hw/hw.h" #include "hw/sysbus.h" #include "trace.h" diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c index 8dca7c936b..a7f5a9464d 100644 --- a/hw/net/ne2000-isa.c +++ b/hw/net/ne2000-isa.c @@ -29,6 +29,7 @@ #include "net/net.h" #include "ne2000.h" #include "exec/address-spaces.h" +#include "qapi/error.h" #include "qapi/visitor.h" #define TYPE_ISA_NE2000 "ne2k_isa" diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c index 5237b4d863..a647f25d96 100644 --- a/hw/net/spapr_llan.c +++ b/hw/net/spapr_llan.c @@ -25,6 +25,8 @@ * */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "net/net.h" #include "hw/qdev.h" @@ -45,6 +47,10 @@ #define DPRINTF(fmt...) #endif +/* Compatibility flags for migration */ +#define SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT 0 +#define SPAPRVLAN_FLAG_RX_BUF_POOLS (1 << SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT) + /* * Virtual LAN device */ @@ -86,6 +92,15 @@ typedef uint64_t vlan_bd_t; #define VIO_SPAPR_VLAN_DEVICE(obj) \ OBJECT_CHECK(VIOsPAPRVLANDevice, (obj), TYPE_VIO_SPAPR_VLAN_DEVICE) +#define RX_POOL_MAX_BDS 4096 +#define RX_MAX_POOLS 5 + +typedef struct { + int32_t bufsize; + int32_t count; + vlan_bd_t bds[RX_POOL_MAX_BDS]; +} RxBufPool; + typedef struct VIOsPAPRVLANDevice { VIOsPAPRDevice sdev; NICConf nicconf; @@ -94,6 +109,8 @@ typedef struct VIOsPAPRVLANDevice { target_ulong buf_list; uint32_t add_buf_ptr, use_buf_ptr, rx_bufs; target_ulong rxq_ptr; + uint32_t compat_flags; /* Compatability flags for migration */ + RxBufPool *rx_pool[RX_MAX_POOLS]; /* Receive buffer descriptor pools */ } VIOsPAPRVLANDevice; static int spapr_vlan_can_receive(NetClientState *nc) @@ -103,6 +120,73 @@ static int spapr_vlan_can_receive(NetClientState *nc) return (dev->isopen && dev->rx_bufs > 0); } +/** + * Get buffer descriptor from one of our receive buffer pools + */ +static vlan_bd_t spapr_vlan_get_rx_bd_from_pool(VIOsPAPRVLANDevice *dev, + size_t size) +{ + vlan_bd_t bd; + int pool; + + for (pool = 0; pool < RX_MAX_POOLS; pool++) { + if (dev->rx_pool[pool]->count > 0 && + dev->rx_pool[pool]->bufsize >= size + 8) { + break; + } + } + if (pool == RX_MAX_POOLS) { + /* Failed to find a suitable buffer */ + return 0; + } + + DPRINTF("Found buffer: pool=%d count=%d rxbufs=%d\n", pool, + dev->rx_pool[pool]->count, dev->rx_bufs); + + /* Remove the buffer from the pool */ + dev->rx_pool[pool]->count--; + bd = dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count]; + dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count] = 0; + + return bd; +} + +/** + * Get buffer descriptor from the receive buffer list page that has been + * supplied by the guest with the H_REGISTER_LOGICAL_LAN call + */ +static vlan_bd_t spapr_vlan_get_rx_bd_from_page(VIOsPAPRVLANDevice *dev, + size_t size) +{ + int buf_ptr = dev->use_buf_ptr; + vlan_bd_t bd; + + do { + buf_ptr += 8; + if (buf_ptr >= VLAN_RX_BDS_LEN + VLAN_RX_BDS_OFF) { + buf_ptr = VLAN_RX_BDS_OFF; + } + + bd = vio_ldq(&dev->sdev, dev->buf_list + buf_ptr); + DPRINTF("use_buf_ptr=%d bd=0x%016llx\n", + buf_ptr, (unsigned long long)bd); + } while ((!(bd & VLAN_BD_VALID) || VLAN_BD_LEN(bd) < size + 8) + && buf_ptr != dev->use_buf_ptr); + + if (!(bd & VLAN_BD_VALID) || VLAN_BD_LEN(bd) < size + 8) { + /* Failed to find a suitable buffer */ + return 0; + } + + /* Remove the buffer from the pool */ + dev->use_buf_ptr = buf_ptr; + vio_stq(&dev->sdev, dev->buf_list + dev->use_buf_ptr, 0); + + DPRINTF("Found buffer: ptr=%d rxbufs=%d\n", dev->use_buf_ptr, dev->rx_bufs); + + return bd; +} + static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf, size_t size) { @@ -110,7 +194,6 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf, VIOsPAPRDevice *sdev = VIO_SPAPR_DEVICE(dev); vlan_bd_t rxq_bd = vio_ldq(sdev, dev->buf_list + VLAN_RXQ_BD_OFF); vlan_bd_t bd; - int buf_ptr = dev->use_buf_ptr; uint64_t handle; uint8_t control; @@ -125,29 +208,16 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf, return -1; } - do { - buf_ptr += 8; - if (buf_ptr >= (VLAN_RX_BDS_LEN + VLAN_RX_BDS_OFF)) { - buf_ptr = VLAN_RX_BDS_OFF; - } - - bd = vio_ldq(sdev, dev->buf_list + buf_ptr); - DPRINTF("use_buf_ptr=%d bd=0x%016llx\n", - buf_ptr, (unsigned long long)bd); - } while ((!(bd & VLAN_BD_VALID) || (VLAN_BD_LEN(bd) < (size + 8))) - && (buf_ptr != dev->use_buf_ptr)); - - if (!(bd & VLAN_BD_VALID) || (VLAN_BD_LEN(bd) < (size + 8))) { - /* Failed to find a suitable buffer */ + if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) { + bd = spapr_vlan_get_rx_bd_from_pool(dev, size); + } else { + bd = spapr_vlan_get_rx_bd_from_page(dev, size); + } + if (!bd) { return -1; } - /* Remove the buffer from the pool */ dev->rx_bufs--; - dev->use_buf_ptr = buf_ptr; - vio_stq(sdev, dev->buf_list + dev->use_buf_ptr, 0); - - DPRINTF("Found buffer: ptr=%d num=%d\n", dev->use_buf_ptr, dev->rx_bufs); /* Transfer the packet data */ if (spapr_vio_dma_write(sdev, VLAN_BD_ADDR(bd) + 8, buf, size) < 0) { @@ -195,13 +265,31 @@ static NetClientInfo net_spapr_vlan_info = { .receive = spapr_vlan_receive, }; +static void spapr_vlan_reset_rx_pool(RxBufPool *rxp) +{ + /* + * Use INT_MAX as bufsize so that unused buffers are moved to the end + * of the list during the qsort in spapr_vlan_add_rxbuf_to_pool() later. + */ + rxp->bufsize = INT_MAX; + rxp->count = 0; + memset(rxp->bds, 0, sizeof(rxp->bds)); +} + static void spapr_vlan_reset(VIOsPAPRDevice *sdev) { VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev); + int i; dev->buf_list = 0; dev->rx_bufs = 0; dev->isopen = 0; + + if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) { + for (i = 0; i < RX_MAX_POOLS; i++) { + spapr_vlan_reset_rx_pool(dev->rx_pool[i]); + } + } } static void spapr_vlan_realize(VIOsPAPRDevice *sdev, Error **errp) @@ -218,10 +306,31 @@ static void spapr_vlan_realize(VIOsPAPRDevice *sdev, Error **errp) static void spapr_vlan_instance_init(Object *obj) { VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(obj); + int i; device_add_bootindex_property(obj, &dev->nicconf.bootindex, "bootindex", "", DEVICE(dev), NULL); + + if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) { + for (i = 0; i < RX_MAX_POOLS; i++) { + dev->rx_pool[i] = g_new(RxBufPool, 1); + spapr_vlan_reset_rx_pool(dev->rx_pool[i]); + } + } +} + +static void spapr_vlan_instance_finalize(Object *obj) +{ + VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(obj); + int i; + + if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) { + for (i = 0; i < RX_MAX_POOLS; i++) { + g_free(dev->rx_pool[i]); + dev->rx_pool[i] = NULL; + } + } } void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd) @@ -372,6 +481,113 @@ static target_ulong h_free_logical_lan(PowerPCCPU *cpu, return H_SUCCESS; } +/** + * Used for qsort, this function compares two RxBufPools by size. + */ +static int rx_pool_size_compare(const void *p1, const void *p2) +{ + const RxBufPool *pool1 = *(RxBufPool **)p1; + const RxBufPool *pool2 = *(RxBufPool **)p2; + + if (pool1->bufsize < pool2->bufsize) { + return -1; + } + return pool1->bufsize > pool2->bufsize; +} + +/** + * Search for a matching buffer pool with exact matching size, + * or return -1 if no matching pool has been found. + */ +static int spapr_vlan_get_rx_pool_id(VIOsPAPRVLANDevice *dev, int size) +{ + int pool; + + for (pool = 0; pool < RX_MAX_POOLS; pool++) { + if (dev->rx_pool[pool]->bufsize == size) { + return pool; + } + } + + return -1; +} + +/** + * Enqueuing receive buffer by adding it to one of our receive buffer pools + */ +static target_long spapr_vlan_add_rxbuf_to_pool(VIOsPAPRVLANDevice *dev, + target_ulong buf) +{ + int size = VLAN_BD_LEN(buf); + int pool; + + pool = spapr_vlan_get_rx_pool_id(dev, size); + if (pool < 0) { + /* + * No matching pool found? Try to use a new one. If the guest used all + * pools before, but changed the size of one pool inbetween, we might + * need to recycle that pool here (if it's empty already). Thus scan + * all buffer pools now, starting with the last (likely empty) one. + */ + for (pool = RX_MAX_POOLS - 1; pool >= 0 ; pool--) { + if (dev->rx_pool[pool]->count == 0) { + dev->rx_pool[pool]->bufsize = size; + /* + * Sort pools by size so that spapr_vlan_receive() + * can later find the smallest buffer pool easily. + */ + qsort(dev->rx_pool, RX_MAX_POOLS, sizeof(dev->rx_pool[0]), + rx_pool_size_compare); + pool = spapr_vlan_get_rx_pool_id(dev, size); + DPRINTF("created RX pool %d for size %lld\n", pool, + VLAN_BD_LEN(buf)); + break; + } + } + } + /* Still no usable pool? Give up */ + if (pool < 0 || dev->rx_pool[pool]->count >= RX_POOL_MAX_BDS) { + return H_RESOURCE; + } + + DPRINTF("h_add_llan_buf(): Add buf using pool %i (size %lli, count=%i)\n", + pool, VLAN_BD_LEN(buf), dev->rx_pool[pool]->count); + + dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count++] = buf; + + return 0; +} + +/** + * This is the old way of enqueuing receive buffers: Add it to the rx queue + * page that has been supplied by the guest (which is quite limited in size). + */ +static target_long spapr_vlan_add_rxbuf_to_page(VIOsPAPRVLANDevice *dev, + target_ulong buf) +{ + vlan_bd_t bd; + + if (dev->rx_bufs >= VLAN_MAX_BUFS) { + return H_RESOURCE; + } + + do { + dev->add_buf_ptr += 8; + if (dev->add_buf_ptr >= VLAN_RX_BDS_LEN + VLAN_RX_BDS_OFF) { + dev->add_buf_ptr = VLAN_RX_BDS_OFF; + } + + bd = vio_ldq(&dev->sdev, dev->buf_list + dev->add_buf_ptr); + } while (bd & VLAN_BD_VALID); + + vio_stq(&dev->sdev, dev->buf_list + dev->add_buf_ptr, buf); + + DPRINTF("h_add_llan_buf(): Added buf ptr=%d rx_bufs=%d bd=0x%016llx\n", + dev->add_buf_ptr, dev->rx_bufs, (unsigned long long)buf); + + return 0; +} + static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, @@ -381,7 +597,7 @@ static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu, target_ulong buf = args[1]; VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg); VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev); - vlan_bd_t bd; + target_long ret; DPRINTF("H_ADD_LOGICAL_LAN_BUFFER(0x" TARGET_FMT_lx ", 0x" TARGET_FMT_lx ")\n", reg, buf); @@ -397,29 +613,23 @@ static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu, return H_PARAMETER; } - if (!dev->isopen || dev->rx_bufs >= VLAN_MAX_BUFS) { + if (!dev->isopen) { return H_RESOURCE; } - do { - dev->add_buf_ptr += 8; - if (dev->add_buf_ptr >= (VLAN_RX_BDS_LEN + VLAN_RX_BDS_OFF)) { - dev->add_buf_ptr = VLAN_RX_BDS_OFF; - } - - bd = vio_ldq(sdev, dev->buf_list + dev->add_buf_ptr); - } while (bd & VLAN_BD_VALID); - - vio_stq(sdev, dev->buf_list + dev->add_buf_ptr, buf); + if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) { + ret = spapr_vlan_add_rxbuf_to_pool(dev, buf); + } else { + ret = spapr_vlan_add_rxbuf_to_page(dev, buf); + } + if (ret) { + return ret; + } dev->rx_bufs++; qemu_flush_queued_packets(qemu_get_queue(dev->nic)); - DPRINTF("h_add_logical_lan_buffer(): Added buf ptr=%d rx_bufs=%d" - " bd=0x%016llx\n", dev->add_buf_ptr, dev->rx_bufs, - (unsigned long long)buf); - return H_SUCCESS; } @@ -509,9 +719,44 @@ static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, sPAPRMachineState *spapr, static Property spapr_vlan_properties[] = { DEFINE_SPAPR_PROPERTIES(VIOsPAPRVLANDevice, sdev), DEFINE_NIC_PROPERTIES(VIOsPAPRVLANDevice, nicconf), + DEFINE_PROP_BIT("use-rx-buffer-pools", VIOsPAPRVLANDevice, + compat_flags, SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT, true), DEFINE_PROP_END_OF_LIST(), }; +static bool spapr_vlan_rx_buffer_pools_needed(void *opaque) +{ + VIOsPAPRVLANDevice *dev = opaque; + + return (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) != 0; +} + +static const VMStateDescription vmstate_rx_buffer_pool = { + .name = "spapr_llan/rx_buffer_pool", + .version_id = 1, + .minimum_version_id = 1, + .needed = spapr_vlan_rx_buffer_pools_needed, + .fields = (VMStateField[]) { + VMSTATE_INT32(bufsize, RxBufPool), + VMSTATE_INT32(count, RxBufPool), + VMSTATE_UINT64_ARRAY(bds, RxBufPool, RX_POOL_MAX_BDS), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_rx_pools = { + .name = "spapr_llan/rx_pools", + .version_id = 1, + .minimum_version_id = 1, + .needed = spapr_vlan_rx_buffer_pools_needed, + .fields = (VMStateField[]) { + VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(rx_pool, VIOsPAPRVLANDevice, + RX_MAX_POOLS, 1, + vmstate_rx_buffer_pool, RxBufPool), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_spapr_llan = { .name = "spapr_llan", .version_id = 1, @@ -528,6 +773,10 @@ static const VMStateDescription vmstate_spapr_llan = { VMSTATE_END_OF_LIST() }, + .subsections = (const VMStateDescription * []) { + &vmstate_rx_pools, + NULL + } }; static void spapr_vlan_class_init(ObjectClass *klass, void *data) @@ -554,6 +803,7 @@ static const TypeInfo spapr_vlan_info = { .instance_size = sizeof(VIOsPAPRVLANDevice), .class_init = spapr_vlan_class_init, .instance_init = spapr_vlan_instance_init, + .instance_finalize = spapr_vlan_instance_finalize, }; static void spapr_vlan_register_types(void) diff --git a/hw/net/vmxnet_rx_pkt.h b/hw/net/vmxnet_rx_pkt.h index a425846b52..0a45c1ba00 100644 --- a/hw/net/vmxnet_rx_pkt.h +++ b/hw/net/vmxnet_rx_pkt.h @@ -18,8 +18,6 @@ #ifndef VMXNET_RX_PKT_H #define VMXNET_RX_PKT_H -#include "stdint.h" -#include "stdbool.h" #include "net/eth.h" /* defines to enable packet dump functions */ diff --git a/hw/net/vmxnet_tx_pkt.h b/hw/net/vmxnet_tx_pkt.h index 57121a6fe5..f51e98ad95 100644 --- a/hw/net/vmxnet_tx_pkt.h +++ b/hw/net/vmxnet_tx_pkt.h @@ -18,8 +18,6 @@ #ifndef VMXNET_TX_PKT_H #define VMXNET_TX_PKT_H -#include "stdint.h" -#include "stdbool.h" #include "net/eth.h" #include "exec/hwaddr.h" diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c index 2deb8ce84b..de23ab5dcd 100644 --- a/hw/net/xilinx_axienet.c +++ b/hw/net/xilinx_axienet.c @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "hw/sysbus.h" +#include "qapi/error.h" #include "qemu/log.h" #include "net/net.h" #include "net/checksum.h" diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 71a3224520..bc846e7096 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -23,6 +23,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" /* FIXME should not use tswap* */ #include "hw/sysbus.h" #include "hw/hw.h" #include "net/net.h" diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index 7866248b93..d96932f6ca 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -31,6 +31,7 @@ #include "trace.h" #include "qemu/error-report.h" #include "qemu/config-file.h" +#include "qemu/cutils.h" #define FW_CFG_NAME "fw_cfg" #define FW_CFG_PATH "/machine/" FW_CFG_NAME diff --git a/hw/nvram/mac_nvram.c b/hw/nvram/mac_nvram.c index 1671f4686e..24f61212ba 100644 --- a/hw/nvram/mac_nvram.c +++ b/hw/nvram/mac_nvram.c @@ -27,6 +27,7 @@ #include "hw/nvram/openbios_firmware_abi.h" #include "sysemu/sysemu.h" #include "hw/ppc/mac.h" +#include "qemu/cutils.h" #include <zlib.h> /* debug NVR */ diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c index 32d5a361d0..802636ef35 100644 --- a/hw/nvram/spapr_nvram.c +++ b/hw/nvram/spapr_nvram.c @@ -23,6 +23,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include <libfdt.h> #include "sysemu/block-backend.h" diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c index 46418c30f7..6d06d5be01 100644 --- a/hw/openrisc/openrisc_sim.c +++ b/hw/openrisc/openrisc_sim.c @@ -19,6 +19,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/boards.h" #include "elf.h" diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c index 862a2366f2..7b582e96ac 100644 --- a/hw/pci-bridge/pci_bridge_dev.c +++ b/hw/pci-bridge/pci_bridge_dev.c @@ -20,6 +20,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/pci/pci_bridge.h" #include "hw/pci/pci_ids.h" #include "hw/pci/msi.h" diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index 41aa66f828..df2b0e26f5 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -29,6 +29,7 @@ #include "hw/pci/pci_host.h" #include "hw/isa/isa.h" #include "hw/sysbus.h" +#include "qapi/error.h" #include "qemu/range.h" #include "hw/xen/xen.h" #include "hw/pci-host/pam.h" diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c index 49cdaab36b..487e32ecbf 100644 --- a/hw/pci-host/prep.c +++ b/hw/pci-host/prep.c @@ -24,6 +24,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/pci/pci.h" #include "hw/pci/pci_bus.h" diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index 115fb8c046..70f897e3a9 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -30,6 +30,7 @@ #include "qemu/osdep.h" #include "hw/hw.h" #include "hw/pci-host/q35.h" +#include "qapi/error.h" #include "qapi/visitor.h" /**************************************************************************** diff --git a/hw/pci/pci.c b/hw/pci/pci.c index e67664deb3..bb605efae0 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -40,6 +40,7 @@ #include "exec/address-spaces.h" #include "hw/hotplug.h" #include "hw/boards.h" +#include "qemu/cutils.h" //#define DEBUG_PCI #ifdef DEBUG_PCI diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index 4aca0c5912..728386ada7 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "hw/pci/pci_bridge.h" #include "hw/pci/pcie.h" diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c index aef838415f..3dcd472eba 100644 --- a/hw/pci/shpc.c +++ b/hw/pci/shpc.c @@ -1,4 +1,5 @@ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/range.h" #include "qemu/error-report.h" diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 09154fa813..ee1c60b820 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -15,6 +15,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "e500.h" #include "e500-ccsr.h" diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index f0a36b3133..32e88b3786 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -47,6 +47,7 @@ * */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/ppc/ppc.h" #include "hw/ppc/mac.h" @@ -70,6 +71,7 @@ #include "sysemu/block-backend.h" #include "exec/address-spaces.h" #include "hw/sysbus.h" +#include "qemu/cutils.h" #define MAX_IDE_BUS 2 #define CFG_ADDR 0xf0000510 diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index d952713313..a9bb1c27df 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -24,6 +24,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/ppc/ppc.h" #include "mac.h" @@ -44,6 +45,7 @@ #include "kvm_ppc.h" #include "sysemu/block-backend.h" #include "exec/address-spaces.h" +#include "qemu/cutils.h" #define MAX_IDE_BUS 2 #define CFG_ADDR 0xf0000510 diff --git a/hw/ppc/mpc8544_guts.c b/hw/ppc/mpc8544_guts.c index ce399d1815..ba69178d69 100644 --- a/hw/ppc/mpc8544_guts.c +++ b/hw/ppc/mpc8544_guts.c @@ -18,6 +18,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "sysemu/sysemu.h" #include "hw/sysbus.h" diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index ce90b09003..38ff2e1596 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -22,6 +22,8 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/ppc/ppc.h" #include "hw/ppc/ppc_e500.h" @@ -463,7 +465,7 @@ void ppce500_set_mpic_proxy(bool enabled) uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset) { /* TB time in tb periods */ - return muldiv64(vmclk, tb_env->tb_freq, get_ticks_per_sec()) + tb_offset; + return muldiv64(vmclk, tb_env->tb_freq, NANOSECONDS_PER_SECOND) + tb_offset; } uint64_t cpu_ppc_load_tbl (CPUPPCState *env) @@ -504,7 +506,9 @@ uint32_t cpu_ppc_load_tbu (CPUPPCState *env) static inline void cpu_ppc_store_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t *tb_offsetp, uint64_t value) { - *tb_offsetp = value - muldiv64(vmclk, tb_env->tb_freq, get_ticks_per_sec()); + *tb_offsetp = value - + muldiv64(vmclk, tb_env->tb_freq, NANOSECONDS_PER_SECOND); + LOG_TB("%s: tb %016" PRIx64 " offset %08" PRIx64 "\n", __func__, value, *tb_offsetp); } @@ -638,11 +642,11 @@ static inline uint32_t _cpu_ppc_load_decr(CPUPPCState *env, uint64_t next) diff = next - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); if (diff >= 0) { - decr = muldiv64(diff, tb_env->decr_freq, get_ticks_per_sec()); + decr = muldiv64(diff, tb_env->decr_freq, NANOSECONDS_PER_SECOND); } else if (tb_env->flags & PPC_TIMER_BOOKE) { decr = 0; } else { - decr = -muldiv64(-diff, tb_env->decr_freq, get_ticks_per_sec()); + decr = -muldiv64(-diff, tb_env->decr_freq, NANOSECONDS_PER_SECOND); } LOG_TB("%s: %08" PRIx32 "\n", __func__, decr); @@ -674,7 +678,8 @@ uint64_t cpu_ppc_load_purr (CPUPPCState *env) diff = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - tb_env->purr_start; - return tb_env->purr_load + muldiv64(diff, tb_env->tb_freq, get_ticks_per_sec()); + return tb_env->purr_load + + muldiv64(diff, tb_env->tb_freq, NANOSECONDS_PER_SECOND); } /* When decrementer expires, @@ -750,7 +755,7 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp, /* Calculate the next timer event */ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - next = now + muldiv64(value, get_ticks_per_sec(), tb_env->decr_freq); + next = now + muldiv64(value, NANOSECONDS_PER_SECOND, tb_env->decr_freq); *nextp = next; /* Adjust timer */ @@ -1011,7 +1016,7 @@ static void cpu_4xx_fit_cb (void *opaque) /* Cannot occur, but makes gcc happy */ return; } - next = now + muldiv64(next, get_ticks_per_sec(), tb_env->tb_freq); + next = now + muldiv64(next, NANOSECONDS_PER_SECOND, tb_env->tb_freq); if (next == now) next++; timer_mod(ppc40x_timer->fit_timer, next); @@ -1042,7 +1047,7 @@ static void start_stop_pit (CPUPPCState *env, ppc_tb_t *tb_env, int is_excp) __func__, ppc40x_timer->pit_reload); now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); next = now + muldiv64(ppc40x_timer->pit_reload, - get_ticks_per_sec(), tb_env->decr_freq); + NANOSECONDS_PER_SECOND, tb_env->decr_freq); if (is_excp) next += tb_env->decr_next - now; if (next == now) @@ -1107,7 +1112,7 @@ static void cpu_4xx_wdt_cb (void *opaque) /* Cannot occur, but makes gcc happy */ return; } - next = now + muldiv64(next, get_ticks_per_sec(), tb_env->decr_freq); + next = now + muldiv64(next, NANOSECONDS_PER_SECOND, tb_env->decr_freq); if (next == now) next++; LOG_TB("%s: TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx "\n", __func__, diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c index d8db3199c9..4b2f07aecb 100644 --- a/hw/ppc/ppc405_boards.c +++ b/hw/ppc/ppc405_boards.c @@ -22,6 +22,9 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/ppc/ppc.h" #include "ppc405.h" diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c index ec81f658c5..d6d3fc2c4a 100644 --- a/hw/ppc/ppc405_uc.c +++ b/hw/ppc/ppc405_uc.c @@ -22,6 +22,9 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/ppc/ppc.h" #include "hw/boards.h" @@ -1353,7 +1356,7 @@ static uint32_t ppc4xx_gpt_readl (void *opaque, hwaddr addr) case 0x00: /* Time base counter */ ret = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + gpt->tb_offset, - gpt->tb_freq, get_ticks_per_sec()); + gpt->tb_freq, NANOSECONDS_PER_SECOND); break; case 0x10: /* Output enable */ @@ -1408,7 +1411,7 @@ static void ppc4xx_gpt_writel (void *opaque, switch (addr) { case 0x00: /* Time base counter */ - gpt->tb_offset = muldiv64(value, get_ticks_per_sec(), gpt->tb_freq) + gpt->tb_offset = muldiv64(value, NANOSECONDS_PER_SECOND, gpt->tb_freq) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ppc4xx_gpt_compute_timer(gpt); break; diff --git a/hw/ppc/ppc_booke.c b/hw/ppc/ppc_booke.c index a8d4e76426..ab8d026c32 100644 --- a/hw/ppc/ppc_booke.c +++ b/hw/ppc/ppc_booke.c @@ -22,6 +22,8 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/ppc/ppc.h" #include "qemu/timer.h" @@ -163,7 +165,7 @@ static void booke_update_fixed_timer(CPUPPCState *env, ticks += delta_tick; } - *next = now + muldiv64(ticks, get_ticks_per_sec(), tb_env->tb_freq); + *next = now + muldiv64(ticks, NANOSECONDS_PER_SECOND, tb_env->tb_freq); if ((*next < now) || (*next > INT64_MAX)) { /* Overflow, so assume the biggest number the qemu timer supports. */ *next = INT64_MAX; diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index 793b9ed34e..3ffb85e601 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -46,6 +46,7 @@ #include "exec/address-spaces.h" #include "trace.h" #include "elf.h" +#include "qemu/cutils.h" /* SMP is not enabled, for now */ #define MAX_CPUS 1 diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index d0bb42305b..e7be21e678 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -25,6 +25,7 @@ * */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "sysemu/sysemu.h" #include "sysemu/numa.h" #include "hw/hw.h" @@ -63,7 +64,7 @@ #include "hw/nmi.h" #include "hw/compat.h" -#include "qemu-common.h" +#include "qemu/cutils.h" #include <libfdt.h> @@ -497,10 +498,11 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, * Older KVM versions with older guest kernels were broken with the * magic page, don't allow the guest to map it. */ - kvmppc_get_hypercall(first_cpu->env_ptr, hypercall, - sizeof(hypercall)); - _FDT((fdt_property(fdt, "hcall-instructions", hypercall, - sizeof(hypercall)))); + if (!kvmppc_get_hypercall(first_cpu->env_ptr, hypercall, + sizeof(hypercall))) { + _FDT((fdt_property(fdt, "hcall-instructions", hypercall, + sizeof(hypercall)))); + } } _FDT((fdt_end_node(fdt))); } @@ -1612,15 +1614,8 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu, /* Set time-base frequency to 512 MHz */ cpu_ppc_tb_init(env, TIMEBASE_FREQ); - /* PAPR always has exception vectors in RAM not ROM. To ensure this, - * MSR[IP] should never be set. - */ - env->msr_mask &= ~(1 << 6); - - /* Tell KVM that we're in PAPR mode */ - if (kvm_enabled()) { - kvmppc_set_papr(cpu); - } + /* Enable PAPR mode in TCG or KVM */ + cpu_ppc_set_papr(cpu); if (cpu->max_compat) { Error *local_err = NULL; @@ -2362,7 +2357,12 @@ DEFINE_SPAPR_MACHINE(2_6, "2.6", true); * pseries-2.5 */ #define SPAPR_COMPAT_2_5 \ - HW_COMPAT_2_5 + HW_COMPAT_2_5 \ + { \ + .driver = "spapr-vlan", \ + .property = "use-rx-buffer-pools", \ + .value = "off", \ + }, static void spapr_machine_2_5_instance_options(MachineState *machine) { diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index ef063c05cf..e6eedf8946 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -11,6 +11,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "cpu.h" +#include "qemu/cutils.h" #include "hw/ppc/spapr_drc.h" #include "qom/object.h" #include "hw/qdev.h" diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index 39f4682f95..1abec27ec6 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -25,6 +25,7 @@ * */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "sysemu/sysemu.h" #include "sysemu/char.h" @@ -36,7 +37,8 @@ #include "hw/pci/pci.h" #include "hw/pci-host/spapr.h" #include "hw/ppc/spapr_drc.h" - +#include "qemu/help_option.h" +#include "qemu/bcd.h" #include <libfdt.h> struct rtas_error_log { diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index b2b1b93cfd..2dcb676c6f 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1,4 +1,5 @@ #include "qemu/osdep.h" +#include "qapi/error.h" #include "sysemu/sysemu.h" #include "cpu.h" #include "helper_regs.h" diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 79baa7b177..8c20d34cdd 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -23,6 +23,9 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/sysbus.h" #include "hw/pci/pci.h" diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c index 9e15924f50..cbd3d23c91 100644 --- a/hw/ppc/spapr_pci_vfio.c +++ b/hw/ppc/spapr_pci_vfio.c @@ -18,6 +18,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/ppc/spapr.h" #include "hw/pci-host/spapr.h" #include "hw/pci/msix.h" diff --git a/hw/ppc/spapr_rng.c b/hw/ppc/spapr_rng.c index 02d6be49f5..80515eb54d 100644 --- a/hw/ppc/spapr_rng.c +++ b/hw/ppc/spapr_rng.c @@ -18,6 +18,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "qemu/error-report.h" #include "sysemu/sysemu.h" #include "sysemu/device_tree.h" diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index b7c5ebde40..2db229272e 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -39,6 +39,7 @@ #include <libfdt.h> #include "hw/ppc/spapr_drc.h" +#include "qemu/cutils.h" /* #define DEBUG_SPAPR */ diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c index 02fa373aee..3a17ac42e4 100644 --- a/hw/ppc/spapr_rtc.c +++ b/hw/ppc/spapr_rtc.c @@ -31,6 +31,7 @@ #include "sysemu/sysemu.h" #include "hw/ppc/spapr.h" #include "qapi-event.h" +#include "qemu/cutils.h" #define SPAPR_RTC(obj) \ OBJECT_CHECK(sPAPRRTCState, (obj), TYPE_SPAPR_RTC) diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index 0f61a550cb..8aa021fde9 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -20,6 +20,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "sysemu/sysemu.h" #include "hw/boards.h" diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index 85be24d3da..34b2faf013 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -16,6 +16,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "sysemu/sysemu.h" #include "hw/s390x/sclp.h" diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 41ff002069..f104200273 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -12,6 +12,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "sysemu/sysemu.h" #include "cpu.h" #include "elf.h" diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index f5f679f82c..918b58543e 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -12,6 +12,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "s390-pci-bus.h" #include <hw/pci/pci_bus.h> #include <hw/pci/msi.h> diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index 506147d670..b28e7d14f8 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -12,6 +12,8 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "s390-pci-inst.h" #include "s390-pci-bus.h" #include <exec/memory-internal.h> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 4361c8a5dc..e3df9c78ba 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -10,6 +10,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/boards.h" #include "exec/address-spaces.h" #include "s390-virtio.h" diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c index 7c6e281af1..544c61643d 100644 --- a/hw/s390x/s390-virtio.c +++ b/hw/s390x/s390-virtio.c @@ -22,6 +22,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "qapi/qmp/qerror.h" #include "qemu/error-report.h" diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c index c8cc732163..85dbe1b600 100644 --- a/hw/s390x/sclp.c +++ b/hw/s390x/sclp.c @@ -13,6 +13,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "sysemu/kvm.h" #include "exec/memory.h" diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index cb887ba7e2..d51642db0d 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -11,6 +11,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c index 1de7706644..595f88b352 100644 --- a/hw/scsi/esp-pci.c +++ b/hw/scsi/esp-pci.c @@ -28,6 +28,7 @@ #include "hw/nvram/eeprom93xx.h" #include "hw/scsi/esp.h" #include "trace.h" +#include "qapi/error.h" #include "qemu/log.h" #define TYPE_AM53C974_DEVICE "am53c974" diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index e55c32c642..8961be2f34 100644 --- a/hw/scsi/esp.c +++ b/hw/scsi/esp.c @@ -27,6 +27,7 @@ #include "hw/sysbus.h" #include "hw/scsi/esp.h" #include "trace.h" +#include "qapi/error.h" #include "qemu/log.h" /* diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index a21752b67e..ad6f398c32 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -1,5 +1,6 @@ #include "qemu/osdep.h" #include "hw/hw.h" +#include "qapi/error.h" #include "qemu/error-report.h" #include "hw/scsi/scsi.h" #include "block/scsi.h" @@ -8,6 +9,7 @@ #include "sysemu/blockdev.h" #include "trace.h" #include "sysemu/dma.h" +#include "qemu/cutils.h" static char *scsibus_get_dev_path(DeviceState *dev); static char *scsibus_get_fw_dev_path(DeviceState *dev); diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 469aec2839..c3ce54a203 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -29,7 +29,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0) #endif #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qapi/error.h" #include "qemu/error-report.h" #include "hw/scsi/scsi.h" #include "block/scsi.h" @@ -38,6 +38,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0) #include "sysemu/blockdev.h" #include "hw/block/block.h" #include "sysemu/dma.h" +#include "qemu/cutils.h" #ifdef __linux #include <scsi/sg.h> diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index f8a1ff2cac..7459465f60 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -12,6 +12,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/error-report.h" #include "hw/scsi/scsi.h" diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index e4833d5065..b00edf7fd4 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -32,6 +32,8 @@ * - Maybe do autosense (PAPR seems to mandate it, linux doesn't care) */ #include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/scsi/scsi.h" #include "block/scsi.h" diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index c86622cfeb..9261d51da7 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -15,6 +15,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include <sys/ioctl.h> #include "qemu/error-report.h" #include "qemu/queue.h" @@ -27,6 +28,7 @@ #include "hw/virtio/virtio-access.h" #include "hw/fw-path-provider.h" #include "linux/vhost.h" +#include "qemu/cutils.h" /* Features supported by host kernel. */ static const int kernel_feature_bits[] = { diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c index 367e47643f..b44ac5dfa0 100644 --- a/hw/scsi/virtio-scsi-dataplane.c +++ b/hw/scsi/virtio-scsi-dataplane.c @@ -19,7 +19,6 @@ #include <block/scsi.h> #include <hw/virtio/virtio-bus.h> #include "hw/virtio/virtio-access.h" -#include "stdio.h" /* Context: QEMU global mutex held */ void virtio_scsi_set_iothread(VirtIOSCSI *s, IOThread *iothread) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 0c30d2e692..ade49727d6 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -14,6 +14,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "standard-headers/linux/virtio_ids.h" #include "hw/virtio/virtio-scsi.h" #include "qemu/error-report.h" diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c index 9abc086851..e690b4ec08 100644 --- a/hw/scsi/vmw_pvscsi.c +++ b/hw/scsi/vmw_pvscsi.c @@ -26,6 +26,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/scsi/scsi.h" #include <block/scsi.h> #include "hw/pci/msi.h" diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c index 9c3679b5db..3deccf02c9 100644 --- a/hw/sd/pxa2xx_mmci.c +++ b/hw/sd/pxa2xx_mmci.c @@ -11,6 +11,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/sysbus.h" #include "hw/arm/pxa.h" diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 1568057e4f..b66e5d2dba 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -34,6 +34,7 @@ #include "hw/hw.h" #include "sysemu/block-backend.h" #include "hw/sd/sd.h" +#include "qapi/error.h" #include "qemu/bitmap.h" #include "hw/qdev-properties.h" #include "qemu/error-report.h" diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h index c712daf4ee..161177cf39 100644 --- a/hw/sd/sdhci-internal.h +++ b/hw/sd/sdhci-internal.h @@ -216,7 +216,7 @@ #define SD_HOST_SPECv2_VERS 0x2401 #define SDHC_REGISTERS_MAP_SIZE 0x100 -#define SDHC_INSERTION_DELAY (get_ticks_per_sec()) +#define SDHC_INSERTION_DELAY (NANOSECONDS_PER_SECOND) #define SDHC_TRANSFER_DELAY 100 #define SDHC_ADMA_DESCS_PER_DELAY 5 #define SDHC_CMD_RESPONSE (3 << 0) diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c index 7d9a1cd822..db373c70c5 100644 --- a/hw/sh4/r2d.c +++ b/hw/sh4/r2d.c @@ -24,6 +24,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "hw/hw.h" #include "hw/sh4/sh.h" diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c index 386a4854ea..ccc9e75894 100644 --- a/hw/sh4/shix.c +++ b/hw/sh4/shix.c @@ -28,6 +28,9 @@ More information in target-sh4/README.sh4 */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/sh4/sh.h" #include "sysemu/sysemu.h" diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c index 1362e79b9b..cb8a111102 100644 --- a/hw/smbios/smbios.c +++ b/hw/smbios/smbios.c @@ -16,6 +16,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu/config-file.h" #include "qemu/error-report.h" #include "sysemu/sysemu.h" diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index c579f5b9ea..dbae41f3a4 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -22,6 +22,9 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "qemu/timer.h" #include "hw/ptimer.h" diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index 613ca7e332..7bfc00abc2 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -22,6 +22,9 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/sysbus.h" #include "qemu/error-report.h" #include "qemu/timer.h" @@ -43,6 +46,7 @@ #include "elf.h" #include "sysemu/block-backend.h" #include "trace.h" +#include "qemu/cutils.h" /* * Sun4m architecture was used in the following machines: diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index 54d200300c..3165e18eb7 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -22,6 +22,9 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/pci/pci.h" #include "hw/pci-host/apb.h" @@ -41,6 +44,7 @@ #include "elf.h" #include "sysemu/block-backend.h" #include "exec/address-spaces.h" +#include "qemu/cutils.h" //#define DEBUG_IRQ //#define DEBUG_EBUS @@ -445,12 +449,12 @@ static void hstick_irq(void *opaque) static int64_t cpu_to_timer_ticks(int64_t cpu_ticks, uint32_t frequency) { - return muldiv64(cpu_ticks, get_ticks_per_sec(), frequency); + return muldiv64(cpu_ticks, NANOSECONDS_PER_SECOND, frequency); } static uint64_t timer_to_cpu_ticks(int64_t timer_ticks, uint32_t frequency) { - return muldiv64(timer_ticks, frequency, get_ticks_per_sec()); + return muldiv64(timer_ticks, frequency, NANOSECONDS_PER_SECOND); } void cpu_tick_set_count(CPUTimer *timer, uint64_t count) diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c index fa4602ca04..afe577c76a 100644 --- a/hw/timer/a9gtimer.c +++ b/hw/timer/a9gtimer.c @@ -22,6 +22,7 @@ #include "qemu/osdep.h" #include "hw/timer/a9gtimer.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "qemu/bitops.h" #include "qemu/log.h" diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c index 2bdaf42b72..d66bbf01b4 100644 --- a/hw/timer/arm_mptimer.c +++ b/hw/timer/arm_mptimer.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "hw/timer/arm_mptimer.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "qom/cpu.h" diff --git a/hw/timer/ds1338.c b/hw/timer/ds1338.c index ff315613bd..0112949e23 100644 --- a/hw/timer/ds1338.c +++ b/hw/timer/ds1338.c @@ -11,7 +11,9 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" #include "hw/i2c/i2c.h" +#include "qemu/bcd.h" /* Size of NVRAM including both the user-accessible area and the * secondary register area. diff --git a/hw/timer/exynos4210_rtc.c b/hw/timer/exynos4210_rtc.c index f21fb54f5c..da4dd451b9 100644 --- a/hw/timer/exynos4210_rtc.c +++ b/hw/timer/exynos4210_rtc.c @@ -29,6 +29,7 @@ #include "hw/sysbus.h" #include "qemu/timer.h" #include "qemu-common.h" +#include "qemu/bcd.h" #include "hw/ptimer.h" #include "hw/hw.h" diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index 0ad542037a..78140e6092 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -28,6 +28,7 @@ #include "hw/hw.h" #include "hw/i386/pc.h" #include "ui/console.h" +#include "qapi/error.h" #include "qemu/error-report.h" #include "qemu/timer.h" #include "hw/timer/hpet.h" diff --git a/hw/timer/i8254.c b/hw/timer/i8254.c index b84a33f874..5e61ad50a8 100644 --- a/hw/timer/i8254.c +++ b/hw/timer/i8254.c @@ -53,7 +53,7 @@ static int pit_get_count(PITChannelState *s) int counter; d = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->count_load_time, PIT_FREQ, - get_ticks_per_sec()); + NANOSECONDS_PER_SECOND); switch(s->mode) { case 0: case 1: @@ -263,7 +263,7 @@ static void pit_irq_timer_update(PITChannelState *s, int64_t current_time) #ifdef DEBUG_PIT printf("irq_level=%d next_delay=%f\n", irq_level, - (double)(expire_time - current_time) / get_ticks_per_sec()); + (double)(expire_time - current_time) / NANOSECONDS_PER_SECOND); #endif s->next_transition_time = expire_time; if (expire_time != -1) diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c index ed511b885b..e18299a482 100644 --- a/hw/timer/i8254_common.c +++ b/hw/timer/i8254_common.c @@ -47,7 +47,7 @@ int pit_get_out(PITChannelState *s, int64_t current_time) int out; d = muldiv64(current_time - s->count_load_time, PIT_FREQ, - get_ticks_per_sec()); + NANOSECONDS_PER_SECOND); switch (s->mode) { default: case 0: @@ -81,7 +81,7 @@ int64_t pit_get_next_transition_time(PITChannelState *s, int64_t current_time) int period2; d = muldiv64(current_time - s->count_load_time, PIT_FREQ, - get_ticks_per_sec()); + NANOSECONDS_PER_SECOND); switch (s->mode) { default: case 0: @@ -121,7 +121,7 @@ int64_t pit_get_next_transition_time(PITChannelState *s, int64_t current_time) break; } /* convert to timer units */ - next_time = s->count_load_time + muldiv64(next_time, get_ticks_per_sec(), + next_time = s->count_load_time + muldiv64(next_time, NANOSECONDS_PER_SECOND, PIT_FREQ); /* fix potential rounding problems */ /* XXX: better solution: use a clock at PIT_FREQ Hz */ diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c index bbcfeb2192..e46ca88391 100644 --- a/hw/timer/m48t59.c +++ b/hw/timer/m48t59.c @@ -25,11 +25,13 @@ #include "qemu/osdep.h" #include "hw/hw.h" #include "hw/timer/m48t59.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "sysemu/sysemu.h" #include "hw/sysbus.h" #include "hw/isa/isa.h" #include "exec/address-spaces.h" +#include "qemu/bcd.h" //#define DEBUG_NVRAM diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index eb0100aa25..2ac0fd3e48 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -22,6 +22,9 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "config-target.h" +#include "qemu/cutils.h" +#include "qemu/bcd.h" #include "hw/hw.h" #include "qemu/timer.h" #include "sysemu/sysemu.h" @@ -106,8 +109,8 @@ static uint64_t get_guest_rtc_ns(RTCState *s) uint64_t guest_rtc; uint64_t guest_clock = qemu_clock_get_ns(rtc_clock); - guest_rtc = s->base_rtc * NANOSECONDS_PER_SECOND - + guest_clock - s->last_update + s->offset; + guest_rtc = s->base_rtc * NANOSECONDS_PER_SECOND + + guest_clock - s->last_update + s->offset; return guest_rtc; } @@ -120,7 +123,7 @@ static void rtc_coalesced_timer_update(RTCState *s) /* divide each RTC interval to 2 - 8 smaller intervals */ int c = MIN(s->irq_coalesced, 7) + 1; int64_t next_clock = qemu_clock_get_ns(rtc_clock) + - muldiv64(s->period / c, get_ticks_per_sec(), RTC_CLOCK_RATE); + muldiv64(s->period / c, NANOSECONDS_PER_SECOND, RTC_CLOCK_RATE); timer_mod(s->coalesced_timer, next_clock); } } @@ -166,10 +169,12 @@ static void periodic_timer_update(RTCState *s, int64_t current_time) s->period = period; #endif /* compute 32 khz clock */ - cur_clock = muldiv64(current_time, RTC_CLOCK_RATE, get_ticks_per_sec()); + cur_clock = + muldiv64(current_time, RTC_CLOCK_RATE, NANOSECONDS_PER_SECOND); + next_irq_clock = (cur_clock & ~(period - 1)) + period; - s->next_periodic_time = - muldiv64(next_irq_clock, get_ticks_per_sec(), RTC_CLOCK_RATE) + 1; + s->next_periodic_time = muldiv64(next_irq_clock, NANOSECONDS_PER_SECOND, + RTC_CLOCK_RATE) + 1; timer_mod(s->periodic_timer, s->next_periodic_time); } else { #ifdef TARGET_I386 diff --git a/hw/timer/omap_gptimer.c b/hw/timer/omap_gptimer.c index b30342129a..3a43863042 100644 --- a/hw/timer/omap_gptimer.c +++ b/hw/timer/omap_gptimer.c @@ -402,7 +402,7 @@ static void omap_gp_timer_write(void *opaque, hwaddr addr, if (s->trigger == gpt_trigger_none) omap_gp_timer_out(s, s->scpwm); /* TODO: make sure this doesn't overflow 32-bits */ - s->ticks_per_sec = get_ticks_per_sec() << (s->pre ? s->ptv + 1 : 0); + s->ticks_per_sec = NANOSECONDS_PER_SECOND << (s->pre ? s->ptv + 1 : 0); omap_gp_timer_update(s); break; diff --git a/hw/timer/omap_synctimer.c b/hw/timer/omap_synctimer.c index edd8d98d57..9ee6519793 100644 --- a/hw/timer/omap_synctimer.c +++ b/hw/timer/omap_synctimer.c @@ -29,7 +29,8 @@ struct omap_synctimer_s { /* 32-kHz Sync Timer of the OMAP2 */ static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) { - return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 0x8000, get_ticks_per_sec()); + return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 0x8000, + NANOSECONDS_PER_SECOND); } void omap_synctimer_reset(struct omap_synctimer_s *s) diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c index 3ccb2cb460..38e0cb5ad6 100644 --- a/hw/timer/pl031.c +++ b/hw/timer/pl031.c @@ -15,6 +15,7 @@ #include "hw/sysbus.h" #include "qemu/timer.h" #include "sysemu/sysemu.h" +#include "qemu/cutils.h" //#define DEBUG_PL031 @@ -80,7 +81,7 @@ static void pl031_interrupt(void * opaque) static uint32_t pl031_get_count(PL031State *s) { int64_t now = qemu_clock_get_ns(rtc_clock); - return s->tick_offset + now / get_ticks_per_sec(); + return s->tick_offset + now / NANOSECONDS_PER_SECOND; } static void pl031_set_alarm(PL031State *s) @@ -96,7 +97,7 @@ static void pl031_set_alarm(PL031State *s) pl031_interrupt(s); } else { int64_t now = qemu_clock_get_ns(rtc_clock); - timer_mod(s->timer, now + (int64_t)ticks * get_ticks_per_sec()); + timer_mod(s->timer, now + (int64_t)ticks * NANOSECONDS_PER_SECOND); } } @@ -204,7 +205,7 @@ static void pl031_init(Object *obj) sysbus_init_irq(dev, &s->irq); qemu_get_timedate(&tm, 0); s->tick_offset = mktimegm(&tm) - - qemu_clock_get_ns(rtc_clock) / get_ticks_per_sec(); + qemu_clock_get_ns(rtc_clock) / NANOSECONDS_PER_SECOND; s->timer = timer_new_ns(rtc_clock, pl031_interrupt, s); } @@ -216,7 +217,7 @@ static void pl031_pre_save(void *opaque) /* tick_offset is base_time - rtc_clock base time. Instead, we want to * store the base time relative to the QEMU_CLOCK_VIRTUAL for backwards-compatibility. */ int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - s->tick_offset_vmstate = s->tick_offset + delta / get_ticks_per_sec(); + s->tick_offset_vmstate = s->tick_offset + delta / NANOSECONDS_PER_SECOND; } static int pl031_post_load(void *opaque, int version_id) @@ -224,7 +225,7 @@ static int pl031_post_load(void *opaque, int version_id) PL031State *s = opaque; int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - s->tick_offset = s->tick_offset_vmstate - delta / get_ticks_per_sec(); + s->tick_offset = s->tick_offset_vmstate - delta / NANOSECONDS_PER_SECOND; pl031_set_alarm(s); return 0; } diff --git a/hw/timer/pxa2xx_timer.c b/hw/timer/pxa2xx_timer.c index 33449e66b5..59002b407e 100644 --- a/hw/timer/pxa2xx_timer.c +++ b/hw/timer/pxa2xx_timer.c @@ -119,11 +119,11 @@ static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu) uint64_t new_qemu; now_vm = s->clock + - muldiv64(now_qemu - s->lastload, s->freq, get_ticks_per_sec()); + muldiv64(now_qemu - s->lastload, s->freq, NANOSECONDS_PER_SECOND); for (i = 0; i < 4; i ++) { new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm), - get_ticks_per_sec(), s->freq); + NANOSECONDS_PER_SECOND, s->freq); timer_mod(s->timer[i].qtimer, new_qemu); } } @@ -148,10 +148,10 @@ static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n) now_vm = s->tm4[counter].clock + muldiv64(now_qemu - s->tm4[counter].lastload, - s->tm4[counter].freq, get_ticks_per_sec()); + s->tm4[counter].freq, NANOSECONDS_PER_SECOND); new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm), - get_ticks_per_sec(), s->tm4[counter].freq); + NANOSECONDS_PER_SECOND, s->tm4[counter].freq); timer_mod(s->tm4[n].tm.qtimer, new_qemu); } @@ -190,7 +190,7 @@ static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset, return s->tm4[tm].tm.value; case OSCR: return s->clock + muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - - s->lastload, s->freq, get_ticks_per_sec()); + s->lastload, s->freq, NANOSECONDS_PER_SECOND); case OSCR11: tm ++; /* fall through */ case OSCR10: tm ++; @@ -214,15 +214,17 @@ static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset, s->snapshot = s->tm4[tm - 1].clock + muldiv64( qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->tm4[tm - 1].lastload, - s->tm4[tm - 1].freq, get_ticks_per_sec()); + s->tm4[tm - 1].freq, NANOSECONDS_PER_SECOND); else s->snapshot = s->tm4[tm - 1].clock; } if (!s->tm4[tm].freq) return s->tm4[tm].clock; - return s->tm4[tm].clock + muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - - s->tm4[tm].lastload, s->tm4[tm].freq, get_ticks_per_sec()); + return s->tm4[tm].clock + + muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - + s->tm4[tm].lastload, s->tm4[tm].freq, + NANOSECONDS_PER_SECOND); case OIER: return s->irq_enabled; case OSSR: /* Status register */ diff --git a/hw/timer/twl92230.c b/hw/timer/twl92230.c index 1c92438b18..7ba4e9a7c9 100644 --- a/hw/timer/twl92230.c +++ b/hw/timer/twl92230.c @@ -25,6 +25,7 @@ #include "hw/i2c/i2c.h" #include "sysemu/sysemu.h" #include "ui/console.h" +#include "qemu/bcd.h" #define VERBOSE 1 diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c index c1c3d4dcc3..381e7266ea 100644 --- a/hw/tpm/tpm_tis.c +++ b/hw/tpm/tpm_tis.c @@ -31,6 +31,7 @@ #include "hw/i386/pc.h" #include "hw/pci/pci_ids.h" #include "tpm_tis.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/main-loop.h" #include "sysemu/tpm_backend.h" diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c index 3cadb6521c..8d3520f5be 100644 --- a/hw/tricore/tricore_testboard.c +++ b/hw/tricore/tricore_testboard.c @@ -19,6 +19,9 @@ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "hw/hw.h" #include "hw/devices.h" #include "net/net.h" diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c index 4522fa263b..31cd171016 100644 --- a/hw/unicore32/puv3.c +++ b/hw/unicore32/puv3.c @@ -10,6 +10,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "qemu-common.h" #include "ui/console.h" #include "elf.h" diff --git a/hw/usb/bus.c b/hw/usb/bus.c index 4452bdbe20..16c3461d99 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -2,10 +2,12 @@ #include "hw/hw.h" #include "hw/usb.h" #include "hw/qdev.h" +#include "qapi/error.h" #include "qemu/error-report.h" #include "sysemu/sysemu.h" #include "monitor/monitor.h" #include "trace.h" +#include "qemu/cutils.h" static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent); diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c index 40f38ad45e..24d05f76f9 100644 --- a/hw/usb/dev-hid.c +++ b/hw/usb/dev-hid.c @@ -27,6 +27,7 @@ #include "ui/console.h" #include "hw/usb.h" #include "hw/usb/desc.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "hw/input/hid.h" diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c index 64acdb0af0..a33f21cb38 100644 --- a/hw/usb/dev-hub.c +++ b/hw/usb/dev-hub.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "trace.h" #include "hw/usb.h" diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index ee2071f3d5..bda84a64bd 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -10,12 +10,14 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include <wchar.h> #include <dirent.h> #include <sys/statvfs.h> #ifdef CONFIG_INOTIFY1 #include <sys/inotify.h> +#include "qapi/error.h" #include "qemu/main-loop.h" #endif diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c index c6abd38c2a..74306b58e3 100644 --- a/hw/usb/dev-network.c +++ b/hw/usb/dev-network.c @@ -24,6 +24,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "hw/usb.h" #include "hw/usb/desc.h" @@ -33,6 +34,7 @@ #include "qemu/config-file.h" #include "sysemu/sysemu.h" #include "qemu/iov.h" +#include "qemu/cutils.h" /*#define TRAFFIC_DEBUG*/ /* Thanks to NetChip Technologies for donating this product ID. diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c index afad1db8b3..ba8538e60e 100644 --- a/hw/usb/dev-serial.c +++ b/hw/usb/dev-serial.c @@ -9,7 +9,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" +#include "qemu/cutils.h" #include "qemu/error-report.h" #include "hw/usb.h" #include "hw/usb/desc.h" diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c index 96a1a13812..af4b851356 100644 --- a/hw/usb/dev-smartcard-reader.c +++ b/hw/usb/dev-smartcard-reader.c @@ -35,6 +35,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/error-report.h" #include "hw/usb.h" diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index 5ae0424923..248a580457 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -8,6 +8,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/error-report.h" #include "qemu/option.h" @@ -21,6 +22,7 @@ #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" #include "qapi/visitor.h" +#include "qemu/cutils.h" //#define DEBUG_MSD diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 0f95d0d284..159f58d5a0 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -28,6 +28,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/usb/ehci-regs.h" #include "hw/usb/hcd-ehci.h" #include "trace.h" @@ -2308,10 +2309,11 @@ static void ehci_frame_timer(void *opaque) /* If we've raised int, we speed up the timer, so that we quickly * notice any new packets queued up in response */ if (ehci->int_req_by_async && (ehci->usbsts & USBSTS_INT)) { - expire_time = t_now + get_ticks_per_sec() / (FRAME_TIMER_FREQ * 4); + expire_time = t_now + + NANOSECONDS_PER_SECOND / (FRAME_TIMER_FREQ * 4); ehci->int_req_by_async = false; } else { - expire_time = t_now + (get_ticks_per_sec() + expire_time = t_now + (NANOSECONDS_PER_SECOND * (ehci->async_stepdown+1) / FRAME_TIMER_FREQ); } timer_mod(ehci->frame_timer, expire_time); diff --git a/hw/usb/hcd-musb.c b/hw/usb/hcd-musb.c index cd2319735f..27d9d0bd82 100644 --- a/hw/usb/hcd-musb.c +++ b/hw/usb/hcd-musb.c @@ -564,7 +564,7 @@ static void musb_schedule_cb(USBPort *port, USBPacket *packey) ep->intv_timer[dir] = timer_new_ns(QEMU_CLOCK_VIRTUAL, musb_cb_tick, ep); timer_mod(ep->intv_timer[dir], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - muldiv64(timeout, get_ticks_per_sec(), 8000)); + muldiv64(timeout, NANOSECONDS_PER_SECOND, 8000)); } static int musb_timeout(int ttype, int speed, int val) diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 17ed4617ef..ffab561cf6 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -27,6 +27,7 @@ #include "qemu/osdep.h" #include "hw/hw.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "hw/usb.h" #include "hw/pci/pci.h" @@ -1849,12 +1850,12 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev, if (usb_frame_time == 0) { #ifdef OHCI_TIME_WARP - usb_frame_time = get_ticks_per_sec(); - usb_bit_time = muldiv64(1, get_ticks_per_sec(), USB_HZ/1000); + usb_frame_time = NANOSECONDS_PER_SECOND; + usb_bit_time = NANOSECONDS_PER_SECOND / (USB_HZ / 1000); #else - usb_frame_time = muldiv64(1, get_ticks_per_sec(), 1000); - if (get_ticks_per_sec() >= USB_HZ) { - usb_bit_time = muldiv64(1, get_ticks_per_sec(), USB_HZ); + usb_frame_time = NANOSECONDS_PER_SECOND / 1000; + if (NANOSECONDS_PER_SECOND >= USB_HZ) { + usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ; } else { usb_bit_time = 1; } diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index c370240be2..18057bfb6e 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -30,6 +30,7 @@ #include "hw/usb.h" #include "hw/usb/uhci-regs.h" #include "hw/pci/pci.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "qemu/iov.h" #include "sysemu/dma.h" @@ -402,7 +403,7 @@ static int uhci_post_load(void *opaque, int version_id) if (version_id < 2) { s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - (get_ticks_per_sec() / FRAME_TIMER_FREQ); + (NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ); } return 0; } @@ -444,7 +445,7 @@ static void uhci_port_write(void *opaque, hwaddr addr, /* start frame processing */ trace_usb_uhci_schedule_start(); s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - (get_ticks_per_sec() / FRAME_TIMER_FREQ); + (NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ); timer_mod(s->frame_timer, s->expire_time); s->status &= ~UHCI_STS_HCHALTED; } else if (!(val & UHCI_CMD_RS)) { @@ -1130,7 +1131,7 @@ static void uhci_frame_timer(void *opaque) UHCIState *s = opaque; uint64_t t_now, t_last_run; int i, frames; - const uint64_t frame_t = get_ticks_per_sec() / FRAME_TIMER_FREQ; + const uint64_t frame_t = NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ; s->completions_only = false; qemu_bh_cancel(s->bh); diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index 5e7ec453d0..6458a94485 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -37,6 +37,7 @@ #include <poll.h> #include <libusb.h> +#include "qapi/error.h" #include "qemu-common.h" #include "monitor/monitor.h" #include "qemu/error-report.h" diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index cbcc218183..8d8054037f 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -26,6 +26,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/timer.h" #include "sysemu/sysemu.h" diff --git a/hw/usb/tusb6010.c b/hw/usb/tusb6010.c index 9f6af90806..8f593a6fdb 100644 --- a/hw/usb/tusb6010.c +++ b/hw/usb/tusb6010.c @@ -516,7 +516,7 @@ static void tusb_async_writew(void *opaque, hwaddr addr, if (value & TUSB_DEV_OTG_TIMER_ENABLE) timer_mod(s->otg_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + muldiv64(TUSB_DEV_OTG_TIMER_VAL(value), - get_ticks_per_sec(), TUSB_DEVCLOCK)); + NANOSECONDS_PER_SECOND, TUSB_DEVCLOCK)); else timer_del(s->otg_timer); break; @@ -726,8 +726,8 @@ static void tusb6010_power(TUSBState *s, int on) /* Pull the interrupt down after TUSB6010 comes up. */ s->intr_ok = 0; tusb_intr_update(s); - timer_mod(s->pwr_timer, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + get_ticks_per_sec() / 2); + timer_mod(s->pwr_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + NANOSECONDS_PER_SECOND / 2); } } diff --git a/hw/vfio/common.c b/hw/vfio/common.c index fb588d8d8e..f27db36fb3 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -323,7 +323,7 @@ static void vfio_listener_region_add(MemoryListener *listener, { VFIOContainer *container = container_of(listener, VFIOContainer, listener); hwaddr iova, end; - Int128 llend; + Int128 llend, llsize; void *vaddr; int ret; @@ -349,12 +349,12 @@ static void vfio_listener_region_add(MemoryListener *listener, if (int128_ge(int128_make64(iova), llend)) { return; } - end = int128_get64(llend); + end = int128_get64(int128_sub(llend, int128_one())); - if ((iova < container->min_iova) || ((end - 1) > container->max_iova)) { + if ((iova < container->min_iova) || (end > container->max_iova)) { error_report("vfio: IOMMU container %p can't map guest IOVA region" " 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx, - container, iova, end - 1); + container, iova, end); ret = -EFAULT; goto fail; } @@ -364,7 +364,7 @@ static void vfio_listener_region_add(MemoryListener *listener, if (memory_region_is_iommu(section->mr)) { VFIOGuestIOMMU *giommu; - trace_vfio_listener_region_add_iommu(iova, end - 1); + trace_vfio_listener_region_add_iommu(iova, end); /* * FIXME: We should do some checking to see if the * capabilities of the host VFIO IOMMU are adequate to model @@ -395,13 +395,16 @@ static void vfio_listener_region_add(MemoryListener *listener, section->offset_within_region + (iova - section->offset_within_address_space); - trace_vfio_listener_region_add_ram(iova, end - 1, vaddr); + trace_vfio_listener_region_add_ram(iova, end, vaddr); - ret = vfio_dma_map(container, iova, end - iova, vaddr, section->readonly); + llsize = int128_sub(llend, int128_make64(iova)); + + ret = vfio_dma_map(container, iova, int128_get64(llsize), + vaddr, section->readonly); if (ret) { error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", " "0x%"HWADDR_PRIx", %p) = %d (%m)", - container, iova, end - iova, vaddr, ret); + container, iova, int128_get64(llsize), vaddr, ret); goto fail; } diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c index a2ab75d3f2..1798a00a3f 100644 --- a/hw/vfio/platform.c +++ b/hw/vfio/platform.c @@ -15,6 +15,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include <sys/ioctl.h> #include <linux/vfio.h> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 7ed3dd9a13..5914e85107 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -9,6 +9,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/virtio/vhost.h" #include "hw/virtio/vhost-backend.h" #include "hw/virtio/virtio-net.h" diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 392d848819..4400718154 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -14,6 +14,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/virtio/vhost.h" #include "hw/hw.h" #include "qemu/atomic.h" diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 0dadb6687f..bfedbbf17f 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -26,6 +26,7 @@ #include "hw/virtio/virtio-balloon.h" #include "hw/virtio/virtio-input.h" #include "hw/pci/pci.h" +#include "qapi/error.h" #include "qemu/error-report.h" #include "hw/pci/msi.h" #include "hw/pci/msix.h" diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index d7134646e2..6b991a7642 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -10,6 +10,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu/iov.h" #include "hw/qdev.h" #include "hw/virtio/virtio.h" diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 08275a9848..14d5d91397 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -12,7 +12,9 @@ */ #include "qemu/osdep.h" - +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "trace.h" #include "exec/address-spaces.h" #include "qemu/error-report.h" diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c index 194c9b4ed9..bbf3646bae 100644 --- a/hw/watchdog/watchdog.c +++ b/hw/watchdog/watchdog.c @@ -20,7 +20,6 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" #include "qemu/option.h" #include "qemu/config-file.h" #include "qemu/queue.h" @@ -29,6 +28,7 @@ #include "sysemu/watchdog.h" #include "qapi-event.h" #include "hw/nmi.h" +#include "qemu/help_option.h" static int watchdog_action = WDT_RESET; static QLIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list; diff --git a/hw/watchdog/wdt_diag288.c b/hw/watchdog/wdt_diag288.c index 1c3658e4a8..f54a35a0e3 100644 --- a/hw/watchdog/wdt_diag288.c +++ b/hw/watchdog/wdt_diag288.c @@ -79,7 +79,7 @@ static int wdt_diag288_handle_timer(DIAG288State *diag288, } timer_mod(diag288->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - timeout * get_ticks_per_sec()); + timeout * NANOSECONDS_PER_SECOND); break; case WDT_DIAG288_CANCEL: if (!diag288->enabled) { diff --git a/hw/watchdog/wdt_ib700.c b/hw/watchdog/wdt_ib700.c index 532530b95b..532afe89e7 100644 --- a/hw/watchdog/wdt_ib700.c +++ b/hw/watchdog/wdt_ib700.c @@ -64,7 +64,7 @@ static void ib700_write_enable_reg(void *vp, uint32_t addr, uint32_t data) ib700_debug("addr = %x, data = %x\n", addr, data); - timeout = (int64_t) time_map[data & 0xF] * get_ticks_per_sec(); + timeout = (int64_t) time_map[data & 0xF] * NANOSECONDS_PER_SECOND; timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout); } diff --git a/hw/xen/xen-host-pci-device.c b/hw/xen/xen-host-pci-device.c index 9666fff8c9..eed8cc88e3 100644 --- a/hw/xen/xen-host-pci-device.c +++ b/hw/xen/xen-host-pci-device.c @@ -7,7 +7,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" +#include "qemu/cutils.h" #include "xen-host-pci-device.h" #define XEN_HOST_PCI_MAX_EXT_CAP \ diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index 657bf6cdc1..f593b046e5 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -53,6 +53,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include <sys/ioctl.h> #include "hw/pci/pci.h" diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c index 1b48f19183..9869ffda01 100644 --- a/hw/xen/xen_pt_config_init.c +++ b/hw/xen/xen_pt_config_init.c @@ -13,6 +13,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "hw/xen/xen_backend.h" #include "xen_pt.h" diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c index 71e745f8ca..0f4c8d77e2 100644 --- a/hw/xen/xen_pt_graphics.c +++ b/hw/xen/xen_pt_graphics.c @@ -2,6 +2,7 @@ * graphics passthrough */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "xen_pt.h" #include "xen-host-pci-device.h" #include "hw/xen/xen_backend.h" diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c index 23050e8fb7..5e94004261 100644 --- a/hw/xtensa/sim.c +++ b/hw/xtensa/sim.c @@ -26,6 +26,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "sysemu/sysemu.h" #include "hw/boards.h" #include "hw/loader.h" diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c index 54e7f46868..2d117369af 100644 --- a/hw/xtensa/xtfpga.c +++ b/hw/xtensa/xtfpga.c @@ -26,6 +26,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" #include "sysemu/sysemu.h" #include "hw/boards.h" #include "hw/loader.h" diff --git a/include/block/accounting.h b/include/block/accounting.h index 2db2a009a1..20891639d5 100644 --- a/include/block/accounting.h +++ b/include/block/accounting.h @@ -25,8 +25,6 @@ #ifndef BLOCK_ACCOUNTING_H #define BLOCK_ACCOUNTING_H - -#include "qemu/typedefs.h" #include "qemu/timed-average.h" typedef struct BlockAcctTimedStats BlockAcctTimedStats; diff --git a/include/block/aio.h b/include/block/aio.h index e086e3b4ee..88a64eeb3c 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -14,7 +14,6 @@ #ifndef QEMU_AIO_H #define QEMU_AIO_H -#include "qemu/typedefs.h" #include "qemu-common.h" #include "qemu/queue.h" #include "qemu/event_notifier.h" diff --git a/include/block/block.h b/include/block/block.h index 01349efad5..47e80bc204 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -2,7 +2,7 @@ #define BLOCK_H #include "block/aio.h" -#include "qemu-common.h" +#include "qemu/iov.h" #include "qemu/option.h" #include "qemu/coroutine.h" #include "block/accounting.h" diff --git a/include/block/write-threshold.h b/include/block/write-threshold.h index 8a79505ada..234d2193e0 100644 --- a/include/block/write-threshold.h +++ b/include/block/write-threshold.h @@ -12,8 +12,6 @@ #ifndef BLOCK_WRITE_THRESHOLD_H #define BLOCK_WRITE_THRESHOLD_H - -#include "qemu/typedefs.h" #include "qemu-common.h" /* diff --git a/include/crypto/cipher.h b/include/crypto/cipher.h index c04c3ac9b9..d770c4835a 100644 --- a/include/crypto/cipher.h +++ b/include/crypto/cipher.h @@ -21,7 +21,7 @@ #ifndef QCRYPTO_CIPHER_H__ #define QCRYPTO_CIPHER_H__ -#include "qemu-common.h" +#include "qapi-types.h" typedef struct QCryptoCipher QCryptoCipher; diff --git a/include/crypto/hash.h b/include/crypto/hash.h index aebccd1386..f38caed669 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h @@ -21,7 +21,7 @@ #ifndef QCRYPTO_HASH_H__ #define QCRYPTO_HASH_H__ -#include "qemu-common.h" +#include "qapi-types.h" /* See also "QCryptoHashAlgorithm" defined in qapi/crypto.json */ diff --git a/include/crypto/init.h b/include/crypto/init.h index 4836a37e3f..2513ed0986 100644 --- a/include/crypto/init.h +++ b/include/crypto/init.h @@ -21,8 +21,6 @@ #ifndef QCRYPTO_INIT_H__ #define QCRYPTO_INIT_H__ -#include "qemu-common.h" - int qcrypto_init(Error **errp); #endif /* QCRYPTO_INIT_H__ */ diff --git a/include/crypto/secret.h b/include/crypto/secret.h index 60f2a502b7..b7392c6ba0 100644 --- a/include/crypto/secret.h +++ b/include/crypto/secret.h @@ -21,7 +21,6 @@ #ifndef QCRYPTO_SECRET_H__ #define QCRYPTO_SECRET_H__ -#include "qemu-common.h" #include "qom/object.h" #define TYPE_QCRYPTO_SECRET "secret" diff --git a/include/crypto/tlscreds.h b/include/crypto/tlscreds.h index 4bf1d2e255..8e2babd533 100644 --- a/include/crypto/tlscreds.h +++ b/include/crypto/tlscreds.h @@ -21,7 +21,6 @@ #ifndef QCRYPTO_TLSCRED_H__ #define QCRYPTO_TLSCRED_H__ -#include "qemu-common.h" #include "qom/object.h" #ifdef CONFIG_GNUTLS diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index a0ad2acb43..9e839e50cd 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -14,7 +14,6 @@ #include "qemu/bswap.h" #include "qemu/queue.h" #include "qemu/fprintf-fn.h" -#include "qemu/typedefs.h" /** * CPUListState: diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 05a151da4a..736209505a 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -379,6 +379,11 @@ static inline void tb_add_jump(TranslationBlock *tb, int n, { /* NOTE: this test is only needed for thread safety */ if (!tb->jmp_next[n]) { + qemu_log_mask_and_addr(CPU_LOG_EXEC, tb->pc, + "Linking TBs %p [" TARGET_FMT_lx + "] index %d -> %p [" TARGET_FMT_lx "]\n", + tb->tc_ptr, tb->pc, n, + tb_next->tc_ptr, tb_next->pc); /* patch the native jump address */ tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc_ptr); diff --git a/include/exec/memory.h b/include/exec/memory.h index 2de789871d..e2a3e9953c 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -31,7 +31,6 @@ #include "qemu/notify.h" #include "qom/object.h" #include "qemu/rcu.h" -#include "qemu/typedefs.h" #define MAX_PHYS_ADDR_SPACE_BITS 62 #define MAX_PHYS_ADDR (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1) diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h index 7462e20fe3..e0978c8b92 100644 --- a/include/hw/acpi/acpi.h +++ b/include/hw/acpi/acpi.h @@ -19,7 +19,6 @@ * <http://www.gnu.org/licenses/>. */ -#include "qemu/typedefs.h" #include "qemu/notify.h" #include "qemu/option.h" #include "exec/memory.h" @@ -155,7 +154,7 @@ void acpi_pm_tmr_reset(ACPIREGS *ar); static inline int64_t acpi_pm_tmr_get_clock(void) { return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY, - get_ticks_per_sec()); + NANOSECONDS_PER_SECOND); } /* PM1a_EVT: piix and ich9 don't implement PM1b. */ diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h index 31b7820b6f..79a43923e8 100644 --- a/include/hw/acpi/pcihp.h +++ b/include/hw/acpi/pcihp.h @@ -27,7 +27,6 @@ #ifndef HW_ACPI_PCIHP_H #define HW_ACPI_PCIHP_H -#include <qemu/typedefs.h> #include "hw/acpi/acpi.h" #include "migration/vmstate.h" diff --git a/include/hw/acpi/piix4.h b/include/hw/acpi/piix4.h index 65e6fd7aa0..26c2370e30 100644 --- a/include/hw/acpi/piix4.h +++ b/include/hw/acpi/piix4.h @@ -1,8 +1,6 @@ #ifndef HW_ACPI_PIIX4_H #define HW_ACPI_PIIX4_H -#include "qemu/typedefs.h" - Object *piix4_pm_find(void); #endif diff --git a/include/hw/acpi/tco.h b/include/hw/acpi/tco.h index c63afc8ca3..52ad767ddd 100644 --- a/include/hw/acpi/tco.h +++ b/include/hw/acpi/tco.h @@ -9,7 +9,6 @@ #ifndef HW_ACPI_TCO_H #define HW_ACPI_TCO_H -#include "qemu/typedefs.h" #include "qemu-common.h" /* As per ICH9 spec, the internal timer has an error of ~0.6s on every tick */ diff --git a/include/hw/boards.h b/include/hw/boards.h index 8efce0f91e..aad5f2a99f 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -3,7 +3,6 @@ #ifndef HW_BOARDS_H #define HW_BOARDS_H -#include "qemu/typedefs.h" #include "sysemu/blockdev.h" #include "sysemu/accel.h" #include "hw/qdev.h" diff --git a/include/hw/char/digic-uart.h b/include/hw/char/digic-uart.h index ef83a3059c..7b3f145372 100644 --- a/include/hw/char/digic-uart.h +++ b/include/hw/char/digic-uart.h @@ -19,7 +19,6 @@ #define HW_CHAR_DIGIC_UART_H #include "hw/sysbus.h" -#include "qemu/typedefs.h" #define TYPE_DIGIC_UART "digic-uart" #define DIGIC_UART(obj) \ diff --git a/include/hw/hotplug.h b/include/hw/hotplug.h index 2db025d0bd..da1d0e4ab8 100644 --- a/include/hw/hotplug.h +++ b/include/hw/hotplug.h @@ -13,7 +13,6 @@ #define HOTPLUG_H #include "qom/object.h" -#include "qemu/typedefs.h" #define TYPE_HOTPLUG_HANDLER "hotplug-handler" diff --git a/include/hw/hw.h b/include/hw/hw.h index cd3d410f97..2cb69d5f5b 100644 --- a/include/hw/hw.h +++ b/include/hw/hw.h @@ -2,7 +2,6 @@ #ifndef QEMU_HW_H #define QEMU_HW_H -#include "qemu-common.h" #if !defined(CONFIG_USER_ONLY) && !defined(NEED_CPU_H) #include "exec/cpu-common.h" @@ -13,6 +12,7 @@ #include "block/aio.h" #include "migration/vmstate.h" #include "qemu/log.h" +#include "qemu/module.h" #ifdef NEED_CPU_H #if TARGET_LONG_BITS == 64 @@ -41,6 +41,8 @@ typedef void QEMUResetHandler(void *opaque); void qemu_register_reset(QEMUResetHandler *func, void *opaque); void qemu_unregister_reset(QEMUResetHandler *func, void *opaque); +void QEMU_NORETURN hw_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2); + #ifdef NEED_CPU_H #if TARGET_LONG_BITS == 64 #define VMSTATE_UINTTL_V(_f, _s, _v) \ diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 847d92f550..96f0b66c77 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -2,7 +2,6 @@ #define HW_PC_H #include "qemu-common.h" -#include "qemu/typedefs.h" #include "exec/memory.h" #include "hw/boards.h" #include "hw/isa/isa.h" diff --git a/include/hw/isa/i8257.h b/include/hw/isa/i8257.h index 8d34ed17b7..8c44d36282 100644 --- a/include/hw/isa/i8257.h +++ b/include/hw/isa/i8257.h @@ -11,7 +11,7 @@ typedef struct I8257Regs { uint8_t pageh; uint8_t dack; uint8_t eop; - DMA_transfer_handler transfer_handler; + IsaDmaTransferHandler transfer_handler; void *opaque; } I8257Regs; diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h index 0bbe21cd48..ffb2ea7cdf 100644 --- a/include/hw/isa/isa.h +++ b/include/hw/isa/isa.h @@ -54,6 +54,9 @@ typedef enum { ISADMA_TRANSFER_ILLEGAL, } IsaDmaTransferMode; +typedef int (*IsaDmaTransferHandler)(void *opaque, int nchan, int pos, + int size); + typedef struct IsaDmaClass { InterfaceClass parent; @@ -65,7 +68,7 @@ typedef struct IsaDmaClass { void (*release_DREQ)(IsaDma *obj, int nchan); void (*schedule)(IsaDma *obj); void (*register_channel)(IsaDma *obj, int nchan, - DMA_transfer_handler transfer_handler, + IsaDmaTransferHandler transfer_handler, void *opaque); } IsaDmaClass; diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index 4315f4e582..d5169895dc 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -1,55 +1,9 @@ #ifndef FW_CFG_H #define FW_CFG_H -#ifndef NO_QEMU_PROTOS - #include "exec/hwaddr.h" -#include "qemu/typedefs.h" -#endif +#include "hw/nvram/fw_cfg_keys.h" -#define FW_CFG_SIGNATURE 0x00 -#define FW_CFG_ID 0x01 -#define FW_CFG_UUID 0x02 -#define FW_CFG_RAM_SIZE 0x03 -#define FW_CFG_NOGRAPHIC 0x04 -#define FW_CFG_NB_CPUS 0x05 -#define FW_CFG_MACHINE_ID 0x06 -#define FW_CFG_KERNEL_ADDR 0x07 -#define FW_CFG_KERNEL_SIZE 0x08 -#define FW_CFG_KERNEL_CMDLINE 0x09 -#define FW_CFG_INITRD_ADDR 0x0a -#define FW_CFG_INITRD_SIZE 0x0b -#define FW_CFG_BOOT_DEVICE 0x0c -#define FW_CFG_NUMA 0x0d -#define FW_CFG_BOOT_MENU 0x0e -#define FW_CFG_MAX_CPUS 0x0f -#define FW_CFG_KERNEL_ENTRY 0x10 -#define FW_CFG_KERNEL_DATA 0x11 -#define FW_CFG_INITRD_DATA 0x12 -#define FW_CFG_CMDLINE_ADDR 0x13 -#define FW_CFG_CMDLINE_SIZE 0x14 -#define FW_CFG_CMDLINE_DATA 0x15 -#define FW_CFG_SETUP_ADDR 0x16 -#define FW_CFG_SETUP_SIZE 0x17 -#define FW_CFG_SETUP_DATA 0x18 -#define FW_CFG_FILE_DIR 0x19 - -#define FW_CFG_FILE_FIRST 0x20 -#define FW_CFG_FILE_SLOTS 0x10 -#define FW_CFG_MAX_ENTRY (FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS) - -#define FW_CFG_WRITE_CHANNEL 0x4000 -#define FW_CFG_ARCH_LOCAL 0x8000 -#define FW_CFG_ENTRY_MASK ~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL) - -#define FW_CFG_INVALID 0xffff - -/* width in bytes of fw_cfg control register */ -#define FW_CFG_CTL_SIZE 0x02 - -#define FW_CFG_MAX_FILE_PATH 56 - -#ifndef NO_QEMU_PROTOS typedef struct FWCfgFile { uint32_t size; /* file size */ uint16_t select; /* write this to 0x510 to read it */ @@ -221,6 +175,4 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr, FWCfgState *fw_cfg_find(void); -#endif /* NO_QEMU_PROTOS */ - #endif diff --git a/include/hw/nvram/fw_cfg_keys.h b/include/hw/nvram/fw_cfg_keys.h new file mode 100644 index 0000000000..0f3e871884 --- /dev/null +++ b/include/hw/nvram/fw_cfg_keys.h @@ -0,0 +1,46 @@ +#ifndef FW_CFG_KEYS_H +#define FW_CFG_KEYS_H + +#define FW_CFG_SIGNATURE 0x00 +#define FW_CFG_ID 0x01 +#define FW_CFG_UUID 0x02 +#define FW_CFG_RAM_SIZE 0x03 +#define FW_CFG_NOGRAPHIC 0x04 +#define FW_CFG_NB_CPUS 0x05 +#define FW_CFG_MACHINE_ID 0x06 +#define FW_CFG_KERNEL_ADDR 0x07 +#define FW_CFG_KERNEL_SIZE 0x08 +#define FW_CFG_KERNEL_CMDLINE 0x09 +#define FW_CFG_INITRD_ADDR 0x0a +#define FW_CFG_INITRD_SIZE 0x0b +#define FW_CFG_BOOT_DEVICE 0x0c +#define FW_CFG_NUMA 0x0d +#define FW_CFG_BOOT_MENU 0x0e +#define FW_CFG_MAX_CPUS 0x0f +#define FW_CFG_KERNEL_ENTRY 0x10 +#define FW_CFG_KERNEL_DATA 0x11 +#define FW_CFG_INITRD_DATA 0x12 +#define FW_CFG_CMDLINE_ADDR 0x13 +#define FW_CFG_CMDLINE_SIZE 0x14 +#define FW_CFG_CMDLINE_DATA 0x15 +#define FW_CFG_SETUP_ADDR 0x16 +#define FW_CFG_SETUP_SIZE 0x17 +#define FW_CFG_SETUP_DATA 0x18 +#define FW_CFG_FILE_DIR 0x19 + +#define FW_CFG_FILE_FIRST 0x20 +#define FW_CFG_FILE_SLOTS 0x10 +#define FW_CFG_MAX_ENTRY (FW_CFG_FILE_FIRST + FW_CFG_FILE_SLOTS) + +#define FW_CFG_WRITE_CHANNEL 0x4000 +#define FW_CFG_ARCH_LOCAL 0x8000 +#define FW_CFG_ENTRY_MASK (~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL)) + +#define FW_CFG_INVALID 0xffff + +/* width in bytes of fw_cfg control register */ +#define FW_CFG_CTL_SIZE 0x02 + +#define FW_CFG_MAX_FILE_PATH 56 + +#endif diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 0be07c8352..ef6ba51f6c 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -1,8 +1,6 @@ #ifndef QEMU_PCI_H #define QEMU_PCI_H -#include "qemu-common.h" - #include "hw/qdev.h" #include "exec/memory.h" #include "sysemu/dma.h" @@ -97,6 +95,15 @@ #define FMT_PCIBUS PRIx64 +typedef uint64_t pcibus_t; + +struct PCIHostDeviceAddress { + unsigned int domain; + unsigned int bus; + unsigned int slot; + unsigned int function; +}; + typedef void PCIConfigWriteFunc(PCIDevice *pci_dev, uint32_t address, uint32_t data, int len); typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev, diff --git a/include/hw/ppc/mac_dbdma.h b/include/hw/ppc/mac_dbdma.h index c6870212e9..0cce4e8bb4 100644 --- a/include/hw/ppc/mac_dbdma.h +++ b/include/hw/ppc/mac_dbdma.h @@ -23,6 +23,7 @@ #define HW_MAC_DBDMA_H 1 #include "exec/memory.h" +#include "qemu/iov.h" typedef struct DBDMA_io DBDMA_io; diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index c3ff99f975..1ce02b20da 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -3,7 +3,6 @@ #include "qemu/queue.h" #include "qemu/option.h" -#include "qemu/typedefs.h" #include "qemu/bitmap.h" #include "qom/object.h" #include "hw/irq.h" diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 03a1b91f31..0586cacceb 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -18,6 +18,7 @@ extern PropertyInfo qdev_prop_string; extern PropertyInfo qdev_prop_chr; extern PropertyInfo qdev_prop_ptr; extern PropertyInfo qdev_prop_macaddr; +extern PropertyInfo qdev_prop_on_off_auto; extern PropertyInfo qdev_prop_losttickpolicy; extern PropertyInfo qdev_prop_bios_chs_trans; extern PropertyInfo qdev_prop_fdc_drive_type; @@ -155,6 +156,8 @@ extern PropertyInfo qdev_prop_arraylen; DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockBackend *) #define DEFINE_PROP_MACADDR(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr) +#define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_on_off_auto, OnOffAuto) #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \ DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_losttickpolicy, \ LostTickPolicy) diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 29052f81a5..8acd3fa998 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -2,7 +2,6 @@ #define QEMU_HW_SCSI_H #include "hw/qdev.h" -#include "qemu/typedefs.h" #include "hw/block/block.h" #include "sysemu/sysemu.h" #include "qemu/notify.h" diff --git a/include/hw/timer/digic-timer.h b/include/hw/timer/digic-timer.h index ae913482c6..d9e67fe291 100644 --- a/include/hw/timer/digic-timer.h +++ b/include/hw/timer/digic-timer.h @@ -19,7 +19,6 @@ #define HW_TIMER_DIGIC_TIMER_H #include "hw/sysbus.h" -#include "qemu/typedefs.h" #include "hw/ptimer.h" #define TYPE_DIGIC_TIMER "digic-timer" diff --git a/include/hw/usb.h b/include/hw/usb.h index c8b6e7b571..163fe0490b 100644 --- a/include/hw/usb.h +++ b/include/hw/usb.h @@ -26,6 +26,7 @@ */ #include "hw/qdev.h" +#include "qemu/iov.h" #include "qemu/queue.h" /* Constants related to the USB / PCI interaction */ diff --git a/include/hw/vfio/vfio.h b/include/hw/vfio/vfio.h index 7153604cd1..f27d599220 100644 --- a/include/hw/vfio/vfio.h +++ b/include/hw/vfio/vfio.h @@ -1,8 +1,6 @@ #ifndef VFIO_API_H #define VFIO_API_H -#include "qemu/typedefs.h" - bool vfio_eeh_as_ok(AddressSpace *as); int vfio_eeh_as_op(AddressSpace *as, uint32_t op); diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h index bf3fe97927..6eb815aace 100644 --- a/include/hw/xen/xen.h +++ b/include/hw/xen/xen.h @@ -9,7 +9,6 @@ #include "hw/irq.h" #include "qemu-common.h" -#include "qemu/typedefs.h" /* xen-machine.c */ enum xen_mode { diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h index 50ec2ffc12..c4b8a05146 100644 --- a/include/monitor/qdev.h +++ b/include/monitor/qdev.h @@ -2,7 +2,6 @@ #define QEMU_QDEV_MONITOR_H #include "hw/qdev-core.h" -#include "qemu/typedefs.h" /*** monitor commands ***/ diff --git a/include/net/filter.h b/include/net/filter.h index cfb11728df..0c4a2ea6c9 100644 --- a/include/net/filter.h +++ b/include/net/filter.h @@ -11,7 +11,6 @@ #include "qom/object.h" #include "qemu-common.h" -#include "qemu/typedefs.h" #include "net/queue.h" #define TYPE_NETFILTER "netfilter" diff --git a/include/qapi/error.h b/include/qapi/error.h index 02e9dd20a7..11be2327c0 100644 --- a/include/qapi/error.h +++ b/include/qapi/error.h @@ -118,11 +118,6 @@ #include "qapi-types.h" /* - * Opaque error object. - */ -typedef struct Error Error; - -/* * Overall category of an error. * Based on the qapi type QapiErrorClass, but reproduced here for nicer * enum names. diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index 1000da2bda..9a8d0105fb 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -14,7 +14,6 @@ #ifndef QAPI_VISITOR_CORE_H #define QAPI_VISITOR_CORE_H -#include "qemu/typedefs.h" #include "qapi/qmp/qobject.h" /* This struct is layout-compatible with all other *List structs diff --git a/include/qemu-common.h b/include/qemu-common.h index 887ca71c8a..163bcbb861 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -12,7 +12,6 @@ #ifndef QEMU_COMMON_H #define QEMU_COMMON_H -#include "qemu/typedefs.h" #include "qemu/fprintf-fn.h" #if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__) || defined(__ia64__) @@ -24,15 +23,6 @@ #include "qemu/option.h" #include "qemu/host-utils.h" -/* HOST_LONG_BITS is the size of a native pointer in bits. */ -#if UINTPTR_MAX == UINT32_MAX -# define HOST_LONG_BITS 32 -#elif UINTPTR_MAX == UINT64_MAX -# define HOST_LONG_BITS 64 -#else -# error Unknown pointer size -#endif - void cpu_ticks_init(void); /* icount */ @@ -59,205 +49,6 @@ int qemu_main(int argc, char **argv, char **envp); void qemu_get_timedate(struct tm *tm, int offset); int qemu_timedate_diff(struct tm *tm); -/** - * is_help_option: - * @s: string to test - * - * Check whether @s is one of the standard strings which indicate - * that the user is asking for a list of the valid values for a - * command option like -cpu or -M. The current accepted strings - * are 'help' and '?'. '?' is deprecated (it is a shell wildcard - * which makes it annoying to use in a reliable way) but provided - * for backwards compatibility. - * - * Returns: true if @s is a request for a list. - */ -static inline bool is_help_option(const char *s) -{ - return !strcmp(s, "?") || !strcmp(s, "help"); -} - -/* util/cutils.c */ -/** - * pstrcpy: - * @buf: buffer to copy string into - * @buf_size: size of @buf in bytes - * @str: string to copy - * - * Copy @str into @buf, including the trailing NUL, but do not - * write more than @buf_size bytes. The resulting buffer is - * always NUL terminated (even if the source string was too long). - * If @buf_size is zero or negative then no bytes are copied. - * - * This function is similar to strncpy(), but avoids two of that - * function's problems: - * * if @str fits in the buffer, pstrcpy() does not zero-fill the - * remaining space at the end of @buf - * * if @str is too long, pstrcpy() will copy the first @buf_size-1 - * bytes and then add a NUL - */ -void pstrcpy(char *buf, int buf_size, const char *str); -/** - * strpadcpy: - * @buf: buffer to copy string into - * @buf_size: size of @buf in bytes - * @str: string to copy - * @pad: character to pad the remainder of @buf with - * - * Copy @str into @buf (but *not* its trailing NUL!), and then pad the - * rest of the buffer with the @pad character. If @str is too large - * for the buffer then it is truncated, so that @buf contains the - * first @buf_size characters of @str, with no terminator. - */ -void strpadcpy(char *buf, int buf_size, const char *str, char pad); -/** - * pstrcat: - * @buf: buffer containing existing string - * @buf_size: size of @buf in bytes - * @s: string to concatenate to @buf - * - * Append a copy of @s to the string already in @buf, but do not - * allow the buffer to overflow. If the existing contents of @buf - * plus @str would total more than @buf_size bytes, then write - * as much of @str as will fit followed by a NUL terminator. - * - * @buf must already contain a NUL-terminated string, or the - * behaviour is undefined. - * - * Returns: @buf. - */ -char *pstrcat(char *buf, int buf_size, const char *s); -/** - * strstart: - * @str: string to test - * @val: prefix string to look for - * @ptr: NULL, or pointer to be written to indicate start of - * the remainder of the string - * - * Test whether @str starts with the prefix @val. - * If it does (including the degenerate case where @str and @val - * are equal) then return true. If @ptr is not NULL then a - * pointer to the first character following the prefix is written - * to it. If @val is not a prefix of @str then return false (and - * @ptr is not written to). - * - * Returns: true if @str starts with prefix @val, false otherwise. - */ -int strstart(const char *str, const char *val, const char **ptr); -/** - * stristart: - * @str: string to test - * @val: prefix string to look for - * @ptr: NULL, or pointer to be written to indicate start of - * the remainder of the string - * - * Test whether @str starts with the case-insensitive prefix @val. - * This function behaves identically to strstart(), except that the - * comparison is made after calling qemu_toupper() on each pair of - * characters. - * - * Returns: true if @str starts with case-insensitive prefix @val, - * false otherwise. - */ -int stristart(const char *str, const char *val, const char **ptr); -/** - * qemu_strnlen: - * @s: string - * @max_len: maximum number of bytes in @s to scan - * - * Return the length of the string @s, like strlen(), but do not - * examine more than @max_len bytes of the memory pointed to by @s. - * If no NUL terminator is found within @max_len bytes, then return - * @max_len instead. - * - * This function has the same behaviour as the POSIX strnlen() - * function. - * - * Returns: length of @s in bytes, or @max_len, whichever is smaller. - */ -int qemu_strnlen(const char *s, int max_len); -/** - * qemu_strsep: - * @input: pointer to string to parse - * @delim: string containing delimiter characters to search for - * - * Locate the first occurrence of any character in @delim within - * the string referenced by @input, and replace it with a NUL. - * The location of the next character after the delimiter character - * is stored into @input. - * If the end of the string was reached without finding a delimiter - * character, then NULL is stored into @input. - * If @input points to a NULL pointer on entry, return NULL. - * The return value is always the original value of *@input (and - * so now points to a NUL-terminated string corresponding to the - * part of the input up to the first delimiter). - * - * This function has the same behaviour as the BSD strsep() function. - * - * Returns: the pointer originally in @input. - */ -char *qemu_strsep(char **input, const char *delim); -time_t mktimegm(struct tm *tm); -int qemu_fdatasync(int fd); -int fcntl_setfl(int fd, int flag); -int qemu_parse_fd(const char *param); -int qemu_strtol(const char *nptr, const char **endptr, int base, - long *result); -int qemu_strtoul(const char *nptr, const char **endptr, int base, - unsigned long *result); -int qemu_strtoll(const char *nptr, const char **endptr, int base, - int64_t *result); -int qemu_strtoull(const char *nptr, const char **endptr, int base, - uint64_t *result); - -int parse_uint(const char *s, unsigned long long *value, char **endptr, - int base); -int parse_uint_full(const char *s, unsigned long long *value, int base); - -/* - * qemu_strtosz() suffixes used to specify the default treatment of an - * argument passed to qemu_strtosz() without an explicit suffix. - * These should be defined using upper case characters in the range - * A-Z, as qemu_strtosz() will use qemu_toupper() on the given argument - * prior to comparison. - */ -#define QEMU_STRTOSZ_DEFSUFFIX_EB 'E' -#define QEMU_STRTOSZ_DEFSUFFIX_PB 'P' -#define QEMU_STRTOSZ_DEFSUFFIX_TB 'T' -#define QEMU_STRTOSZ_DEFSUFFIX_GB 'G' -#define QEMU_STRTOSZ_DEFSUFFIX_MB 'M' -#define QEMU_STRTOSZ_DEFSUFFIX_KB 'K' -#define QEMU_STRTOSZ_DEFSUFFIX_B 'B' -int64_t qemu_strtosz(const char *nptr, char **end); -int64_t qemu_strtosz_suffix(const char *nptr, char **end, - const char default_suffix); -int64_t qemu_strtosz_suffix_unit(const char *nptr, char **end, - const char default_suffix, int64_t unit); -#define K_BYTE (1ULL << 10) -#define M_BYTE (1ULL << 20) -#define G_BYTE (1ULL << 30) -#define T_BYTE (1ULL << 40) -#define P_BYTE (1ULL << 50) -#define E_BYTE (1ULL << 60) - -/* used to print char* safely */ -#define STR_OR_NULL(str) ((str) ? (str) : "null") - -/* id.c */ - -typedef enum IdSubSystems { - ID_QDEV, - ID_BLOCK, - ID_MAX /* last element, used as array size */ -} IdSubSystems; - -char *id_generate(IdSubSystems id); -bool id_wellformed(const char *id); - -/* path.c */ -void init_paths(const char *prefix); -const char *path(const char *pathname); - #define qemu_isalnum(c) isalnum((unsigned char)(c)) #define qemu_isalpha(c) isalpha((unsigned char)(c)) #define qemu_iscntrl(c) iscntrl((unsigned char)(c)) @@ -304,26 +95,6 @@ int qemu_openpty_raw(int *aslave, char *pty_name); sendto(sockfd, buf, len, flags, destaddr, addrlen) #endif -/* Error handling. */ - -void QEMU_NORETURN hw_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2); - -struct ParallelIOArg { - void *buffer; - int count; -}; - -typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size); - -typedef uint64_t pcibus_t; - -typedef struct PCIHostDeviceAddress { - unsigned int domain; - unsigned int bus; - unsigned int slot; - unsigned int function; -} PCIHostDeviceAddress; - void tcg_exec_init(unsigned long tb_size); bool tcg_enabled(void); @@ -365,36 +136,6 @@ ssize_t qemu_co_send_recv(int sockfd, void *buf, size_t bytes, bool do_send); #define qemu_co_send(sockfd, buf, bytes) \ qemu_co_send_recv(sockfd, buf, bytes, true) -typedef struct QEMUIOVector { - struct iovec *iov; - int niov; - int nalloc; - size_t size; -} QEMUIOVector; - -void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint); -void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov); -void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len); -void qemu_iovec_concat(QEMUIOVector *dst, - QEMUIOVector *src, size_t soffset, size_t sbytes); -size_t qemu_iovec_concat_iov(QEMUIOVector *dst, - struct iovec *src_iov, unsigned int src_cnt, - size_t soffset, size_t sbytes); -bool qemu_iovec_is_zero(QEMUIOVector *qiov); -void qemu_iovec_destroy(QEMUIOVector *qiov); -void qemu_iovec_reset(QEMUIOVector *qiov); -size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset, - void *buf, size_t bytes); -size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset, - const void *buf, size_t bytes); -size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset, - int fillc, size_t bytes); -ssize_t qemu_iovec_compare(QEMUIOVector *a, QEMUIOVector *b); -void qemu_iovec_clone(QEMUIOVector *dest, const QEMUIOVector *src, void *buf); -void qemu_iovec_discard_back(QEMUIOVector *qiov, size_t bytes); - -bool buffer_is_zero(const void *buf, size_t len); - void qemu_progress_init(int enabled, float min_skip); void qemu_progress_end(void); void qemu_progress_print(float delta, int max); @@ -409,76 +150,14 @@ void os_setup_early_signal_handling(void); char *os_find_datadir(void); void os_parse_cmd_args(int index, const char *optarg); -/* Convert a byte between binary and BCD. */ -static inline uint8_t to_bcd(uint8_t val) -{ - return ((val / 10) << 4) | (val % 10); -} - -static inline uint8_t from_bcd(uint8_t val) -{ - return ((val >> 4) * 10) + (val & 0x0f); -} - -/* Round number down to multiple */ -#define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m)) - -/* Round number up to multiple */ -#define QEMU_ALIGN_UP(n, m) QEMU_ALIGN_DOWN((n) + (m) - 1, (m)) - #include "qemu/module.h" /* - * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128) - * Input is limited to 14-bit numbers - */ - -int uleb128_encode_small(uint8_t *out, uint32_t n); -int uleb128_decode_small(const uint8_t *in, uint32_t *n); - -/* unicode.c */ -int mod_utf8_codepoint(const char *s, size_t n, char **end); - -/* * Hexdump a buffer to a file. An optional string prefix is added to every line */ void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size); -/* vector definitions */ -#ifdef __ALTIVEC__ -#include <altivec.h> -/* The altivec.h header says we're allowed to undef these for - * C++ compatibility. Here we don't care about C++, but we - * undef them anyway to avoid namespace pollution. - */ -#undef vector -#undef pixel -#undef bool -#define VECTYPE __vector unsigned char -#define SPLAT(p) vec_splat(vec_ld(0, p), 0) -#define ALL_EQ(v1, v2) vec_all_eq(v1, v2) -#define VEC_OR(v1, v2) ((v1) | (v2)) -/* altivec.h may redefine the bool macro as vector type. - * Reset it to POSIX semantics. */ -#define bool _Bool -#elif defined __SSE2__ -#include <emmintrin.h> -#define VECTYPE __m128i -#define SPLAT(p) _mm_set1_epi8(*(p)) -#define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0xFFFF) -#define VEC_OR(v1, v2) (_mm_or_si128(v1, v2)) -#else -#define VECTYPE unsigned long -#define SPLAT(p) (*(p) * (~0UL / 255)) -#define ALL_EQ(v1, v2) ((v1) == (v2)) -#define VEC_OR(v1, v2) ((v1) | (v2)) -#endif - -#define BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR 8 -bool can_use_buffer_find_nonzero_offset(const void *buf, size_t len); -size_t buffer_find_nonzero_offset(const void *buf, size_t len); - /* * helper to parse debug environment variables */ diff --git a/include/qemu/bcd.h b/include/qemu/bcd.h new file mode 100644 index 0000000000..b4c9b64b8f --- /dev/null +++ b/include/qemu/bcd.h @@ -0,0 +1,15 @@ +#ifndef QEMU_BCD_H +#define QEMU_BCD_H 1 + +/* Convert a byte between binary and BCD. */ +static inline uint8_t to_bcd(uint8_t val) +{ + return ((val / 10) << 4) | (val % 10); +} + +static inline uint8_t from_bcd(uint8_t val) +{ + return ((val >> 4) * 10) + (val & 0x0f); +} + +#endif diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h index 95071ba9e8..fcedf0d249 100644 --- a/include/qemu/bswap.h +++ b/include/qemu/bswap.h @@ -419,11 +419,9 @@ static inline void stfq_be_p(void *ptr, float64 v) static inline unsigned long leul_to_cpu(unsigned long v) { - /* In order to break an include loop between here and - qemu-common.h, don't rely on HOST_LONG_BITS. */ -#if ULONG_MAX == UINT32_MAX +#if HOST_LONG_BITS == 32 return le_bswap(v, 32); -#elif ULONG_MAX == UINT64_MAX +#elif HOST_LONG_BITS == 64 return le_bswap(v, 64); #else # error Unknown sizeof long diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index 99b939846b..305fe76c29 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -15,7 +15,6 @@ #ifndef QEMU_COROUTINE_H #define QEMU_COROUTINE_H -#include "qemu/typedefs.h" #include "qemu/queue.h" #include "qemu/timer.h" diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h new file mode 100644 index 0000000000..db7adadcf9 --- /dev/null +++ b/include/qemu/cutils.h @@ -0,0 +1,183 @@ +#ifndef QEMU_CUTILS_H +#define QEMU_CUTILS_H 1 + +#include "qemu/fprintf-fn.h" + +/** + * pstrcpy: + * @buf: buffer to copy string into + * @buf_size: size of @buf in bytes + * @str: string to copy + * + * Copy @str into @buf, including the trailing NUL, but do not + * write more than @buf_size bytes. The resulting buffer is + * always NUL terminated (even if the source string was too long). + * If @buf_size is zero or negative then no bytes are copied. + * + * This function is similar to strncpy(), but avoids two of that + * function's problems: + * * if @str fits in the buffer, pstrcpy() does not zero-fill the + * remaining space at the end of @buf + * * if @str is too long, pstrcpy() will copy the first @buf_size-1 + * bytes and then add a NUL + */ +void pstrcpy(char *buf, int buf_size, const char *str); +/** + * strpadcpy: + * @buf: buffer to copy string into + * @buf_size: size of @buf in bytes + * @str: string to copy + * @pad: character to pad the remainder of @buf with + * + * Copy @str into @buf (but *not* its trailing NUL!), and then pad the + * rest of the buffer with the @pad character. If @str is too large + * for the buffer then it is truncated, so that @buf contains the + * first @buf_size characters of @str, with no terminator. + */ +void strpadcpy(char *buf, int buf_size, const char *str, char pad); +/** + * pstrcat: + * @buf: buffer containing existing string + * @buf_size: size of @buf in bytes + * @s: string to concatenate to @buf + * + * Append a copy of @s to the string already in @buf, but do not + * allow the buffer to overflow. If the existing contents of @buf + * plus @str would total more than @buf_size bytes, then write + * as much of @str as will fit followed by a NUL terminator. + * + * @buf must already contain a NUL-terminated string, or the + * behaviour is undefined. + * + * Returns: @buf. + */ +char *pstrcat(char *buf, int buf_size, const char *s); +/** + * strstart: + * @str: string to test + * @val: prefix string to look for + * @ptr: NULL, or pointer to be written to indicate start of + * the remainder of the string + * + * Test whether @str starts with the prefix @val. + * If it does (including the degenerate case where @str and @val + * are equal) then return true. If @ptr is not NULL then a + * pointer to the first character following the prefix is written + * to it. If @val is not a prefix of @str then return false (and + * @ptr is not written to). + * + * Returns: true if @str starts with prefix @val, false otherwise. + */ +int strstart(const char *str, const char *val, const char **ptr); +/** + * stristart: + * @str: string to test + * @val: prefix string to look for + * @ptr: NULL, or pointer to be written to indicate start of + * the remainder of the string + * + * Test whether @str starts with the case-insensitive prefix @val. + * This function behaves identically to strstart(), except that the + * comparison is made after calling qemu_toupper() on each pair of + * characters. + * + * Returns: true if @str starts with case-insensitive prefix @val, + * false otherwise. + */ +int stristart(const char *str, const char *val, const char **ptr); +/** + * qemu_strnlen: + * @s: string + * @max_len: maximum number of bytes in @s to scan + * + * Return the length of the string @s, like strlen(), but do not + * examine more than @max_len bytes of the memory pointed to by @s. + * If no NUL terminator is found within @max_len bytes, then return + * @max_len instead. + * + * This function has the same behaviour as the POSIX strnlen() + * function. + * + * Returns: length of @s in bytes, or @max_len, whichever is smaller. + */ +int qemu_strnlen(const char *s, int max_len); +/** + * qemu_strsep: + * @input: pointer to string to parse + * @delim: string containing delimiter characters to search for + * + * Locate the first occurrence of any character in @delim within + * the string referenced by @input, and replace it with a NUL. + * The location of the next character after the delimiter character + * is stored into @input. + * If the end of the string was reached without finding a delimiter + * character, then NULL is stored into @input. + * If @input points to a NULL pointer on entry, return NULL. + * The return value is always the original value of *@input (and + * so now points to a NUL-terminated string corresponding to the + * part of the input up to the first delimiter). + * + * This function has the same behaviour as the BSD strsep() function. + * + * Returns: the pointer originally in @input. + */ +char *qemu_strsep(char **input, const char *delim); +time_t mktimegm(struct tm *tm); +int qemu_fdatasync(int fd); +int fcntl_setfl(int fd, int flag); +int qemu_parse_fd(const char *param); +int qemu_strtol(const char *nptr, const char **endptr, int base, + long *result); +int qemu_strtoul(const char *nptr, const char **endptr, int base, + unsigned long *result); +int qemu_strtoll(const char *nptr, const char **endptr, int base, + int64_t *result); +int qemu_strtoull(const char *nptr, const char **endptr, int base, + uint64_t *result); + +int parse_uint(const char *s, unsigned long long *value, char **endptr, + int base); +int parse_uint_full(const char *s, unsigned long long *value, int base); + +/* + * qemu_strtosz() suffixes used to specify the default treatment of an + * argument passed to qemu_strtosz() without an explicit suffix. + * These should be defined using upper case characters in the range + * A-Z, as qemu_strtosz() will use qemu_toupper() on the given argument + * prior to comparison. + */ +#define QEMU_STRTOSZ_DEFSUFFIX_EB 'E' +#define QEMU_STRTOSZ_DEFSUFFIX_PB 'P' +#define QEMU_STRTOSZ_DEFSUFFIX_TB 'T' +#define QEMU_STRTOSZ_DEFSUFFIX_GB 'G' +#define QEMU_STRTOSZ_DEFSUFFIX_MB 'M' +#define QEMU_STRTOSZ_DEFSUFFIX_KB 'K' +#define QEMU_STRTOSZ_DEFSUFFIX_B 'B' +int64_t qemu_strtosz(const char *nptr, char **end); +int64_t qemu_strtosz_suffix(const char *nptr, char **end, + const char default_suffix); +int64_t qemu_strtosz_suffix_unit(const char *nptr, char **end, + const char default_suffix, int64_t unit); +#define K_BYTE (1ULL << 10) +#define M_BYTE (1ULL << 20) +#define G_BYTE (1ULL << 30) +#define T_BYTE (1ULL << 40) +#define P_BYTE (1ULL << 50) +#define E_BYTE (1ULL << 60) + +/* used to print char* safely */ +#define STR_OR_NULL(str) ((str) ? (str) : "null") + +bool can_use_buffer_find_nonzero_offset(const void *buf, size_t len); +size_t buffer_find_nonzero_offset(const void *buf, size_t len); +bool buffer_is_zero(const void *buf, size_t len); + +/* + * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128) + * Input is limited to 14-bit numbers + */ + +int uleb128_encode_small(uint8_t *out, uint32_t n); +int uleb128_decode_small(const uint8_t *in, uint32_t *n); + +#endif diff --git a/include/qemu/help_option.h b/include/qemu/help_option.h new file mode 100644 index 0000000000..e39a66e77b --- /dev/null +++ b/include/qemu/help_option.h @@ -0,0 +1,22 @@ +#ifndef QEMU_HELP_OPTION_H +#define QEMU_HELP_OPTION_H 1 + +/** + * is_help_option: + * @s: string to test + * + * Check whether @s is one of the standard strings which indicate + * that the user is asking for a list of the valid values for a + * command option like -cpu or -M. The current accepted strings + * are 'help' and '?'. '?' is deprecated (it is a shell wildcard + * which makes it annoying to use in a reliable way) but provided + * for backwards compatibility. + * + * Returns: true if @s is a request for a list. + */ +static inline bool is_help_option(const char *s) +{ + return !strcmp(s, "?") || !strcmp(s, "help"); +} + +#endif diff --git a/include/qemu/id.h b/include/qemu/id.h new file mode 100644 index 0000000000..7d90335afb --- /dev/null +++ b/include/qemu/id.h @@ -0,0 +1,13 @@ +#ifndef QEMU_ID_H +#define QEMU_ID_H 1 + +typedef enum IdSubSystems { + ID_QDEV, + ID_BLOCK, + ID_MAX /* last element, used as array size */ +} IdSubSystems; + +char *id_generate(IdSubSystems id); +bool id_wellformed(const char *id); + +#endif diff --git a/include/qemu/iov.h b/include/qemu/iov.h index 28475516eb..bd9fd55b0a 100644 --- a/include/qemu/iov.h +++ b/include/qemu/iov.h @@ -14,8 +14,6 @@ #ifndef IOV_H #define IOV_H -#include "qemu-common.h" - /** * count and return data size, in bytes, of an iovec * starting at `iov' of `iov_cnt' number of elements. @@ -138,4 +136,32 @@ size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt, size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt, size_t bytes); +typedef struct QEMUIOVector { + struct iovec *iov; + int niov; + int nalloc; + size_t size; +} QEMUIOVector; + +void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint); +void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov); +void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len); +void qemu_iovec_concat(QEMUIOVector *dst, + QEMUIOVector *src, size_t soffset, size_t sbytes); +size_t qemu_iovec_concat_iov(QEMUIOVector *dst, + struct iovec *src_iov, unsigned int src_cnt, + size_t soffset, size_t sbytes); +bool qemu_iovec_is_zero(QEMUIOVector *qiov); +void qemu_iovec_destroy(QEMUIOVector *qiov); +void qemu_iovec_reset(QEMUIOVector *qiov); +size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset, + void *buf, size_t bytes); +size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset, + const void *buf, size_t bytes); +size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset, + int fillc, size_t bytes); +ssize_t qemu_iovec_compare(QEMUIOVector *a, QEMUIOVector *b); +void qemu_iovec_clone(QEMUIOVector *dest, const QEMUIOVector *src, void *buf); +void qemu_iovec_discard_back(QEMUIOVector *qiov, size_t bytes); + #endif diff --git a/include/qemu/log.h b/include/qemu/log.h index 40c24fda40..cf38adbdb0 100644 --- a/include/qemu/log.h +++ b/include/qemu/log.h @@ -66,10 +66,32 @@ qemu_log_vprintf(const char *fmt, va_list va) } } -/* log only if a bit is set on the current loglevel mask +/* log only if a bit is set on the current loglevel mask: + * @mask: bit to check in the mask + * @fmt: printf-style format string + * @args: optional arguments for format string */ -void GCC_FMT_ATTR(2, 3) qemu_log_mask(int mask, const char *fmt, ...); +#define qemu_log_mask(MASK, FMT, ...) \ + do { \ + if (unlikely(qemu_loglevel_mask(MASK))) { \ + qemu_log(FMT, ## __VA_ARGS__); \ + } \ + } while (0) +/* log only if a bit is set on the current loglevel mask + * and we are in the address range we care about: + * @mask: bit to check in the mask + * @addr: address to check in dfilter + * @fmt: printf-style format string + * @args: optional arguments for format string + */ +#define qemu_log_mask_and_addr(MASK, ADDR, FMT, ...) \ + do { \ + if (unlikely(qemu_loglevel_mask(MASK)) && \ + qemu_log_in_addr_range(ADDR)) { \ + qemu_log(FMT, ## __VA_ARGS__); \ + } \ + } while (0) /* Maintenance: */ @@ -115,6 +137,8 @@ static inline void qemu_set_log(int log_flags) } void qemu_set_log_filename(const char *filename); +void qemu_set_dfilter_ranges(const char *ranges); +bool qemu_log_in_addr_range(uint64_t addr); int qemu_str_to_log_mask(const char *str); /* Print a usage message listing all the valid logging categories diff --git a/include/qemu/option.h b/include/qemu/option.h index 8809ce1e75..8542d2dfd6 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -28,7 +28,6 @@ #include "qemu/queue.h" #include "qapi/qmp/qdict.h" -#include "qemu/typedefs.h" const char *get_opt_name(char *buf, int buf_size, const char *p, char delim); const char *get_opt_value(char *buf, int buf_size, const char *p); diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 4538fdca42..408783f532 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -7,8 +7,10 @@ * * To avoid getting into possible circular include dependencies, this * file should not include any other QEMU headers, with the exceptions - * of config-host.h, compiler.h, os-posix.h and os-win32.h, all of which - * are doing a similar job to this file and are under similar constraints. + * of config-host.h, config-target.h, qemu/compiler.h, + * sysemu/os-posix.h, sysemu/os-win32.h, glib-compat.h and + * qemu/typedefs.h, all of which are doing a similar job to this file + * and are under similar constraints. * * This header also contains prototypes for functions defined in * os-*.c and util/oslib-*.c; those would probably be better split @@ -76,6 +78,9 @@ extern int daemon(int, int); #include <sys/stat.h> #include <sys/time.h> #include <assert.h> +/* setjmp must be declared before sysemu/os-win32.h + * because it is redefined there. */ +#include <setjmp.h> #include <signal.h> #ifdef __OpenBSD__ @@ -98,8 +103,7 @@ extern int daemon(int, int); #endif #include "glib-compat.h" - -#include "qapi/error.h" +#include "qemu/typedefs.h" #ifndef O_LARGEFILE #define O_LARGEFILE 0 @@ -126,6 +130,15 @@ extern int daemon(int, int); #define TIME_MAX LONG_MAX #endif +/* HOST_LONG_BITS is the size of a native pointer in bits. */ +#if UINTPTR_MAX == UINT32_MAX +# define HOST_LONG_BITS 32 +#elif UINTPTR_MAX == UINT64_MAX +# define HOST_LONG_BITS 64 +#else +# error Unknown pointer size +#endif + #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif @@ -139,6 +152,12 @@ extern int daemon(int, int); #define MIN_NON_ZERO(a, b) (((a) != 0 && (a) < (b)) ? (a) : (b)) #endif +/* Round number down to multiple */ +#define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m)) + +/* Round number up to multiple */ +#define QEMU_ALIGN_UP(n, m) QEMU_ALIGN_DOWN((n) + (m) - 1, (m)) + #ifndef ROUND_UP #define ROUND_UP(n,d) (((n) + (d) - 1) & -(d)) #endif diff --git a/include/qemu/path.h b/include/qemu/path.h new file mode 100644 index 0000000000..ed5fee086f --- /dev/null +++ b/include/qemu/path.h @@ -0,0 +1,7 @@ +#ifndef QEMU_PATH_H +#define QEMU_PATH_H 1 + +void init_paths(const char *prefix); +const char *path(const char *pathname); + +#endif diff --git a/include/qemu/range.h b/include/qemu/range.h index 9fc547b9cb..c903eb574a 100644 --- a/include/qemu/range.h +++ b/include/qemu/range.h @@ -1,7 +1,6 @@ #ifndef QEMU_RANGE_H #define QEMU_RANGE_H -#include <qemu/typedefs.h> #include "qemu/queue.h" /* diff --git a/include/qemu/timer.h b/include/qemu/timer.h index 7197d0859a..471969a24d 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -1,7 +1,6 @@ #ifndef QEMU_TIMER_H #define QEMU_TIMER_H -#include "qemu/typedefs.h" #include "qemu-common.h" #include "qemu/notify.h" #include "qemu/host-utils.h" @@ -784,18 +783,13 @@ void cpu_enable_ticks(void); /* Caller must hold BQL */ void cpu_disable_ticks(void); -static inline int64_t get_ticks_per_sec(void) -{ - return 1000000000LL; -} - static inline int64_t get_max_clock_jump(void) { /* This should be small enough to prevent excessive interrupts from being * generated by the RTC on clock jumps, but large enough to avoid frequent * unnecessary resets in idle VMs. */ - return 60 * get_ticks_per_sec(); + return 60 * NANOSECONDS_PER_SECOND; } /* @@ -821,7 +815,7 @@ static inline int64_t get_clock(void) { LARGE_INTEGER ti; QueryPerformanceCounter(&ti); - return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq); + return muldiv64(ti.QuadPart, NANOSECONDS_PER_SECOND, clock_freq); } #else diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index fd039e0e81..1dcf6f5d53 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -26,6 +26,7 @@ typedef struct DisplayChangeListener DisplayChangeListener; typedef struct DisplayState DisplayState; typedef struct DisplaySurface DisplaySurface; typedef struct DriveInfo DriveInfo; +typedef struct Error Error; typedef struct EventNotifier EventNotifier; typedef struct FWCfgIoState FWCfgIoState; typedef struct FWCfgMemState FWCfgMemState; @@ -65,6 +66,7 @@ typedef struct PCIEPort PCIEPort; typedef struct PCIESlot PCIESlot; typedef struct PCIExpressDevice PCIExpressDevice; typedef struct PCIExpressHost PCIExpressHost; +typedef struct PCIHostDeviceAddress PCIHostDeviceAddress; typedef struct PCIHostState PCIHostState; typedef struct PCMachineClass PCMachineClass; typedef struct PCMachineState PCMachineState; diff --git a/include/qemu/unicode.h b/include/qemu/unicode.h new file mode 100644 index 0000000000..d8731652d2 --- /dev/null +++ b/include/qemu/unicode.h @@ -0,0 +1,6 @@ +#ifndef QEMU_UNICODE_H +#define QEMU_UNICODE_H 1 + +int mod_utf8_codepoint(const char *s, size_t n, char **end); + +#endif diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 7052eee7b7..b7a10f791a 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -20,14 +20,12 @@ #ifndef QEMU_CPU_H #define QEMU_CPU_H -#include <setjmp.h> #include "hw/qdev-core.h" #include "disas/bfd.h" #include "exec/hwaddr.h" #include "exec/memattrs.h" #include "qemu/queue.h" #include "qemu/thread.h" -#include "qemu/typedefs.h" typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size, void *opaque); diff --git a/include/qom/object.h b/include/qom/object.h index eda16df005..21bb5ff149 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -15,8 +15,8 @@ #define QEMU_OBJECT_H #include <glib.h> +#include "qapi-types.h" #include "qemu/queue.h" -#include "qemu/typedefs.h" struct TypeImpl; typedef struct TypeImpl *Type; diff --git a/include/sysemu/accel.h b/include/sysemu/accel.h index 997720f36c..a74b2faf5f 100644 --- a/include/sysemu/accel.h +++ b/include/sysemu/accel.h @@ -23,7 +23,6 @@ #ifndef HW_ACCEL_H #define HW_ACCEL_H -#include "qemu/typedefs.h" #include "qom/object.h" typedef struct AccelState { diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index d839bffeb0..c62b6fe96d 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -13,7 +13,7 @@ #ifndef BLOCK_BACKEND_H #define BLOCK_BACKEND_H -#include "qemu/typedefs.h" +#include "qemu/iov.h" /* * TODO Have to include block/block.h for a bunch of block layer diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 4c2f777ad1..307fd8fde4 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -41,6 +41,11 @@ typedef struct { #define CHR_IOCTL_PP_EPP_WRITE 11 #define CHR_IOCTL_PP_DATA_DIR 12 +struct ParallelIOArg { + void *buffer; + int count; +}; + #define CHR_IOCTL_SERIAL_SET_TIOCM 13 #define CHR_IOCTL_SERIAL_GET_TIOCM 14 diff --git a/include/sysemu/memory_mapping.h b/include/sysemu/memory_mapping.h index d46d879b94..706152d533 100644 --- a/include/sysemu/memory_mapping.h +++ b/include/sysemu/memory_mapping.h @@ -15,7 +15,6 @@ #define MEMORY_MAPPING_H #include "qemu/queue.h" -#include "qemu/typedefs.h" #include "exec/memory.h" typedef struct GuestPhysBlock { diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index e7989199fc..5854adc4e6 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -13,7 +13,6 @@ */ #include "qapi-types.h" -#include "qemu/typedefs.h" /* replay clock kinds */ enum ReplayClockKind { diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 3bb8897727..38fb3cad35 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -2,7 +2,6 @@ #define SYSEMU_H /* Misc. things related to the system emulator. */ -#include "qemu/typedefs.h" #include "qemu/option.h" #include "qemu/queue.h" #include "qemu/timer.h" diff --git a/include/ui/console.h b/include/ui/console.h index f63697182f..eb9419dfd6 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -5,7 +5,6 @@ #include "qom/object.h" #include "qapi/qmp/qdict.h" #include "qemu/notify.h" -#include "qemu/typedefs.h" #include "qapi-types.h" #ifdef CONFIG_OPENGL diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h index e34c4effcb..4a67e01232 100644 --- a/include/ui/qemu-pixman.h +++ b/include/ui/qemu-pixman.h @@ -16,8 +16,6 @@ #pragma GCC diagnostic pop #endif -#include "qemu/typedefs.h" - /* * pixman image formats are defined to be native endian, * that means host byte order on qemu. So we go define diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h index 2dabe49f41..aa2436355f 100644 --- a/include/ui/qemu-spice.h +++ b/include/ui/qemu-spice.h @@ -18,11 +18,11 @@ #ifndef QEMU_SPICE_H #define QEMU_SPICE_H +#include "qapi/error.h" #ifdef CONFIG_SPICE #include <spice.h> - #include "qemu/option.h" #include "qemu/config-file.h" diff --git a/io/channel-command.c b/io/channel-command.c index 604514adfc..ad25313be1 100644 --- a/io/channel-command.c +++ b/io/channel-command.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "io/channel-command.h" #include "io/channel-watch.h" +#include "qapi/error.h" #include "qemu/sockets.h" #include "trace.h" diff --git a/io/channel-file.c b/io/channel-file.c index f28e2b0a5c..e1da2435e6 100644 --- a/io/channel-file.c +++ b/io/channel-file.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "io/channel-file.h" #include "io/channel-watch.h" +#include "qapi/error.h" #include "qemu/sockets.h" #include "trace.h" diff --git a/io/channel-socket.c b/io/channel-socket.c index d005070584..ca8bc20b17 100644 --- a/io/channel-socket.c +++ b/io/channel-socket.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "io/channel-socket.h" #include "io/channel-watch.h" #include "trace.h" diff --git a/io/channel-tls.c b/io/channel-tls.c index 7608fd9de0..9a8525c816 100644 --- a/io/channel-tls.c +++ b/io/channel-tls.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "io/channel-tls.h" #include "trace.h" diff --git a/io/channel-websock.c b/io/channel-websock.c index 35860a2738..708178779e 100644 --- a/io/channel-websock.c +++ b/io/channel-websock.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "io/channel-websock.h" #include "crypto/hash.h" #include "trace.h" diff --git a/io/channel.c b/io/channel.c index dd6fc0eb28..692eb179b3 100644 --- a/io/channel.c +++ b/io/channel.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "io/channel.h" +#include "qapi/error.h" #include "qemu/coroutine.h" bool qio_channel_has_feature(QIOChannel *ioc, @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "io/task.h" +#include "qapi/error.h" #include "qemu/thread.h" #include "trace.h" diff --git a/iohandler.c b/iohandler.c index 0abb4a7e7a..3f23433b5a 100644 --- a/iohandler.c +++ b/iohandler.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/queue.h" #include "block/aio.h" diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 19dc7f5457..e47caff7ae 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -7,6 +7,7 @@ #include "qemu.h" #include "disas/disas.h" +#include "qemu/path.h" #ifdef _ARCH_PPC64 #undef ARCH_DLINFO diff --git a/linux-user/main.c b/linux-user/main.c index 2b1e7552da..b432bf2b1e 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -22,7 +22,9 @@ #include <sys/resource.h> #include "qemu.h" -#include "qemu-common.h" +#include "qemu/path.h" +#include "qemu/cutils.h" +#include "qemu/help_option.h" #include "cpu.h" #include "tcg.h" #include "qemu/timer.h" diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 951753143c..032d338869 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -18,6 +18,8 @@ */ #define _ATFILE_SOURCE #include "qemu/osdep.h" +#include "qemu/cutils.h" +#include "qemu/path.h" #include <elf.h> #include <endian.h> #include <grp.h> diff --git a/linux-user/uaccess.c b/linux-user/uaccess.c index 75d890dfef..0a5c0b0b29 100644 --- a/linux-user/uaccess.c +++ b/linux-user/uaccess.c @@ -1,5 +1,6 @@ /* User memory access */ #include "qemu/osdep.h" +#include "qemu/cutils.h" #include "qemu.h" diff --git a/main-loop.c b/main-loop.c index 3a7f4cdbb2..89a699419f 100644 --- a/main-loop.c +++ b/main-loop.c @@ -23,7 +23,8 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qapi/error.h" +#include "qemu/cutils.h" #include "qemu/timer.h" #include "qemu/sockets.h" // struct in_addr needed for libslirp.h #include "sysemu/qtest.h" @@ -14,6 +14,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "exec/memory.h" #include "exec/address-spaces.h" #include "exec/ioport.h" diff --git a/memory_mapping.c b/memory_mapping.c index c8855de92b..2354b2b7f3 100644 --- a/memory_mapping.c +++ b/memory_mapping.c @@ -12,6 +12,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include <glib.h> #include "qemu-common.h" diff --git a/migration/block.c b/migration/block.c index 72883d7c64..1743317288 100644 --- a/migration/block.c +++ b/migration/block.c @@ -14,11 +14,13 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "block/block.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "hw/hw.h" +#include "qemu/cutils.h" #include "qemu/queue.h" #include "qemu/timer.h" #include "migration/block.h" diff --git a/migration/exec.c b/migration/exec.c index 62f892d4d9..559420969b 100644 --- a/migration/exec.c +++ b/migration/exec.c @@ -16,6 +16,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/sockets.h" #include "qemu/main-loop.h" diff --git a/migration/fd.c b/migration/fd.c index 085dd7c51e..3d788bb297 100644 --- a/migration/fd.c +++ b/migration/fd.c @@ -14,6 +14,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/main-loop.h" #include "qemu/sockets.h" diff --git a/migration/migration.c b/migration/migration.c index 034a918d32..991313a862 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -14,7 +14,7 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qemu/cutils.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "migration/migration.h" diff --git a/migration/ram.c b/migration/ram.c index 704f6a95bf..3f057388cb 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -28,6 +28,7 @@ #include "qemu/osdep.h" #include <zlib.h> #include "qapi-event.h" +#include "qemu/cutils.h" #include "qemu/bitops.h" #include "qemu/bitmap.h" #include "qemu/timer.h" diff --git a/migration/rdma.c b/migration/rdma.c index bcae1e81b3..f6a9992b3e 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -12,7 +12,9 @@ * */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" +#include "qemu/cutils.h" #include "migration/migration.h" #include "migration/qemu-file.h" #include "exec/cpu-common.h" diff --git a/migration/savevm.c b/migration/savevm.c index 0a33c227c5..16ba443798 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -27,7 +27,6 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" #include "hw/boards.h" #include "hw/hw.h" #include "hw/qdev.h" @@ -50,7 +49,7 @@ #include "qemu/iov.h" #include "block/snapshot.h" #include "block/qapi.h" - +#include "qemu/cutils.h" #ifndef ETH_P_RARP #define ETH_P_RARP 0x8035 diff --git a/migration/xbzrle.c b/migration/xbzrle.c index 4db3f6c5cc..c858339259 100644 --- a/migration/xbzrle.c +++ b/migration/xbzrle.c @@ -11,7 +11,7 @@ * */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qemu/cutils.h" #include "include/migration/migration.h" /* @@ -78,6 +78,7 @@ #include "qmp-introspect.h" #include "sysemu/block-backend.h" #include "sysemu/qtest.h" +#include "qemu/cutils.h" /* for hmp_info_irq/pic */ #if defined(TARGET_SPARC) @@ -1523,9 +1524,9 @@ int64_t dev_time; static void hmp_info_profile(Monitor *mon, const QDict *qdict) { monitor_printf(mon, "async time %" PRId64 " (%0.3f)\n", - dev_time, dev_time / (double)get_ticks_per_sec()); + dev_time, dev_time / (double)NANOSECONDS_PER_SECOND); monitor_printf(mon, "qemu time %" PRId64 " (%0.3f)\n", - tcg_time, tcg_time / (double)get_ticks_per_sec()); + tcg_time, tcg_time / (double)NANOSECONDS_PER_SECOND); tcg_time = 0; dev_time = 0; } diff --git a/nbd/client.c b/nbd/client.c index 9e5b651082..f89c0a16ae 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -17,6 +17,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "nbd-internal.h" static int nbd_errno_to_system_errno(int err) diff --git a/nbd/common.c b/nbd/common.c index bde673a04a..a44718ce58 100644 --- a/nbd/common.c +++ b/nbd/common.c @@ -17,6 +17,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "nbd-internal.h" ssize_t nbd_wr_syncv(QIOChannel *ioc, diff --git a/nbd/server.c b/nbd/server.c index d4225cdb55..b95571bdf5 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -17,6 +17,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "nbd-internal.h" static int system_errno_to_nbd_errno(int err) diff --git a/net/dump.c b/net/dump.c index 94ac32a39f..41f7673efd 100644 --- a/net/dump.c +++ b/net/dump.c @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "clients.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/error-report.h" #include "qemu/iov.h" diff --git a/net/filter-buffer.c b/net/filter-buffer.c index 972177b453..cc6bd94445 100644 --- a/net/filter-buffer.c +++ b/net/filter-buffer.c @@ -9,6 +9,7 @@ #include "qemu/osdep.h" #include "net/filter.h" #include "net/queue.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/timer.h" #include "qemu/iov.h" diff --git a/net/filter.c b/net/filter.c index a08ef68ae6..1c4fc5a2c7 100644 --- a/net/filter.c +++ b/net/filter.c @@ -7,6 +7,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qapi/qmp/qerror.h" #include "qemu/error-report.h" @@ -32,9 +32,11 @@ #include "monitor/monitor.h" #include "qemu-common.h" +#include "qemu/help_option.h" #include "qapi/qmp/qerror.h" #include "qemu/error-report.h" #include "qemu/sockets.h" +#include "qemu/cutils.h" #include "qemu/config-file.h" #include "qmp-commands.h" #include "hw/qdev.h" diff --git a/net/netmap.c b/net/netmap.c index 6fa2c418a5..d9c21b2b86 100644 --- a/net/netmap.c +++ b/net/netmap.c @@ -37,6 +37,7 @@ #include "sysemu/sysemu.h" #include "qemu/error-report.h" #include "qemu/iov.h" +#include "qemu/cutils.h" typedef struct NetmapState { NetClientState nc; diff --git a/net/slirp.c b/net/slirp.c index 0013c27fe6..791a8f7b89 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -38,6 +38,7 @@ #include "slirp/libslirp.h" #include "slirp/ip6.h" #include "sysemu/char.h" +#include "qemu/cutils.h" static int get_str_sep(char *buf, int buf_size, const char **pp, int sep) { diff --git a/net/socket.c b/net/socket.c index 9826efb46f..9fa2cd8d51 100644 --- a/net/socket.c +++ b/net/socket.c @@ -26,6 +26,7 @@ #include "net/net.h" #include "clients.h" #include "monitor/monitor.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/error-report.h" #include "qemu/option.h" diff --git a/net/tap-aix.c b/net/tap-aix.c index 9d830b7a32..0e6da63963 100644 --- a/net/tap-aix.c +++ b/net/tap-aix.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "tap_int.h" int tap_open(char *ifname, int ifname_size, int *vnet_hdr, diff --git a/net/tap-bsd.c b/net/tap-bsd.c index 83de19a646..c506ac31d6 100644 --- a/net/tap-bsd.c +++ b/net/tap-bsd.c @@ -23,8 +23,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "tap_int.h" -#include "qemu-common.h" +#include "qemu/cutils.h" #include "sysemu/sysemu.h" #include "qemu/error-report.h" diff --git a/net/tap-haiku.c b/net/tap-haiku.c index 397e53235e..b27e57e955 100644 --- a/net/tap-haiku.c +++ b/net/tap-haiku.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "tap_int.h" int tap_open(char *ifname, int ifname_size, int *vnet_hdr, diff --git a/net/tap-linux.c b/net/tap-linux.c index 0929cf76f5..a503fa9c6e 100644 --- a/net/tap-linux.c +++ b/net/tap-linux.c @@ -32,8 +32,9 @@ #include <sys/ioctl.h> #include "sysemu/sysemu.h" -#include "qemu-common.h" +#include "qapi/error.h" #include "qemu/error-report.h" +#include "qemu/cutils.h" #define PATH_NET_TUN "/dev/net/tun" diff --git a/net/tap-solaris.c b/net/tap-solaris.c index e3907a8218..a2a92356c1 100644 --- a/net/tap-solaris.c +++ b/net/tap-solaris.c @@ -23,8 +23,10 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "tap_int.h" #include "sysemu/sysemu.h" +#include "qemu/cutils.h" #include <sys/ethernet.h> #include <sys/sockio.h> @@ -36,7 +36,9 @@ #include "clients.h" #include "monitor/monitor.h" #include "sysemu/sysemu.h" +#include "qapi/error.h" #include "qemu-common.h" +#include "qemu/cutils.h" #include "qemu/error-report.h" #include "net/tap.h" diff --git a/os-posix.c b/os-posix.c index 92fa3baa1a..107fde38bf 100644 --- a/os-posix.c +++ b/os-posix.c @@ -38,6 +38,7 @@ #include "qemu/rcu.h" #include "qemu/error-report.h" #include "qemu/log.h" +#include "qemu/cutils.h" #ifdef CONFIG_LINUX #include <sys/prctl.h> diff --git a/pc-bios/optionrom/optionrom.h b/pc-bios/optionrom/optionrom.h index f1a9021ec1..6c4c2c82f4 100644 --- a/pc-bios/optionrom/optionrom.h +++ b/pc-bios/optionrom/optionrom.h @@ -19,8 +19,7 @@ */ -#define NO_QEMU_PROTOS -#include "../../include/hw/nvram/fw_cfg.h" +#include "../../include/hw/nvram/fw_cfg_keys.h" #define BIOS_CFG_IOPORT_CFG 0x510 #define BIOS_CFG_IOPORT_DATA 0x511 diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img Binary files differindex bd8f21050f..d3978ba050 100644 --- a/pc-bios/s390-ccw.img +++ b/pc-bios/s390-ccw.img diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile index 11c5dd4799..4208cb4295 100644 --- a/pc-bios/s390-ccw/Makefile +++ b/pc-bios/s390-ccw/Makefile @@ -9,7 +9,7 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw) .PHONY : all clean build-all -OBJECTS = start.o main.o bootmap.o sclp-ascii.o virtio.o +OBJECTS = start.o main.o bootmap.o sclp-ascii.o virtio.o virtio-scsi.o CFLAGS += -fPIE -fno-stack-protector -ffreestanding -march=z900 CFLAGS += -fno-delete-null-pointer-checks -msoft-float LDFLAGS += -Wl,-pie -nostdlib diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index 492530275d..611102e3ef 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -72,7 +72,7 @@ static void jump_to_IPL_code(uint64_t address) asm volatile("lghi 1,1\n\t" "diag 1,1,0x308\n\t" : : : "1", "memory"); - virtio_panic("\n! IPL returns !\n"); + panic("\n! IPL returns !\n"); } /*********************************************************************** @@ -84,7 +84,7 @@ static const int max_bprs_entries = sizeof(_bprs) / sizeof(ExtEckdBlockPtr); static inline void verify_boot_info(BootInfo *bip) { - IPL_assert(magic_match(bip->magic, ZIPL_MAGIC), "No zIPL magic"); + IPL_assert(magic_match(bip->magic, ZIPL_MAGIC), "No zIPL sig in BootInfo"); IPL_assert(bip->version == BOOT_INFO_VERSION, "Wrong zIPL version"); IPL_assert(bip->bp_type == BOOT_INFO_BP_TYPE_IPL, "DASD is not for IPL"); IPL_assert(bip->dev_type == BOOT_INFO_DEV_TYPE_ECKD, "DASD is not ECKD"); @@ -315,6 +315,40 @@ static void print_eckd_msg(void) sclp_print(msg); } +static void ipl_eckd(void) +{ + ScsiMbr *mbr = (void *)sec; + LDL_VTOC *vlbl = (void *)sec; + + print_eckd_msg(); + + /* Grab the MBR again */ + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); + read_block(0, mbr, "Cannot read block 0 on DASD"); + + if (magic_match(mbr->magic, IPL1_MAGIC)) { + ipl_eckd_cdl(); /* no return */ + } + + /* LDL/CMS? */ + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); + read_block(2, vlbl, "Cannot read block 2"); + + if (magic_match(vlbl->magic, CMS1_MAGIC)) { + ipl_eckd_ldl(ECKD_CMS); /* no return */ + } + if (magic_match(vlbl->magic, LNX1_MAGIC)) { + ipl_eckd_ldl(ECKD_LDL); /* no return */ + } + + ipl_eckd_ldl(ECKD_LDL_UNLABELED); /* it still may return */ + /* + * Ok, it is not a LDL by any means. + * It still might be a CDL with zero record keys for IPL1 and IPL2 + */ + ipl_eckd_cdl(); +} + /*********************************************************************** * IPL a SCSI disk */ @@ -382,7 +416,7 @@ static void zipl_run(ScsiBlockPtr *pte) read_block(pte->blockno, tmp_sec, "Cannot read header"); header = (ComponentHeader *)tmp_sec; - IPL_assert(magic_match(tmp_sec, ZIPL_MAGIC), "No zIPL magic"); + IPL_assert(magic_match(tmp_sec, ZIPL_MAGIC), "No zIPL magic in header"); IPL_assert(header->type == ZIPL_COMP_HEADER_IPL, "Bad header type"); dputs("start loading images\n"); @@ -412,16 +446,26 @@ static void ipl_scsi(void) const int pte_len = sizeof(ScsiBlockPtr); ScsiBlockPtr *prog_table_entry; - /* The 0-th block (MBR) was already read into sec[] */ + /* Grab the MBR */ + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); + read_block(0, mbr, "Cannot read block 0"); + + if (!magic_match(mbr->magic, ZIPL_MAGIC)) { + return; + } sclp_print("Using SCSI scheme.\n"); + debug_print_int("MBR Version", mbr->version_id); + IPL_check(mbr->version_id == 1, + "Unknown MBR layout version, assuming version 1"); debug_print_int("program table", mbr->blockptr.blockno); + IPL_assert(mbr->blockptr.blockno, "No Program Table"); /* Parse the program table */ read_block(mbr->blockptr.blockno, sec, "Error reading Program Table"); - IPL_assert(magic_match(sec, ZIPL_MAGIC), "No zIPL magic"); + IPL_assert(magic_match(sec, ZIPL_MAGIC), "No zIPL magic in PT"); ns_end = sec + virtio_get_block_size(); for (ns = (sec + pte_len); (ns + pte_len) < ns_end; ns += pte_len) { @@ -613,7 +657,7 @@ static IsoBcSection *find_iso_bc_entry(void) if (!is_iso_bc_valid(e)) { /* The validation entry is mandatory */ - virtio_panic("No valid boot catalog found!\n"); + panic("No valid boot catalog found!\n"); return NULL; } @@ -629,7 +673,7 @@ static IsoBcSection *find_iso_bc_entry(void) } } - virtio_panic("No suitable boot entry found on ISO-9660 media!\n"); + panic("No suitable boot entry found on ISO-9660 media!\n"); return NULL; } @@ -645,57 +689,58 @@ static void ipl_iso_el_torito(void) } /*********************************************************************** - * IPL starts here + * Bus specific IPL sequences */ -void zipl_load(void) +static void zipl_load_vblk(void) { - ScsiMbr *mbr = (void *)sec; - LDL_VTOC *vlbl = (void *)sec; - - /* Grab the MBR */ - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); - read_block(0, mbr, "Cannot read block 0"); - - dputs("checking magic\n"); - - if (magic_match(mbr->magic, ZIPL_MAGIC)) { - ipl_scsi(); /* no return */ - } - - /* Check if we can boot as ISO media */ if (virtio_guessed_disk_nature()) { virtio_assume_iso9660(); } ipl_iso_el_torito(); - /* We have failed to follow the SCSI scheme, so */ if (virtio_guessed_disk_nature()) { sclp_print("Using guessed DASD geometry.\n"); virtio_assume_eckd(); } - print_eckd_msg(); - if (magic_match(mbr->magic, IPL1_MAGIC)) { - ipl_eckd_cdl(); /* no return */ + ipl_eckd(); +} + +static void zipl_load_vscsi(void) +{ + if (virtio_get_block_size() == VIRTIO_ISO_BLOCK_SIZE) { + /* Is it an ISO image in non-CD drive? */ + ipl_iso_el_torito(); } - /* LDL/CMS? */ - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); - read_block(2, vlbl, "Cannot read block 2"); + sclp_print("Using guessed DASD geometry.\n"); + virtio_assume_eckd(); + ipl_eckd(); +} - if (magic_match(vlbl->magic, CMS1_MAGIC)) { - ipl_eckd_ldl(ECKD_CMS); /* no return */ - } - if (magic_match(vlbl->magic, LNX1_MAGIC)) { - ipl_eckd_ldl(ECKD_LDL); /* no return */ +/*********************************************************************** + * IPL starts here + */ + +void zipl_load(void) +{ + if (virtio_get_device()->is_cdrom) { + ipl_iso_el_torito(); + panic("\n! Cannot IPL this ISO image !\n"); } - ipl_eckd_ldl(ECKD_LDL_UNLABELED); /* it still may return */ - /* - * Ok, it is not a LDL by any means. - * It still might be a CDL with zero record keys for IPL1 and IPL2 - */ - ipl_eckd_cdl(); + ipl_scsi(); + + switch (virtio_get_device_type()) { + case VIRTIO_ID_BLOCK: + zipl_load_vblk(); + break; + case VIRTIO_ID_SCSI: + zipl_load_vscsi(); + break; + default: + panic("\n! Unknown IPL device type !\n"); + } - virtio_panic("\n* this can never happen *\n"); + panic("\n* this can never happen *\n"); } diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h index f98765b841..bea168714b 100644 --- a/pc-bios/s390-ccw/bootmap.h +++ b/pc-bios/s390-ccw/bootmap.h @@ -264,15 +264,6 @@ typedef enum { /* utility code below */ -static inline void IPL_assert(bool term, const char *message) -{ - if (!term) { - sclp_print("\n! "); - sclp_print(message); - virtio_panic(" !\n"); /* no return */ - } -} - static const unsigned char ebc2asc[256] = /* 0123456789abcdef0123456789abcdef */ "................................" /* 1F */ diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c index d5fe4cea1d..1c9e0791ab 100644 --- a/pc-bios/s390-ccw/main.c +++ b/pc-bios/s390-ccw/main.c @@ -12,9 +12,8 @@ #include "virtio.h" char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE))); -char ring_area[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE))); uint64_t boot_value; -static struct subchannel_id blk_schid = { .one = 1 }; +static SubChannelId blk_schid = { .one = 1 }; /* * Priniciples of Operations (SA22-7832-09) chapter 17 requires that @@ -23,7 +22,7 @@ static struct subchannel_id blk_schid = { .one = 1 }; */ void write_subsystem_identification(void) { - struct subchannel_id *schid = (struct subchannel_id *) 184; + SubChannelId *schid = (SubChannelId *) 184; uint32_t *zeroes = (uint32_t *) 188; *schid = blk_schid; @@ -31,14 +30,14 @@ void write_subsystem_identification(void) } -void virtio_panic(const char *string) +void panic(const char *string) { sclp_print(string); disabled_wait(); while (1) { } } -static bool find_dev(struct schib *schib, int dev_no) +static bool find_dev(Schib *schib, int dev_no) { int i, r; @@ -51,7 +50,7 @@ static bool find_dev(struct schib *schib, int dev_no) if (!schib->pmcw.dnv) { continue; } - if (!virtio_is_blk(blk_schid)) { + if (!virtio_is_supported(blk_schid)) { continue; } if ((dev_no < 0) || (schib->pmcw.dev == dev_no)) { @@ -64,7 +63,7 @@ static bool find_dev(struct schib *schib, int dev_no) static void virtio_setup(uint64_t dev_info) { - struct schib schib; + Schib schib; int ssid; bool found = false; uint16_t dev_no; @@ -92,15 +91,11 @@ static void virtio_setup(uint64_t dev_info) } } - if (!found) { - virtio_panic("No virtio-blk device found!\n"); - } + IPL_assert(found, "No virtio device found"); - virtio_setup_block(blk_schid); + virtio_setup_device(blk_schid); - if (!virtio_ipl_disk_is_valid()) { - virtio_panic("No valid hard disk detected.\n"); - } + IPL_assert(virtio_ipl_disk_is_valid(), "No valid IPL device detected"); } int main(void) @@ -111,6 +106,6 @@ int main(void) zipl_load(); /* no return */ - virtio_panic("Failed to load OS from hard disk\n"); + panic("Failed to load OS from hard disk\n"); return 0; /* make compiler happy */ } diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h index 5484c2a45c..616d96738d 100644 --- a/pc-bios/s390-ccw/s390-ccw.h +++ b/pc-bios/s390-ccw/s390-ccw.h @@ -45,15 +45,22 @@ typedef unsigned long long __u64; #include "cio.h" +typedef struct irb Irb; +typedef struct ccw1 Ccw1; +typedef struct cmd_orb CmdOrb; +typedef struct schib Schib; +typedef struct chsc_area_sda ChscAreaSda; +typedef struct senseid SenseId; +typedef struct subchannel_id SubChannelId; + /* start.s */ void disabled_wait(void); void consume_sclp_int(void); /* main.c */ -void virtio_panic(const char *string); +void panic(const char *string); void write_subsystem_identification(void); extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE))); -extern char ring_area[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE))); extern uint64_t boot_value; /* sclp-ascii.c */ @@ -63,10 +70,11 @@ void sclp_setup(void); /* virtio.c */ unsigned long virtio_load_direct(ulong rec_list1, ulong rec_list2, ulong subchan_id, void *load_addr); -bool virtio_is_blk(struct subchannel_id schid); -void virtio_setup_block(struct subchannel_id schid); +bool virtio_is_supported(SubChannelId schid); +void virtio_setup_device(SubChannelId schid); int virtio_read(ulong sector, void *load_addr); int enable_mss_facility(void); +ulong get_second(void); /* bootmap.c */ void zipl_load(void); @@ -143,4 +151,42 @@ static inline void yield(void) #define MAX_SECTOR_SIZE 4096 +static inline void sleep(unsigned int seconds) +{ + ulong target = get_second() + seconds; + + while (get_second() < target) { + yield(); + } +} + +static inline void *memcpy(void *s1, const void *s2, size_t n) +{ + uint8_t *p1 = s1; + const uint8_t *p2 = s2; + + while (n--) { + p1[n] = p2[n]; + } + return s1; +} + +static inline void IPL_assert(bool term, const char *message) +{ + if (!term) { + sclp_print("\n! "); + sclp_print(message); + panic(" !\n"); /* no return */ + } +} + +static inline void IPL_check(bool term, const char *message) +{ + if (!term) { + sclp_print("\n! WARNING: "); + sclp_print(message); + sclp_print(" !\n"); + } +} + #endif /* S390_CCW_H */ diff --git a/pc-bios/s390-ccw/scsi.h b/pc-bios/s390-ccw/scsi.h new file mode 100644 index 0000000000..fc830f7e52 --- /dev/null +++ b/pc-bios/s390-ccw/scsi.h @@ -0,0 +1,184 @@ +/* + * SCSI definitions for s390 machine loader for qemu + * + * Copyright 2015 IBM Corp. + * Author: Eugene "jno" Dvurechenski <jno@linux.vnet.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 SCSI_H +#define SCSI_H + +#include "s390-ccw.h" + +#define SCSI_DEFAULT_CDB_SIZE 32 +#define SCSI_DEFAULT_SENSE_SIZE 96 + +#define CDB_STATUS_GOOD 0 +#define CDB_STATUS_CHECK_CONDITION 0x02U +#define CDB_STATUS_VALID(status) (((status) & ~0x3eU) == 0) + +#define SCSI_SENSE_CODE_MASK 0x7fU +#define SCSI_SENSE_KEY_MASK 0x0fU +#define SCSI_SENSE_KEY_NO_SENSE 0 +#define SCSI_SENSE_KEY_UNIT_ATTENTION 6 + +union ScsiLun { + uint64_t v64; /* numeric shortcut */ + uint8_t v8[8]; /* generic 8 bytes representation */ + uint16_t v16[4]; /* 4-level big-endian LUN as specified by SAM-2 */ +}; +typedef union ScsiLun ScsiLun; + +struct ScsiSense70 { + uint8_t b0; /* b0 & 7f = resp code (0x70 or 0x71) */ + uint8_t b1, b2; /* b2 & 0f = sense key */ + uint8_t u1[1 * 4 + 1 + 1 * 4]; /* b7 = N - 7 */ + uint8_t additional_sense_code; /* b12 */ + uint8_t additional_sense_code_qualifier; /* b13 */ + uint8_t u2[1 + 3 + 0]; /* up to N (<=252) bytes */ +} __attribute__((packed)); +typedef struct ScsiSense70 ScsiSense70; + +/* don't confuse with virtio-scsi response/status fields! */ + +static inline uint8_t scsi_sense_response(const void *p) +{ + return ((const ScsiSense70 *)p)->b0 & SCSI_SENSE_CODE_MASK; +} + +static inline uint8_t scsi_sense_key(const void *p) +{ + return ((const ScsiSense70 *)p)->b2 & SCSI_SENSE_KEY_MASK; +} + +#define SCSI_INQ_RDT_CDROM 0x05 + +struct ScsiInquiryStd { + uint8_t peripheral_qdt; /* b0, use (b0 & 0x1f) to get SCSI_INQ_RDT */ + uint8_t b1; /* Removable Media Bit = b1 & 0x80 */ + uint8_t spc_version; /* b2 */ + uint8_t b3; /* b3 & 0x0f == resp_data_fmt == 2, must! */ + uint8_t u1[1 + 1 + 1 + 1 + 8]; /* b4..b15 unused, b4 = (N - 1) */ + char prod_id[16]; /* "QEMU CD-ROM" is here */ + uint8_t u2[4 /* b32..b35 unused, mandatory */ + + 8 + 12 + 1 + 1 + 8 * 2 + 22 /* b36..95 unused, optional*/ + + 0]; /* b96..bN unused, vendor specific */ + /* byte N */ +} __attribute__((packed)); +typedef struct ScsiInquiryStd ScsiInquiryStd; + +struct ScsiCdbInquiry { + uint8_t command; /* b0, == 0x12 */ + uint8_t b1; /* b1, |= 0x01 (evpd) */ + uint8_t b2; /* b2; if evpd==1 */ + uint16_t alloc_len; /* b3, b4 */ + uint8_t control; /* b5 */ +} __attribute__((packed)); +typedef struct ScsiCdbInquiry ScsiCdbInquiry; + +struct ScsiCdbRead10 { + uint8_t command; /* =0x28 */ + uint8_t b1; + uint32_t lba; + uint8_t b6; + uint16_t xfer_length; + uint8_t control; +} __attribute__((packed)); +typedef struct ScsiCdbRead10 ScsiCdbRead10; + +struct ScsiCdbTestUnitReady { + uint8_t command; /* =0x00 */ + uint8_t b1_b4[4]; + uint8_t control; +} __attribute__((packed)); +typedef struct ScsiCdbTestUnitReady ScsiCdbTestUnitReady; + +struct ScsiCdbReportLuns { + uint8_t command; /* =0xa0 */ + uint8_t b1; + uint8_t select_report; /* =0x02, "all" */ + uint8_t b3_b5[3]; + uint32_t alloc_len; + uint8_t b10; + uint8_t control; +} __attribute__((packed)); +typedef struct ScsiCdbReportLuns ScsiCdbReportLuns; + +struct ScsiLunReport { + uint32_t lun_list_len; + uint32_t b4_b7; + ScsiLun lun[1]; /* space for at least 1 lun must be allocated */ +} __attribute__((packed)); +typedef struct ScsiLunReport ScsiLunReport; + +struct ScsiCdbReadCapacity16 { + uint8_t command; /* =0x9e = "service action in 16" */ + uint8_t service_action; /* 5 bits, =0x10 = "read capacity 16" */ + uint64_t b2_b9; + uint32_t alloc_len; + uint8_t b14; + uint8_t control; +} __attribute__((packed)); +typedef struct ScsiCdbReadCapacity16 ScsiCdbReadCapacity16; + +struct ScsiReadCapacity16Data { + uint64_t ret_lba; /* get it, 0..7 */ + uint32_t lb_len; /* bytes, 8..11 */ + uint8_t u1[2 + 1 * 2 + 16]; /* b12..b31, unused */ +} __attribute__((packed)); +typedef struct ScsiReadCapacity16Data ScsiReadCapacity16Data; + +static inline ScsiLun make_lun(uint16_t channel, uint16_t target, uint32_t lun) +{ + ScsiLun r = { .v64 = 0 }; + + /* See QEMU code to choose the way to handle LUNs. + * + * So, a valid LUN must have (always channel #0): + * lun[0] == 1 + * lun[1] - target, any value + * lun[2] == 0 or (LUN, MSB, 0x40 set, 0x80 clear) + * lun[3] - LUN, LSB, any value + */ + r.v8[0] = 1; + r.v8[1] = target & 0xffU; + r.v8[2] = (lun >> 8) & 0x3fU; + if (r.v8[2]) { + r.v8[2] |= 0x40; + } + r.v8[3] = lun & 0xffU; + + return r; +} + +static inline const char *scsi_cdb_status_msg(uint8_t status) +{ + static char err_msg[] = "STATUS=XX"; + uint8_t v = status & 0x3eU; + + fill_hex_val(err_msg + 7, &v, 1); + return err_msg; +} + +static inline const char *scsi_cdb_asc_msg(const void *s) +{ + static char err_msg[] = "RSPN=XX KEY=XX CODE=XX QLFR=XX"; + const ScsiSense70 *p = s; + uint8_t sr = scsi_sense_response(s); + uint8_t sk = scsi_sense_key(s); + uint8_t ac = p->additional_sense_code; + uint8_t cq = p->additional_sense_code_qualifier; + + fill_hex_val(err_msg + 5, &sr, 1); + fill_hex_val(err_msg + 12, &sk, 1); + fill_hex_val(err_msg + 20, &ac, 1); + fill_hex_val(err_msg + 28, &cq, 1); + + return err_msg; +} + +#endif /* SCSI_H */ diff --git a/pc-bios/s390-ccw/virtio-scsi.c b/pc-bios/s390-ccw/virtio-scsi.c new file mode 100644 index 0000000000..3bb48e917e --- /dev/null +++ b/pc-bios/s390-ccw/virtio-scsi.c @@ -0,0 +1,342 @@ +/* + * Virtio-SCSI implementation for s390 machine loader for qemu + * + * Copyright 2015 IBM Corp. + * Author: Eugene "jno" Dvurechenski <jno@linux.vnet.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 "s390-ccw.h" +#include "virtio.h" +#include "scsi.h" +#include "virtio-scsi.h" + +static ScsiDevice default_scsi_device; +static VirtioScsiCmdReq req; +static VirtioScsiCmdResp resp; + +static uint8_t scsi_inquiry_std_response[256]; + +static inline void vs_assert(bool term, const char **msgs) +{ + if (!term) { + int i = 0; + + sclp_print("\n! "); + while (msgs[i]) { + sclp_print(msgs[i++]); + } + panic(" !\n"); + } +} + +static void virtio_scsi_verify_response(VirtioScsiCmdResp *resp, + const char *title) +{ + const char *mr[] = { + title, ": response ", virtio_scsi_response_msg(resp), 0 + }; + const char *ms[] = { + title, + CDB_STATUS_VALID(resp->status) ? ": " : ": invalid ", + scsi_cdb_status_msg(resp->status), + resp->status == CDB_STATUS_CHECK_CONDITION ? " " : 0, + resp->sense_len ? scsi_cdb_asc_msg(resp->sense) + : "no sense data", + scsi_sense_response(resp->sense) == 0x70 ? ", sure" : "?", + 0 + }; + + vs_assert(resp->response == VIRTIO_SCSI_S_OK, mr); + vs_assert(resp->status == CDB_STATUS_GOOD, ms); +} + +static void prepare_request(VDev *vdev, const void *cdb, int cdb_size, + void *data, uint32_t data_size) +{ + const ScsiDevice *sdev = vdev->scsi_device; + + memset(&req, 0, sizeof(req)); + req.lun = make_lun(sdev->channel, sdev->target, sdev->lun); + memcpy(&req.cdb, cdb, cdb_size); + + memset(&resp, 0, sizeof(resp)); + resp.status = 0xff; /* set invalid */ + resp.response = 0xff; /* */ + + if (data && data_size) { + memset(data, 0, data_size); + } +} + +static inline void vs_io_assert(bool term, const char *msg) +{ + if (!term) { + virtio_scsi_verify_response(&resp, msg); + } +} + +static void vs_run(const char *title, VirtioCmd *cmd, VDev *vdev, + const void *cdb, int cdb_size, + void *data, uint32_t data_size) +{ + prepare_request(vdev, cdb, cdb_size, data, data_size); + vs_io_assert(virtio_run(vdev, VR_REQUEST, cmd) == 0, title); +} + +/* SCSI protocol implementation routines */ + +static bool scsi_inquiry(VDev *vdev, void *data, uint32_t data_size) +{ + ScsiCdbInquiry cdb = { + .command = 0x12, + .alloc_len = data_size < 65535 ? data_size : 65535, + }; + VirtioCmd inquiry[] = { + { &req, sizeof(req), VRING_DESC_F_NEXT }, + { &resp, sizeof(resp), VRING_DESC_F_WRITE | VRING_DESC_F_NEXT }, + { data, data_size, VRING_DESC_F_WRITE }, + }; + + vs_run("inquiry", inquiry, vdev, &cdb, sizeof(cdb), data, data_size); + + return virtio_scsi_response_ok(&resp); +} + +static bool scsi_test_unit_ready(VDev *vdev) +{ + ScsiCdbTestUnitReady cdb = { + .command = 0x00, + }; + VirtioCmd test_unit_ready[] = { + { &req, sizeof(req), VRING_DESC_F_NEXT }, + { &resp, sizeof(resp), VRING_DESC_F_WRITE }, + }; + + prepare_request(vdev, &cdb, sizeof(cdb), 0, 0); + virtio_run(vdev, VR_REQUEST, test_unit_ready); /* ignore errors here */ + + return virtio_scsi_response_ok(&resp); +} + +static bool scsi_report_luns(VDev *vdev, void *data, uint32_t data_size) +{ + ScsiCdbReportLuns cdb = { + .command = 0xa0, + .select_report = 0x02, /* REPORT ALL */ + .alloc_len = data_size, + }; + VirtioCmd report_luns[] = { + { &req, sizeof(req), VRING_DESC_F_NEXT }, + { &resp, sizeof(resp), VRING_DESC_F_WRITE | VRING_DESC_F_NEXT }, + { data, data_size, VRING_DESC_F_WRITE }, + }; + + vs_run("report luns", report_luns, + vdev, &cdb, sizeof(cdb), data, data_size); + + return virtio_scsi_response_ok(&resp); +} + +static bool scsi_read_10(VDev *vdev, + ulong sector, int sectors, void *data) +{ + int f = vdev->blk_factor; + unsigned int data_size = sectors * virtio_get_block_size() * f; + ScsiCdbRead10 cdb = { + .command = 0x28, + .lba = sector * f, + .xfer_length = sectors * f, + }; + VirtioCmd read_10[] = { + { &req, sizeof(req), VRING_DESC_F_NEXT }, + { &resp, sizeof(resp), VRING_DESC_F_WRITE | VRING_DESC_F_NEXT }, + { data, data_size * f, VRING_DESC_F_WRITE }, + }; + + debug_print_int("read_10 sector", sector); + debug_print_int("read_10 sectors", sectors); + + vs_run("read(10)", read_10, vdev, &cdb, sizeof(cdb), data, data_size); + + return virtio_scsi_response_ok(&resp); +} + +static bool scsi_read_capacity(VDev *vdev, + void *data, uint32_t data_size) +{ + ScsiCdbReadCapacity16 cdb = { + .command = 0x9e, /* SERVICE_ACTION_IN_16 */ + .service_action = 0x10, /* SA_READ_CAPACITY */ + .alloc_len = data_size, + }; + VirtioCmd read_capacity_16[] = { + { &req, sizeof(req), VRING_DESC_F_NEXT }, + { &resp, sizeof(resp), VRING_DESC_F_WRITE | VRING_DESC_F_NEXT }, + { data, data_size, VRING_DESC_F_WRITE }, + }; + + vs_run("read capacity", read_capacity_16, + vdev, &cdb, sizeof(cdb), data, data_size); + + return virtio_scsi_response_ok(&resp); +} + +/* virtio-scsi routines */ + +static void virtio_scsi_locate_device(VDev *vdev) +{ + const uint16_t channel = 0; /* again, it's what QEMU does */ + uint16_t target; + static uint8_t data[16 + 8 * 63]; + ScsiLunReport *r = (void *) data; + ScsiDevice *sdev = vdev->scsi_device; + int i, luns; + + /* QEMU has hardcoded channel #0 in many places. + * If this hardcoded value is ever changed, we'll need to add code for + * vdev->config.scsi.max_channel != 0 here. + */ + debug_print_int("config.scsi.max_channel", vdev->config.scsi.max_channel); + debug_print_int("config.scsi.max_target ", vdev->config.scsi.max_target); + debug_print_int("config.scsi.max_lun ", vdev->config.scsi.max_lun); + + for (target = 0; target <= vdev->config.scsi.max_target; target++) { + sdev->channel = channel; + sdev->target = target; /* sdev->lun will be 0 here */ + if (!scsi_report_luns(vdev, data, sizeof(data))) { + if (resp.response == VIRTIO_SCSI_S_BAD_TARGET) { + continue; + } + print_int("target", target); + virtio_scsi_verify_response(&resp, "SCSI cannot report LUNs"); + } + if (r->lun_list_len == 0) { + print_int("no LUNs for target", target); + continue; + } + luns = r->lun_list_len / 8; + debug_print_int("LUNs reported", luns); + if (luns == 1) { + /* There is no ",lun=#" arg for -device or ",lun=0" given. + * Hence, the only LUN reported. + * Usually, it's 0. + */ + sdev->lun = r->lun[0].v16[0]; /* it's returned this way */ + debug_print_int("Have to use LUN", sdev->lun); + return; /* we have to use this device */ + } + for (i = 0; i < luns; i++) { + if (r->lun[i].v64) { + /* Look for non-zero LUN - we have where to choose from */ + sdev->lun = r->lun[i].v16[0]; + debug_print_int("Will use LUN", sdev->lun); + return; /* we have found a device */ + } + } + } + panic("\n! Cannot locate virtio-scsi device !\n"); +} + +int virtio_scsi_read_many(VDev *vdev, + ulong sector, void *load_addr, int sec_num) +{ + if (!scsi_read_10(vdev, sector, sec_num, load_addr)) { + virtio_scsi_verify_response(&resp, "virtio-scsi:read_many"); + } + + return 0; +} + +static bool virtio_scsi_inquiry_response_is_cdrom(void *data) +{ + const ScsiInquiryStd *response = data; + const int resp_data_fmt = response->b3 & 0x0f; + int i; + + IPL_check(resp_data_fmt == 2, "Wrong INQUIRY response format"); + if (resp_data_fmt != 2) { + return false; /* cannot decode */ + } + + if ((response->peripheral_qdt & 0x1f) == SCSI_INQ_RDT_CDROM) { + return true; + } + + for (i = 0; i < sizeof(response->prod_id); i++) { + if (response->prod_id[i] != QEMU_CDROM_SIGNATURE[i]) { + return false; + } + } + return true; +} + +static void scsi_parse_capacity_report(void *data, + uint64_t *last_lba, uint32_t *lb_len) +{ + ScsiReadCapacity16Data *p = data; + + if (last_lba) { + *last_lba = p->ret_lba; + } + + if (lb_len) { + *lb_len = p->lb_len; + } +} + +void virtio_scsi_setup(VDev *vdev) +{ + int retry_test_unit_ready = 3; + uint8_t data[256]; + uint32_t data_size = sizeof(data); + + vdev->scsi_device = &default_scsi_device; + virtio_scsi_locate_device(vdev); + + /* We have to "ping" the device before it becomes readable */ + while (!scsi_test_unit_ready(vdev)) { + + if (!virtio_scsi_response_ok(&resp)) { + uint8_t code = resp.sense[0] & SCSI_SENSE_CODE_MASK; + uint8_t sense_key = resp.sense[2] & SCSI_SENSE_KEY_MASK; + + IPL_assert(resp.sense_len != 0, "virtio-scsi:setup: no SENSE data"); + + IPL_assert(retry_test_unit_ready && code == 0x70 && + sense_key == SCSI_SENSE_KEY_UNIT_ATTENTION, + "virtio-scsi:setup: cannot retry"); + + /* retry on CHECK_CONDITION/UNIT_ATTENTION as it + * may not designate a real error, but it may be + * a result of device reset, etc. + */ + retry_test_unit_ready--; + sleep(1); + continue; + } + + virtio_scsi_verify_response(&resp, "virtio-scsi:setup"); + } + + /* read and cache SCSI INQUIRY response */ + if (!scsi_inquiry(vdev, scsi_inquiry_std_response, + sizeof(scsi_inquiry_std_response))) { + virtio_scsi_verify_response(&resp, "virtio-scsi:setup:inquiry"); + } + + if (virtio_scsi_inquiry_response_is_cdrom(scsi_inquiry_std_response)) { + sclp_print("SCSI CD-ROM detected.\n"); + vdev->is_cdrom = true; + vdev->scsi_block_size = VIRTIO_ISO_BLOCK_SIZE; + } + + if (!scsi_read_capacity(vdev, data, data_size)) { + virtio_scsi_verify_response(&resp, "virtio-scsi:setup:read_capacity"); + } + scsi_parse_capacity_report(data, &vdev->scsi_last_block, + (uint32_t *) &vdev->scsi_block_size); +} diff --git a/pc-bios/s390-ccw/virtio-scsi.h b/pc-bios/s390-ccw/virtio-scsi.h new file mode 100644 index 0000000000..f50b38b18b --- /dev/null +++ b/pc-bios/s390-ccw/virtio-scsi.h @@ -0,0 +1,72 @@ +/* + * Virtio-SCSI definitions for s390 machine loader for qemu + * + * Copyright 2015 IBM Corp. + * Author: Eugene "jno" Dvurechenski <jno@linux.vnet.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 VIRTIO_SCSI_H +#define VIRTIO_SCSI_H + +#include "s390-ccw.h" +#include "virtio.h" +#include "scsi.h" + +#define VIRTIO_SCSI_CDB_SIZE SCSI_DEFAULT_CDB_SIZE +#define VIRTIO_SCSI_SENSE_SIZE SCSI_DEFAULT_SENSE_SIZE + +/* command-specific response values */ +#define VIRTIO_SCSI_S_OK 0x00 +#define VIRTIO_SCSI_S_BAD_TARGET 0x03 + +#define QEMU_CDROM_SIGNATURE "QEMU CD-ROM " + +enum virtio_scsi_vq_id { + VR_CONTROL = 0, + VR_EVENT = 1, + VR_REQUEST = 2, +}; + +struct VirtioScsiCmdReq { + ScsiLun lun; + uint64_t id; + uint8_t task_attr; /* = 0 = VIRTIO_SCSI_S_SIMPLE */ + uint8_t prio; + uint8_t crn; /* = 0 */ + uint8_t cdb[VIRTIO_SCSI_CDB_SIZE]; +} __attribute__((packed)); +typedef struct VirtioScsiCmdReq VirtioScsiCmdReq; + +struct VirtioScsiCmdResp { + uint32_t sense_len; + uint32_t residual; + uint16_t status_qualifier; + uint8_t status; /* first check for .response */ + uint8_t response; /* then for .status */ + uint8_t sense[VIRTIO_SCSI_SENSE_SIZE]; +} __attribute__((packed)); +typedef struct VirtioScsiCmdResp VirtioScsiCmdResp; + +static inline const char *virtio_scsi_response_msg(const VirtioScsiCmdResp *r) +{ + static char err_msg[] = "VS RESP=XX"; + uint8_t v = r->response; + + fill_hex_val(err_msg + 8, &v, 1); + return err_msg; +} + +static inline bool virtio_scsi_response_ok(const VirtioScsiCmdResp *r) +{ + return r->response == VIRTIO_SCSI_S_OK && r->status == CDB_STATUS_GOOD; +} + +void virtio_scsi_setup(VDev *vdev); +int virtio_scsi_read_many(VDev *vdev, + ulong sector, void *load_addr, int sec_num); + +#endif /* VIRTIO_SCSI_H */ diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c index 87aed38a95..1d34e8c1aa 100644 --- a/pc-bios/s390-ccw/virtio.c +++ b/pc-bios/s390-ccw/virtio.c @@ -10,39 +10,68 @@ #include "s390-ccw.h" #include "virtio.h" +#include "virtio-scsi.h" -static struct vring block; +#define VRING_WAIT_REPLY_TIMEOUT 3 + +static VRing block[VIRTIO_MAX_VQS]; +static char ring_area[VIRTIO_RING_SIZE * VIRTIO_MAX_VQS] + __attribute__((__aligned__(PAGE_SIZE))); static char chsc_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); +static VDev vdev = { + .nr_vqs = 1, + .vrings = block, + .cmd_vr_idx = 0, + .ring_area = ring_area, + .wait_reply_timeout = VRING_WAIT_REPLY_TIMEOUT, + .schid = { .one = 1 }, + .scsi_block_size = VIRTIO_SCSI_BLOCK_SIZE, + .blk_factor = 1, +}; + +VDev *virtio_get_device(void) +{ + return &vdev; +} + +VirtioDevType virtio_get_device_type(void) +{ + return vdev.senseid.cu_model; +} + +/* virtio spec v1.0 para 4.3.3.2 */ static long kvm_hypercall(unsigned long nr, unsigned long param1, - unsigned long param2) + unsigned long param2, unsigned long param3) { register ulong r_nr asm("1") = nr; register ulong r_param1 asm("2") = param1; register ulong r_param2 asm("3") = param2; + register ulong r_param3 asm("4") = param3; register long retval asm("2"); asm volatile ("diag 2,4,0x500" : "=d" (retval) - : "d" (r_nr), "0" (r_param1), "r"(r_param2) + : "d" (r_nr), "0" (r_param1), "r"(r_param2), "d"(r_param3) : "memory", "cc"); return retval; } -static void virtio_notify(struct subchannel_id schid) +static long virtio_notify(SubChannelId schid, int vq_idx, long cookie) { - kvm_hypercall(KVM_S390_VIRTIO_CCW_NOTIFY, *(u32 *)&schid, 0); + return kvm_hypercall(KVM_S390_VIRTIO_CCW_NOTIFY, *(u32 *)&schid, + vq_idx, cookie); } /*********************************************** * Virtio functions * ***********************************************/ -static int drain_irqs(struct subchannel_id schid) +static int drain_irqs(SubChannelId schid) { - struct irb irb = {}; + Irb irb = {}; int r = 0; while (1) { @@ -59,17 +88,17 @@ static int drain_irqs(struct subchannel_id schid) } } -static int run_ccw(struct subchannel_id schid, int cmd, void *ptr, int len) +static int run_ccw(VDev *vdev, int cmd, void *ptr, int len) { - struct ccw1 ccw = {}; - struct cmd_orb orb = {}; - struct schib schib; + Ccw1 ccw = {}; + CmdOrb orb = {}; + Schib schib; int r; /* start command processing */ - stsch_err(schid, &schib); + stsch_err(vdev->schid, &schib); schib.scsw.ctrl = SCSW_FCTL_START_FUNC; - msch(schid, &schib); + msch(vdev->schid, &schib); /* start subchannel command */ orb.fmt = 1; @@ -80,41 +109,29 @@ static int run_ccw(struct subchannel_id schid, int cmd, void *ptr, int len) ccw.cda = (long)ptr; ccw.count = len; - r = ssch(schid, &orb); + r = ssch(vdev->schid, &orb); /* * XXX Wait until device is done processing the CCW. For now we can * assume that a simple tsch will have finished the CCW processing, * but the architecture allows for asynchronous operation */ if (!r) { - r = drain_irqs(schid); + r = drain_irqs(vdev->schid); } return r; } -static void virtio_set_status(struct subchannel_id schid, - unsigned long dev_addr) +static void vring_init(VRing *vr, VqInfo *info) { - unsigned char status = dev_addr; - if (run_ccw(schid, CCW_CMD_WRITE_STATUS, &status, sizeof(status))) { - virtio_panic("Could not write status to host!\n"); - } -} + void *p = (void *) info->queue; -static void virtio_reset(struct subchannel_id schid) -{ - run_ccw(schid, CCW_CMD_VDEV_RESET, NULL, 0); -} - -static void vring_init(struct vring *vr, unsigned int num, void *p, - unsigned long align) -{ debug_print_addr("init p", p); - vr->num = num; + vr->id = info->index; + vr->num = info->num; vr->desc = p; - vr->avail = p + num*sizeof(struct vring_desc); - vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + align-1) - & ~(align - 1)); + vr->avail = p + info->num * sizeof(VRingDesc); + vr->used = (void *)(((unsigned long)&vr->avail->ring[info->num] + + info->align - 1) & ~(info->align - 1)); /* Zero out all relevant field */ vr->avail->flags = 0; @@ -125,16 +142,18 @@ static void vring_init(struct vring *vr, unsigned int num, void *p, vr->used->idx = 0; vr->used_idx = 0; vr->next_idx = 0; + vr->cookie = 0; debug_print_addr("init vr", vr); } -static void vring_notify(struct subchannel_id schid) +static bool vring_notify(VRing *vr) { - virtio_notify(schid); + vr->cookie = virtio_notify(vr->schid, vr->id, vr->cookie); + return vr->cookie >= 0; } -static void vring_send_buf(struct vring *vr, void *p, int len, int flags) +static void vring_send_buf(VRing *vr, void *p, int len, int flags) { /* For follow-up chains we need to keep the first entry point */ if (!(flags & VRING_HIDDEN_IS_CHAIN)) { @@ -162,11 +181,26 @@ static u64 get_clock(void) return r; } -static ulong get_second(void) +ulong get_second(void) { return (get_clock() >> 12) / 1000000; } +static int vr_poll(VRing *vr) +{ + if (vr->used->idx == vr->used_idx) { + vring_notify(vr); + yield(); + return 0; + } + + vr->used_idx = vr->used->idx; + vr->next_idx = 0; + vr->desc[0].len = 0; + vr->desc[0].flags = 0; + return 1; /* vr has been updated */ +} + /* * Wait for the host to reply. * @@ -174,67 +208,92 @@ static ulong get_second(void) * * Returns 0 on success, 1 on timeout. */ -static int vring_wait_reply(struct vring *vr, int timeout) +static int vring_wait_reply(void) { - ulong target_second = get_second() + timeout; - struct subchannel_id schid = vr->schid; - int r = 0; + ulong target_second = get_second() + vdev.wait_reply_timeout; - /* Wait until the used index has moved. */ - while (vr->used->idx == vr->used_idx) { - vring_notify(schid); - if (timeout && (get_second() >= target_second)) { - r = 1; - break; + /* Wait for any queue to be updated by the host */ + do { + int i, r = 0; + + for (i = 0; i < vdev.nr_vqs; i++) { + r += vr_poll(&vdev.vrings[i]); } yield(); - } + if (r) { + return 0; + } + } while (!vdev.wait_reply_timeout || (get_second() < target_second)); - vr->used_idx = vr->used->idx; - vr->next_idx = 0; - vr->desc[0].len = 0; - vr->desc[0].flags = 0; + return 1; +} - return r; +int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd) +{ + VRing *vr = &vdev->vrings[vqid]; + int i = 0; + + do { + vring_send_buf(vr, cmd[i].data, cmd[i].size, + cmd[i].flags | (i ? VRING_HIDDEN_IS_CHAIN : 0)); + } while (cmd[i++].flags & VRING_DESC_F_NEXT); + + vring_wait_reply(); + if (drain_irqs(vr->schid)) { + return -1; + } + return 0; } /*********************************************** * Virtio block * ***********************************************/ -int virtio_read_many(ulong sector, void *load_addr, int sec_num) +static int virtio_blk_read_many(VDev *vdev, + ulong sector, void *load_addr, int sec_num) { - struct virtio_blk_outhdr out_hdr; + VirtioBlkOuthdr out_hdr; u8 status; - int r; + VRing *vr = &vdev->vrings[vdev->cmd_vr_idx]; /* Tell the host we want to read */ out_hdr.type = VIRTIO_BLK_T_IN; out_hdr.ioprio = 99; out_hdr.sector = virtio_sector_adjust(sector); - vring_send_buf(&block, &out_hdr, sizeof(out_hdr), VRING_DESC_F_NEXT); + vring_send_buf(vr, &out_hdr, sizeof(out_hdr), VRING_DESC_F_NEXT); /* This is where we want to receive data */ - vring_send_buf(&block, load_addr, virtio_get_block_size() * sec_num, + vring_send_buf(vr, load_addr, virtio_get_block_size() * sec_num, VRING_DESC_F_WRITE | VRING_HIDDEN_IS_CHAIN | VRING_DESC_F_NEXT); /* status field */ - vring_send_buf(&block, &status, sizeof(u8), VRING_DESC_F_WRITE | - VRING_HIDDEN_IS_CHAIN); + vring_send_buf(vr, &status, sizeof(u8), + VRING_DESC_F_WRITE | VRING_HIDDEN_IS_CHAIN); /* Now we can tell the host to read */ - vring_wait_reply(&block, 0); + vring_wait_reply(); - r = drain_irqs(block.schid); - if (r) { + if (drain_irqs(vr->schid)) { /* Well, whatever status is supposed to contain... */ status = 1; } return status; } +int virtio_read_many(ulong sector, void *load_addr, int sec_num) +{ + switch (vdev.senseid.cu_model) { + case VIRTIO_ID_BLOCK: + return virtio_blk_read_many(&vdev, sector, load_addr, sec_num); + case VIRTIO_ID_SCSI: + return virtio_scsi_read_many(&vdev, sector, load_addr, sec_num); + } + panic("\n! No readable IPL device !\n"); + return -1; +} + unsigned long virtio_load_direct(ulong rec_list1, ulong rec_list2, ulong subchan_id, void *load_addr) { @@ -251,7 +310,7 @@ unsigned long virtio_load_direct(ulong rec_list1, ulong rec_list2, sclp_print("."); status = virtio_read_many(sec, (void *)addr, sec_num); if (status) { - virtio_panic("I/O Error"); + panic("I/O Error"); } addr += sec_num * virtio_get_block_size(); @@ -263,78 +322,110 @@ int virtio_read(ulong sector, void *load_addr) return virtio_read_many(sector, load_addr, 1); } -static VirtioBlkConfig blk_cfg = {}; -static bool guessed_disk_nature; +/* + * Other supported value pairs, if any, would need to be added here. + * Note: head count is always 15. + */ +static inline u8 virtio_eckd_sectors_for_block_size(int size) +{ + switch (size) { + case 512: + return 49; + case 1024: + return 33; + case 2048: + return 21; + case 4096: + return 12; + } + return 0; +} -bool virtio_guessed_disk_nature(void) +VirtioGDN virtio_guessed_disk_nature(void) { - return guessed_disk_nature; + return vdev.guessed_disk_nature; } void virtio_assume_scsi(void) { - guessed_disk_nature = true; - blk_cfg.blk_size = 512; - blk_cfg.physical_block_exp = 0; + switch (vdev.senseid.cu_model) { + case VIRTIO_ID_BLOCK: + vdev.guessed_disk_nature = VIRTIO_GDN_SCSI; + vdev.config.blk.blk_size = VIRTIO_SCSI_BLOCK_SIZE; + vdev.config.blk.physical_block_exp = 0; + vdev.blk_factor = 1; + break; + case VIRTIO_ID_SCSI: + vdev.scsi_block_size = VIRTIO_SCSI_BLOCK_SIZE; + break; + } } void virtio_assume_iso9660(void) { - guessed_disk_nature = true; - blk_cfg.blk_size = 2048; - blk_cfg.physical_block_exp = 0; + switch (vdev.senseid.cu_model) { + case VIRTIO_ID_BLOCK: + vdev.guessed_disk_nature = VIRTIO_GDN_SCSI; + vdev.config.blk.blk_size = VIRTIO_ISO_BLOCK_SIZE; + vdev.config.blk.physical_block_exp = 0; + vdev.blk_factor = VIRTIO_ISO_BLOCK_SIZE / VIRTIO_SECTOR_SIZE; + break; + case VIRTIO_ID_SCSI: + vdev.scsi_block_size = VIRTIO_ISO_BLOCK_SIZE; + break; + } } void virtio_assume_eckd(void) { - guessed_disk_nature = true; - blk_cfg.blk_size = 4096; - blk_cfg.physical_block_exp = 0; - - /* this must be here to calculate code segment position */ - blk_cfg.geometry.heads = 15; - blk_cfg.geometry.sectors = 12; + vdev.guessed_disk_nature = VIRTIO_GDN_DASD; + vdev.blk_factor = 1; + vdev.config.blk.physical_block_exp = 0; + switch (vdev.senseid.cu_model) { + case VIRTIO_ID_BLOCK: + vdev.config.blk.blk_size = 4096; + break; + case VIRTIO_ID_SCSI: + vdev.config.blk.blk_size = vdev.scsi_block_size; + break; + } + vdev.config.blk.geometry.heads = 15; + vdev.config.blk.geometry.sectors = + virtio_eckd_sectors_for_block_size(vdev.config.blk.blk_size); } bool virtio_disk_is_scsi(void) { - if (guessed_disk_nature) { - return (virtio_get_block_size() == 512); + if (vdev.guessed_disk_nature == VIRTIO_GDN_SCSI) { + return true; } - return (blk_cfg.geometry.heads == 255) - && (blk_cfg.geometry.sectors == 63) - && (virtio_get_block_size() == 512); -} - -/* - * Other supported value pairs, if any, would need to be added here. - * Note: head count is always 15. - */ -static inline u8 virtio_eckd_sectors_for_block_size(int size) -{ - switch (size) { - case 512: - return 49; - case 1024: - return 33; - case 2048: - return 21; - case 4096: - return 12; + switch (vdev.senseid.cu_model) { + case VIRTIO_ID_BLOCK: + return (vdev.config.blk.geometry.heads == 255) + && (vdev.config.blk.geometry.sectors == 63) + && (virtio_get_block_size() == VIRTIO_SCSI_BLOCK_SIZE); + case VIRTIO_ID_SCSI: + return true; } - return 0; + return false; } bool virtio_disk_is_eckd(void) { const int block_size = virtio_get_block_size(); - if (guessed_disk_nature) { - return (block_size == 4096); + if (vdev.guessed_disk_nature == VIRTIO_GDN_DASD) { + return true; } - return (blk_cfg.geometry.heads == 15) - && (blk_cfg.geometry.sectors == - virtio_eckd_sectors_for_block_size(block_size)); + switch (vdev.senseid.cu_model) { + case VIRTIO_ID_BLOCK: + return (vdev.config.blk.geometry.heads == 15) + && (vdev.config.blk.geometry.sectors == + virtio_eckd_sectors_for_block_size(block_size)); + case VIRTIO_ID_SCSI: + return false; + } + return false; } bool virtio_ipl_disk_is_valid(void) @@ -344,34 +435,80 @@ bool virtio_ipl_disk_is_valid(void) int virtio_get_block_size(void) { - return blk_cfg.blk_size << blk_cfg.physical_block_exp; + switch (vdev.senseid.cu_model) { + case VIRTIO_ID_BLOCK: + return vdev.config.blk.blk_size << vdev.config.blk.physical_block_exp; + case VIRTIO_ID_SCSI: + return vdev.scsi_block_size; + } + return 0; } uint8_t virtio_get_heads(void) { - return blk_cfg.geometry.heads; + switch (vdev.senseid.cu_model) { + case VIRTIO_ID_BLOCK: + return vdev.config.blk.geometry.heads; + case VIRTIO_ID_SCSI: + return vdev.guessed_disk_nature == VIRTIO_GDN_DASD + ? vdev.config.blk.geometry.heads : 255; + } + return 0; } uint8_t virtio_get_sectors(void) { - return blk_cfg.geometry.sectors; + switch (vdev.senseid.cu_model) { + case VIRTIO_ID_BLOCK: + return vdev.config.blk.geometry.sectors; + case VIRTIO_ID_SCSI: + return vdev.guessed_disk_nature == VIRTIO_GDN_DASD + ? vdev.config.blk.geometry.sectors : 63; + } + return 0; } uint64_t virtio_get_blocks(void) { - return blk_cfg.capacity / - (virtio_get_block_size() / VIRTIO_SECTOR_SIZE); + const uint64_t factor = virtio_get_block_size() / VIRTIO_SECTOR_SIZE; + switch (vdev.senseid.cu_model) { + case VIRTIO_ID_BLOCK: + return vdev.config.blk.capacity / factor; + case VIRTIO_ID_SCSI: + return vdev.scsi_last_block / factor; + } + return 0; } -void virtio_setup_block(struct subchannel_id schid) +static void virtio_setup_ccw(VDev *vdev) { - struct vq_info_block info; - struct vq_config_block config = {}; - - blk_cfg.blk_size = 0; /* mark "illegal" - setup started... */ - guessed_disk_nature = false; - - virtio_reset(schid); + int i, cfg_size = 0; + unsigned char status = VIRTIO_CONFIG_S_DRIVER_OK; + + IPL_assert(virtio_is_supported(vdev->schid), "PE"); + /* device ID has been established now */ + + vdev->config.blk.blk_size = 0; /* mark "illegal" - setup started... */ + vdev->guessed_disk_nature = VIRTIO_GDN_NONE; + + run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0); + + switch (vdev->senseid.cu_model) { + case VIRTIO_ID_BLOCK: + vdev->nr_vqs = 1; + vdev->cmd_vr_idx = 0; + cfg_size = sizeof(vdev->config.blk); + break; + case VIRTIO_ID_SCSI: + vdev->nr_vqs = 3; + vdev->cmd_vr_idx = VR_REQUEST; + cfg_size = sizeof(vdev->config.scsi); + break; + default: + panic("Unsupported virtio device\n"); + } + IPL_assert(run_ccw(vdev, CCW_CMD_READ_CONF, &vdev->config, cfg_size) == 0, + "Could not get block device configuration"); /* * Skipping CCW_CMD_READ_FEAT. We're not doing anything fancy, and @@ -379,54 +516,84 @@ void virtio_setup_block(struct subchannel_id schid) * expect it. */ - config.index = 0; - if (run_ccw(schid, CCW_CMD_READ_VQ_CONF, &config, sizeof(config))) { - virtio_panic("Could not get block device VQ configuration\n"); - } - if (run_ccw(schid, CCW_CMD_READ_CONF, &blk_cfg, sizeof(blk_cfg))) { - virtio_panic("Could not get block device configuration\n"); - } - vring_init(&block, config.num, ring_area, - KVM_S390_VIRTIO_RING_ALIGN); - - info.queue = (unsigned long long) ring_area; - info.align = KVM_S390_VIRTIO_RING_ALIGN; - info.index = 0; - info.num = config.num; - block.schid = schid; - - if (!run_ccw(schid, CCW_CMD_SET_VQ, &info, sizeof(info))) { - virtio_set_status(schid, VIRTIO_CONFIG_S_DRIVER_OK); + for (i = 0; i < vdev->nr_vqs; i++) { + VqInfo info = { + .queue = (unsigned long long) ring_area + (i * VIRTIO_RING_SIZE), + .align = KVM_S390_VIRTIO_RING_ALIGN, + .index = i, + .num = 0, + }; + VqConfig config = { + .index = i, + .num = 0, + }; + + IPL_assert( + run_ccw(vdev, CCW_CMD_READ_VQ_CONF, &config, sizeof(config)) == 0, + "Could not get block device VQ configuration"); + info.num = config.num; + vring_init(&vdev->vrings[i], &info); + vdev->vrings[i].schid = vdev->schid; + IPL_assert(run_ccw(vdev, CCW_CMD_SET_VQ, &info, sizeof(info)) == 0, + "Cannot set VQ info"); } + IPL_assert( + run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status)) == 0, + "Could not write status to host"); +} - if (!virtio_ipl_disk_is_valid()) { - /* make sure all getters but blocksize return 0 for invalid IPL disk */ - memset(&blk_cfg, 0, sizeof(blk_cfg)); - virtio_assume_scsi(); +void virtio_setup_device(SubChannelId schid) +{ + vdev.schid = schid; + virtio_setup_ccw(&vdev); + + switch (vdev.senseid.cu_model) { + case VIRTIO_ID_BLOCK: + sclp_print("Using virtio-blk.\n"); + if (!virtio_ipl_disk_is_valid()) { + /* make sure all getters but blocksize return 0 for + * invalid IPL disk + */ + memset(&vdev.config.blk, 0, sizeof(vdev.config.blk)); + virtio_assume_scsi(); + } + break; + case VIRTIO_ID_SCSI: + IPL_assert(vdev.config.scsi.sense_size == VIRTIO_SCSI_SENSE_SIZE, + "Config: sense size mismatch"); + IPL_assert(vdev.config.scsi.cdb_size == VIRTIO_SCSI_CDB_SIZE, + "Config: CDB size mismatch"); + + sclp_print("Using virtio-scsi.\n"); + virtio_scsi_setup(&vdev); + break; + default: + panic("\n! No IPL device available !\n"); } } -bool virtio_is_blk(struct subchannel_id schid) +bool virtio_is_supported(SubChannelId schid) { - int r; - struct senseid senseid = {}; - + vdev.schid = schid; + memset(&vdev.senseid, 0, sizeof(vdev.senseid)); /* run sense id command */ - r = run_ccw(schid, CCW_CMD_SENSE_ID, &senseid, sizeof(senseid)); - if (r) { + if (run_ccw(&vdev, CCW_CMD_SENSE_ID, &vdev.senseid, sizeof(vdev.senseid))) { return false; } - if ((senseid.cu_type != 0x3832) || (senseid.cu_model != VIRTIO_ID_BLOCK)) { - return false; + if (vdev.senseid.cu_type == 0x3832) { + switch (vdev.senseid.cu_model) { + case VIRTIO_ID_BLOCK: + case VIRTIO_ID_SCSI: + return true; + } } - - return true; + return false; } int enable_mss_facility(void) { int ret; - struct chsc_area_sda *sda_area = (struct chsc_area_sda *) chsc_page; + ChscAreaSda *sda_area = (ChscAreaSda *) chsc_page; memset(sda_area, 0, PAGE_SIZE); sda_area->request.length = 0x0400; diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h index afa01a885b..3c6e91510e 100644 --- a/pc-bios/s390-ccw/virtio.h +++ b/pc-bios/s390-ccw/virtio.h @@ -23,49 +23,58 @@ /* We've given up on this device. */ #define VIRTIO_CONFIG_S_FAILED 0x80 -enum virtio_dev_type { +enum VirtioDevType { VIRTIO_ID_NET = 1, VIRTIO_ID_BLOCK = 2, VIRTIO_ID_CONSOLE = 3, VIRTIO_ID_BALLOON = 5, + VIRTIO_ID_SCSI = 8, }; - -struct virtio_dev_header { - enum virtio_dev_type type : 8; - u8 num_vq; - u8 feature_len; - u8 config_len; - u8 status; - u8 vqconfig[]; +typedef enum VirtioDevType VirtioDevType; + +struct VirtioDevHeader { + VirtioDevType type:8; + uint8_t num_vq; + uint8_t feature_len; + uint8_t config_len; + uint8_t status; + uint8_t vqconfig[]; } __attribute__((packed)); +typedef struct VirtioDevHeader VirtioDevHeader; -struct virtio_vqconfig { - u64 token; - u64 address; - u16 num; - u8 pad[6]; +struct VirtioVqConfig { + uint64_t token; + uint64_t address; + uint16_t num; + uint8_t pad[6]; } __attribute__((packed)); +typedef struct VirtioVqConfig VirtioVqConfig; -struct vq_info_block { - u64 queue; - u32 align; - u16 index; - u16 num; +struct VqInfo { + uint64_t queue; + uint32_t align; + uint16_t index; + uint16_t num; } __attribute__((packed)); +typedef struct VqInfo VqInfo; -struct vq_config_block { - u16 index; - u16 num; +struct VqConfig { + uint16_t index; + uint16_t num; } __attribute__((packed)); +typedef struct VqConfig VqConfig; -struct virtio_dev { - struct virtio_dev_header *header; - struct virtio_vqconfig *vqconfig; +struct VirtioDev { + VirtioDevHeader *header; + VirtioVqConfig *vqconfig; char *host_features; char *guest_features; char *config; }; +typedef struct VirtioDev VirtioDev; +#define VIRTIO_RING_SIZE (PAGE_SIZE * 8) +#define VIRTIO_MAX_VQS 3 #define KVM_S390_VIRTIO_RING_ALIGN 4096 #define VRING_USED_F_NO_NOTIFY 1 @@ -81,46 +90,53 @@ struct virtio_dev { #define VRING_HIDDEN_IS_CHAIN 256 /* Virtio ring descriptors: 16 bytes. These can chain together via "next". */ -struct vring_desc { +struct VRingDesc { /* Address (guest-physical). */ - u64 addr; + uint64_t addr; /* Length. */ - u32 len; + uint32_t len; /* The flags as indicated above. */ - u16 flags; + uint16_t flags; /* We chain unused descriptors via this, too */ - u16 next; + uint16_t next; } __attribute__((packed)); +typedef struct VRingDesc VRingDesc; -struct vring_avail { - u16 flags; - u16 idx; - u16 ring[]; +struct VRingAvail { + uint16_t flags; + uint16_t idx; + uint16_t ring[]; } __attribute__((packed)); +typedef struct VRingAvail VRingAvail; -/* u32 is used here for ids for padding reasons. */ -struct vring_used_elem { +/* uint32_t is used here for ids for padding reasons. */ +struct VRingUsedElem { /* Index of start of used descriptor chain. */ - u32 id; + uint32_t id; /* Total length of the descriptor chain which was used (written to) */ - u32 len; + uint32_t len; } __attribute__((packed)); +typedef struct VRingUsedElem VRingUsedElem; -struct vring_used { - u16 flags; - u16 idx; - struct vring_used_elem ring[]; +struct VRingUsed { + uint16_t flags; + uint16_t idx; + VRingUsedElem ring[]; } __attribute__((packed)); +typedef struct VRingUsed VRingUsed; -struct vring { +struct VRing { unsigned int num; int next_idx; int used_idx; - struct vring_desc *desc; - struct vring_avail *avail; - struct vring_used *used; - struct subchannel_id schid; + VRingDesc *desc; + VRingAvail *avail; + VRingUsed *used; + SubChannelId schid; + long cookie; + int id; }; +typedef struct VRing VRing; /*********************************************** @@ -152,39 +168,49 @@ struct vring { #define VIRTIO_BLK_T_BARRIER 0x80000000 /* This is the first element of the read scatter-gather list. */ -struct virtio_blk_outhdr { +struct VirtioBlkOuthdr { /* VIRTIO_BLK_T* */ - u32 type; + uint32_t type; /* io priority. */ - u32 ioprio; + uint32_t ioprio; /* Sector (ie. 512 byte offset) */ - u64 sector; + uint64_t sector; }; +typedef struct VirtioBlkOuthdr VirtioBlkOuthdr; -typedef struct VirtioBlkConfig { - u64 capacity; /* in 512-byte sectors */ - u32 size_max; /* max segment size (if VIRTIO_BLK_F_SIZE_MAX) */ - u32 seg_max; /* max number of segments (if VIRTIO_BLK_F_SEG_MAX) */ +struct VirtioBlkConfig { + uint64_t capacity; /* in 512-byte sectors */ + uint32_t size_max; /* max segment size (if VIRTIO_BLK_F_SIZE_MAX) */ + uint32_t seg_max; /* max number of segments (if VIRTIO_BLK_F_SEG_MAX) */ - struct virtio_blk_geometry { - u16 cylinders; - u8 heads; - u8 sectors; + struct VirtioBlkGeometry { + uint16_t cylinders; + uint8_t heads; + uint8_t sectors; } geometry; /* (if VIRTIO_BLK_F_GEOMETRY) */ - u32 blk_size; /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */ + uint32_t blk_size; /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */ /* the next 4 entries are guarded by VIRTIO_BLK_F_TOPOLOGY */ - u8 physical_block_exp; /* exponent for physical block per logical block */ - u8 alignment_offset; /* alignment offset in logical blocks */ - u16 min_io_size; /* min I/O size without performance penalty + uint8_t physical_block_exp; /* exponent for physical blk per logical blk */ + uint8_t alignment_offset; /* alignment offset in logical blocks */ + uint16_t min_io_size; /* min I/O size without performance penalty in logical blocks */ - u32 opt_io_size; /* optimal sustained I/O size in logical blocks */ + uint32_t opt_io_size; /* optimal sustained I/O size in logical blks */ + + uint8_t wce; /* writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */ +} __attribute__((packed)); +typedef struct VirtioBlkConfig VirtioBlkConfig; - u8 wce; /* writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */ -} __attribute__((packed)) VirtioBlkConfig; +enum guessed_disk_nature_type { + VIRTIO_GDN_NONE = 0, + VIRTIO_GDN_DASD = 1, + VIRTIO_GDN_CDROM = 2, + VIRTIO_GDN_SCSI = 3, +}; +typedef enum guessed_disk_nature_type VirtioGDN; -bool virtio_guessed_disk_nature(void); +VirtioGDN virtio_guessed_disk_nature(void); void virtio_assume_scsi(void); void virtio_assume_eckd(void); void virtio_assume_iso9660(void); @@ -199,10 +225,68 @@ extern uint64_t virtio_get_blocks(void); extern int virtio_read_many(ulong sector, void *load_addr, int sec_num); #define VIRTIO_SECTOR_SIZE 512 +#define VIRTIO_ISO_BLOCK_SIZE 2048 +#define VIRTIO_SCSI_BLOCK_SIZE 512 static inline ulong virtio_sector_adjust(ulong sector) { return sector * (virtio_get_block_size() / VIRTIO_SECTOR_SIZE); } +struct VirtioScsiConfig { + uint32_t num_queues; + uint32_t seg_max; + uint32_t max_sectors; + uint32_t cmd_per_lun; + uint32_t event_info_size; + uint32_t sense_size; + uint32_t cdb_size; + uint16_t max_channel; + uint16_t max_target; + uint32_t max_lun; +} __attribute__((packed)); +typedef struct VirtioScsiConfig VirtioScsiConfig; + +struct ScsiDevice { + uint16_t channel; /* Always 0 in QEMU */ + uint16_t target; /* will be scanned over */ + uint32_t lun; /* will be reported */ +}; +typedef struct ScsiDevice ScsiDevice; + +struct VDev { + int nr_vqs; + VRing *vrings; + int cmd_vr_idx; + void *ring_area; + long wait_reply_timeout; + VirtioGDN guessed_disk_nature; + SubChannelId schid; + SenseId senseid; + union { + VirtioBlkConfig blk; + VirtioScsiConfig scsi; + } config; + ScsiDevice *scsi_device; + bool is_cdrom; + int scsi_block_size; + int blk_factor; + uint64_t scsi_last_block; + uint32_t scsi_dev_cyls; + uint8_t scsi_dev_heads; +}; +typedef struct VDev VDev; + +VDev *virtio_get_device(void); +VirtioDevType virtio_get_device_type(void); + +struct VirtioCmd { + void *data; + int size; + int flags; +}; +typedef struct VirtioCmd VirtioCmd; + +int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd); + #endif /* VIRTIO_H */ diff --git a/qapi-schema.json b/qapi-schema.json index e1dd7e19b4..8907790daa 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3089,6 +3089,7 @@ # # 'unmapped' and 'pause' since 2.0 # 'ro' and 'kp_comma' since 2.4 +# 'kp_equals' and 'power' since 2.6 ## { 'enum': 'QKeyCode', 'data': [ 'unmapped', @@ -3107,7 +3108,7 @@ 'left', 'up', 'down', 'right', 'insert', 'delete', 'stop', 'again', 'props', 'undo', 'front', 'copy', 'open', 'paste', 'find', 'cut', 'lf', 'help', 'meta_l', 'meta_r', 'compose', 'pause', 'ro', - 'kp_comma' ] } + 'kp_comma', 'kp_equals', 'power' ] } ## # @KeyValue diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c index 73e4acea7b..602f2609cc 100644 --- a/qapi/opts-visitor.c +++ b/qapi/opts-visitor.c @@ -11,7 +11,8 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qapi/error.h" +#include "qemu/cutils.h" #include "qapi/qmp/qerror.h" #include "qapi/opts-visitor.h" #include "qemu/queue.h" diff --git a/qapi/qapi-util.c b/qapi/qapi-util.c index 8afb12eb43..818730a660 100644 --- a/qapi/qapi-util.c +++ b/qapi/qapi-util.c @@ -11,6 +11,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qapi/util.h" diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index 856606b253..fa680c9991 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -13,6 +13,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qapi/qmp/qobject.h" #include "qapi/qmp/qerror.h" diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 8f27c3456d..510a1aead8 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -12,6 +12,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qapi/qmp/types.h" #include "qapi/qmp/dispatch.h" #include "qapi/qmp/json-parser.h" diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c index e6598327c3..7cd1b777a0 100644 --- a/qapi/qmp-input-visitor.c +++ b/qapi/qmp-input-visitor.c @@ -13,6 +13,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qapi/qmp-input-visitor.h" #include "qapi/visitor-impl.h" #include "qemu/queue.h" diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c index 59eb5dc4e3..ab129536e4 100644 --- a/qapi/string-input-visitor.c +++ b/qapi/string-input-visitor.c @@ -11,6 +11,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qapi/string-input-visitor.h" #include "qapi/visitor-impl.h" diff --git a/qdev-monitor.c b/qdev-monitor.c index be6a07ee49..e19617fa8b 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -27,6 +27,7 @@ #include "qapi/qmp/qerror.h" #include "qemu/config-file.h" #include "qemu/error-report.h" +#include "qemu/help_option.h" /* * Aliases were a bad idea from the start. Let's keep them diff --git a/qemu-char.c b/qemu-char.c index f90e4c1208..270819aec3 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" #include "qemu-common.h" +#include "qemu/cutils.h" #include "monitor/monitor.h" #include "sysemu/sysemu.h" #include "sysemu/block-backend.h" @@ -2798,6 +2799,13 @@ static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len) NULL); } + if (ret == QIO_CHANNEL_ERR_BLOCK) { + errno = EAGAIN; + ret = -1; + } else if (ret == -1) { + errno = EIO; + } + if (msgfds_num) { /* close and clean read_msgfds */ for (i = 0; i < s->read_msgfds_num; i++) { diff --git a/qemu-doc.texi b/qemu-doc.texi index bc9dd13cc9..79141d3582 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -1262,13 +1262,18 @@ basic example. @subsection Inter-VM Shared Memory device -With KVM enabled on a Linux host, a shared memory device is available. Guests -map a POSIX shared memory region into the guest as a PCI device that enables -zero-copy communication to the application level of the guests. The basic -syntax is: +On Linux hosts, a shared memory device is available. The basic syntax +is: @example -qemu-system-i386 -device ivshmem,size=@var{size},shm=@var{shm-name} +qemu-system-x86_64 -device ivshmem-plain,memdev=@var{hostmem} +@end example + +where @var{hostmem} names a host memory backend. For a POSIX shared +memory backend, use something like + +@example +-object memory-backend-file,size=1M,share,mem-path=/dev/shm/ivshmem,id=@var{hostmem} @end example If desired, interrupts can be sent between guest VMs accessing the same shared @@ -1282,28 +1287,24 @@ memory server is: ivshmem-server -p @var{pidfile} -S @var{path} -m @var{shm-name} -l @var{shm-size} -n @var{vectors} # Then start your qemu instances with matching arguments -qemu-system-i386 -device ivshmem,size=@var{shm-size},vectors=@var{vectors},chardev=@var{id} - [,msi=on][,ioeventfd=on][,role=peer|master] +qemu-system-x86_64 -device ivshmem-doorbell,vectors=@var{vectors},chardev=@var{id} -chardev socket,path=@var{path},id=@var{id} @end example When using the server, the guest will be assigned a VM ID (>=0) that allows guests using the same server to communicate via interrupts. Guests can read their -VM ID from a device register (see example code). Since receiving the shared -memory region from the server is asynchronous, there is a (small) chance the -guest may boot before the shared memory is attached. To allow an application -to ensure shared memory is attached, the VM ID register will return -1 (an -invalid VM ID) until the memory is attached. Once the shared memory is -attached, the VM ID will return the guest's valid VM ID. With these semantics, -the guest application can check to ensure the shared memory is attached to the -guest before proceeding. - -The @option{role} argument can be set to either master or peer and will affect -how the shared memory is migrated. With @option{role=master}, the guest will -copy the shared memory on migration to the destination host. With -@option{role=peer}, the guest will not be able to migrate with the device attached. -With the @option{peer} case, the device should be detached and then reattached -after migration using the PCI hotplug support. +VM ID from a device register (see ivshmem-spec.txt). + +@subsubsection Migration with ivshmem + +With device property @option{master=on}, the guest will copy the shared +memory on migration to the destination host. With @option{master=off}, +the guest will not be able to migrate with the device attached. In the +latter case, the device should be detached and then reattached after +migration using the PCI hotplug support. + +At most one of the devices sharing the same memory can be master. The +master must complete migration before you plug back the other devices. @subsubsection ivshmem and hugepages @@ -1311,8 +1312,8 @@ Instead of specifying the <shm size> using POSIX shm, you may specify a memory backend that has hugepage support: @example -qemu-system-i386 -object memory-backend-file,size=1G,mem-path=/mnt/hugepages/my-shmem-file,id=mb1 - -device ivshmem,x-memdev=mb1 +qemu-system-x86_64 -object memory-backend-file,size=1G,mem-path=/dev/hugepages/my-shmem-file,share,id=mb1 + -device ivshmem-plain,memdev=mb1 @end example ivshmem-server also supports hugepages mount points with the diff --git a/qemu-img.c b/qemu-img.c index 29eae2a24b..bd93d0a774 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -22,11 +22,12 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qapi-visit.h" #include "qapi/qmp-output-visitor.h" #include "qapi/qmp/qerror.h" #include "qapi/qmp/qjson.h" -#include "qemu-common.h" +#include "qemu/cutils.h" #include "qemu/config-file.h" #include "qemu/option.h" #include "qemu/error-report.h" diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index e929d24a49..139f7ebcbb 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -9,6 +9,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-io.h" #include "sysemu/block-backend.h" #include "block/block.h" @@ -18,6 +19,7 @@ #include "qemu/main-loop.h" #include "qemu/timer.h" #include "sysemu/block-backend.h" +#include "qemu/cutils.h" #define CMD_NOFILE_OK 0x01 @@ -11,6 +11,7 @@ #include <getopt.h> #include <libgen.h> +#include "qapi/error.h" #include "qemu-io.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" diff --git a/qemu-nbd.c b/qemu-nbd.c index f3528c8c04..9bb9cb7f61 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -17,7 +17,9 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" +#include "qemu/cutils.h" #include "sysemu/block-backend.h" #include "block/block_int.h" #include "block/nbd.h" diff --git a/qemu-options.hx b/qemu-options.hx index 5654ce35bb..d70d0703ac 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1226,15 +1226,6 @@ STEXI Set the initial graphical resolution and depth (PPC, SPARC only). ETEXI -DEF("input-linux", 1, QEMU_OPTION_input_linux, - "-input-linux <evdev>\n" - " Use input device.\n", QEMU_ARCH_ALL) -STEXI -@item -input-linux @var{dev} -@findex -input-linux -Use input device. -ETEXI - DEF("vnc", HAS_ARG, QEMU_OPTION_vnc , "-vnc display start a VNC server on display\n", QEMU_ARCH_ALL) STEXI @@ -3165,6 +3156,24 @@ STEXI Output log in @var{logfile} instead of to stderr ETEXI +DEF("dfilter", HAS_ARG, QEMU_OPTION_DFILTER, \ + "-dfilter range,.. filter debug output to range of addresses (useful for -d cpu,exec,etc..)\n", + QEMU_ARCH_ALL) +STEXI +@item -dfilter @var{range1}[,...] +@findex -dfilter +Filter debug output to that relevant to a range of target addresses. The filter +spec can be either @var{start}+@var{size}, @var{start}-@var{size} or +@var{start}..@var{end} where @var{start} @var{end} and @var{size} are the +addresses and sizes required. For example: +@example + -dfilter 0x8000..0x8fff,0xffffffc000080000+0x200,0xffffffc000060000-0x1000 +@end example +Will dump output for any code in the 0x1000 sized block starting at 0x8000 and +the 0x200 sized block starting at 0xffffffc000080000 and another 0x1000 sized +block starting at 0xffffffc00005f000. +ETEXI + DEF("L", HAS_ARG, QEMU_OPTION_L, \ "-L path set the directory for the BIOS, VGA BIOS and keymaps\n", QEMU_ARCH_ALL) diff --git a/qga/channel-posix.c b/qga/channel-posix.c index 7ad3c00765..63458c6632 100644 --- a/qga/channel-posix.c +++ b/qga/channel-posix.c @@ -1,6 +1,7 @@ #include "qemu/osdep.h" #include <glib.h> #include <termios.h> +#include "qapi/error.h" #include "qemu/sockets.h" #include "qga/channel.h" diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 9f51faea80..2ae37255d4 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -23,6 +23,7 @@ #include "qemu/host-utils.h" #include "qemu/sockets.h" #include "qemu/base64.h" +#include "qemu/cutils.h" #ifndef CONFIG_HAS_ENVIRON #ifdef __APPLE__ diff --git a/qga/commands.c b/qga/commands.c index e091ee1af1..95d8b04a16 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -16,6 +16,7 @@ #include "qga-qmp-commands.h" #include "qapi/qmp/qerror.h" #include "qemu/base64.h" +#include "qemu/cutils.h" /* Maximum captured guest-exec out_data/err_data - 16MB */ #define GUEST_EXEC_MAX_OUTPUT (16*1024*1024) diff --git a/qga/main.c b/qga/main.c index 743c5c1349..c552782101 100644 --- a/qga/main.c +++ b/qga/main.c @@ -24,11 +24,11 @@ #include "qapi/qmp/qjson.h" #include "qga/guest-agent-core.h" #include "qemu/module.h" -#include "signal.h" #include "qapi/qmp/qerror.h" #include "qapi/qmp/dispatch.h" #include "qga/channel.h" #include "qemu/bswap.h" +#include "qemu/help_option.h" #ifdef _WIN32 #include "qga/service-win32.h" #include "qga/vss-win32.h" diff --git a/qga/vss-win32/requester.cpp b/qga/vss-win32/requester.cpp index b57d5170e8..889052dedd 100644 --- a/qga/vss-win32/requester.cpp +++ b/qga/vss-win32/requester.cpp @@ -13,7 +13,6 @@ #include "qemu/osdep.h" #include "vss-common.h" #include "requester.h" -#include "assert.h" #include "inc/win2003/vswriter.h" #include "inc/win2003/vsbackup.h" @@ -14,7 +14,7 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qemu/cutils.h" #include "monitor/monitor.h" #include "sysemu/sysemu.h" #include "qmp-commands.h" diff --git a/qobject/json-parser.c b/qobject/json-parser.c index 6c05f6cc70..67ed727318 100644 --- a/qobject/json-parser.c +++ b/qobject/json-parser.c @@ -12,7 +12,7 @@ */ #include "qemu/osdep.h" - +#include "qapi/error.h" #include "qemu-common.h" #include "qapi/qmp/qstring.h" #include "qapi/qmp/qint.h" diff --git a/qobject/qdict.c b/qobject/qdict.c index 9833bd0730..a1285361c4 100644 --- a/qobject/qdict.c +++ b/qobject/qdict.c @@ -19,6 +19,7 @@ #include "qapi/qmp/qobject.h" #include "qemu/queue.h" #include "qemu-common.h" +#include "qemu/cutils.h" /** * qdict_new(): Create a new QDict diff --git a/qobject/qjson.c b/qobject/qjson.c index 06dc210cbf..ef160d2119 100644 --- a/qobject/qjson.c +++ b/qobject/qjson.c @@ -21,6 +21,7 @@ #include "qapi/qmp/qbool.h" #include "qapi/qmp/qfloat.h" #include "qapi/qmp/qdict.h" +#include "qemu/unicode.h" typedef struct JSONParsingState { @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qom/cpu.h" #include "sysemu/kvm.h" diff --git a/qom/object.c b/qom/object.c index 844ae7a0fd..8e6e68dffc 100644 --- a/qom/object.c +++ b/qom/object.c @@ -11,9 +11,10 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qom/object.h" #include "qom/object_interfaces.h" -#include "qemu-common.h" +#include "qemu/cutils.h" #include "qapi/visitor.h" #include "qapi-visit.h" #include "qapi/string-input-visitor.h" diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c index c2f6e2998e..ab5da35e4f 100644 --- a/qom/object_interfaces.c +++ b/qom/object_interfaces.c @@ -1,4 +1,5 @@ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qom/object_interfaces.h" #include "qemu/module.h" #include "qapi-visit.h" diff --git a/qom/qom-qobject.c b/qom/qom-qobject.c index 9cbc4c69a6..e6b17c1f1b 100644 --- a/qom/qom-qobject.c +++ b/qom/qom-qobject.c @@ -10,6 +10,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qom/object.h" #include "qom/qom-qobject.h" @@ -12,6 +12,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "sysemu/qtest.h" #include "hw/qdev.h" #include "sysemu/char.h" diff --git a/replay/replay-input.c b/replay/replay-input.c index 2d5d9191ca..06babe0ecc 100644 --- a/replay/replay-input.c +++ b/replay/replay-input.c @@ -10,6 +10,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "sysemu/replay.h" #include "replay-internal.h" diff --git a/replay/replay.c b/replay/replay.c index fcfde4fc93..ec32c81072 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -10,6 +10,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "sysemu/replay.h" #include "replay-internal.h" diff --git a/scripts/clean-includes b/scripts/clean-includes index 177d253eb9..72b47f17f9 100755 --- a/scripts/clean-includes +++ b/scripts/clean-includes @@ -139,12 +139,13 @@ for f in "$@"; do # Remove includes that osdep.h already provides perl -n -i -e 'print if !/\s*#\s*include\s*(["<][^>"]*[">])/ || ! (grep { $_ eq $1 } qw ( - "config-host.h" "qemu/compiler.h" "config.h" - <stdarg.h> <stddef.h> <stdbool.h> <stdint.h> <sys/types.h> + "config-host.h" "config-target.h" "qemu/compiler.h" + <setjmp.h> <stdarg.h> <stddef.h> <stdbool.h> <stdint.h> <sys/types.h> <stdlib.h> <stdio.h> <string.h> <strings.h> <inttypes.h> <limits.h> <unistd.h> <time.h> <ctype.h> <errno.h> <fcntl.h> <sys/stat.h> <sys/time.h> <assert.h> <signal.h> - "glib-compat.h" "qapi/error.h" + "sysemu/os-posix.h, sysemu/os-win32.h "glib-compat.h" + "qemu/typedefs.h" ))' "$f" done diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py index e09c8751a9..437cf6c8e3 100644 --- a/scripts/qapi-types.py +++ b/scripts/qapi-types.py @@ -294,11 +294,6 @@ fdef.write(mcgen(''' ''', prefix=prefix)) -# To avoid circular headers, use only typedefs.h here, not qobject.h -fdecl.write(mcgen(''' -#include "qemu/typedefs.h" -''')) - schema = QAPISchema(input_file) gen = QAPISchemaGenTypeVisitor() schema.visit(gen) diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index c147990efe..31d2330356 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -355,6 +355,7 @@ h_comment = ''' fdef.write(mcgen(''' #include "qemu/osdep.h" #include "qemu-common.h" +#include "qapi/error.h" #include "%(prefix)sqapi-visit.h" ''', prefix=prefix)) diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py index a62c310705..e409b7326e 100644 --- a/scripts/tracetool/backend/log.py +++ b/scripts/tracetool/backend/log.py @@ -20,11 +20,7 @@ PUBLIC = True def generate_h_begin(events): - out('#include <stdio.h>', - '#include <sys/time.h>', - '#include <sys/types.h>', - '#include <unistd.h>', - '#include "trace/control.h"', + out('#include "trace/control.h"', '#include "qemu/log.h"', '') diff --git a/scripts/tracetool/format/events_h.py b/scripts/tracetool/format/events_h.py index bbfaa5bd1f..4529263e00 100644 --- a/scripts/tracetool/format/events_h.py +++ b/scripts/tracetool/format/events_h.py @@ -21,8 +21,6 @@ def generate(events, backend): '', '#ifndef TRACE__GENERATED_EVENTS_H', '#define TRACE__GENERATED_EVENTS_H', - '', - '#include <stdbool.h>', '') # event identifiers diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py index 2bd68a218e..0835406216 100644 --- a/scripts/tracetool/format/h.py +++ b/scripts/tracetool/format/h.py @@ -23,7 +23,6 @@ def generate(events, backend): '#define TRACE__GENERATED_TRACERS_H', '', '#include "qemu-common.h"', - '#include "qemu/typedefs.h"', '') backend.generate_begin(events) diff --git a/scripts/tracetool/format/tcg_h.py b/scripts/tracetool/format/tcg_h.py index 006eaa897c..e2331f251d 100644 --- a/scripts/tracetool/format/tcg_h.py +++ b/scripts/tracetool/format/tcg_h.py @@ -34,8 +34,6 @@ def generate(events, backend): '#ifndef TRACE__GENERATED_TCG_TRACERS_H', '#define TRACE__GENERATED_TCG_TRACERS_H', '', - '#include <stdint.h>', - '', '#include "trace.h"', '#include "exec/helper-proto.h"', '', diff --git a/scripts/tracetool/format/ust_events_c.py b/scripts/tracetool/format/ust_events_c.py index bf0b334362..9967c7a82e 100644 --- a/scripts/tracetool/format/ust_events_c.py +++ b/scripts/tracetool/format/ust_events_c.py @@ -32,5 +32,4 @@ def generate(events, backend): ' */', '#pragma GCC diagnostic ignored "-Wredundant-decls"', '', - '#include "qemu/typedefs.h"', '#include "generated-ust-provider.h"') diff --git a/slirp/slirp.c b/slirp/slirp.c index 9ccf4157d8..3481fcc94b 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -28,6 +28,7 @@ #include "sysemu/char.h" #include "slirp.h" #include "hw/hw.h" +#include "qemu/cutils.h" /* host loopback address */ struct in_addr loopback_addr; diff --git a/slirp/tftp.c b/slirp/tftp.c index 25ad6efdf8..12b5ff6e25 100644 --- a/slirp/tftp.c +++ b/slirp/tftp.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include <slirp.h> #include "qemu-common.h" +#include "qemu/cutils.h" static inline int tftp_session_in_use(struct tftp_session *spt) { diff --git a/stubs/gdbstub.c b/stubs/gdbstub.c index 359c28990a..2b7aee50d3 100644 --- a/stubs/gdbstub.c +++ b/stubs/gdbstub.c @@ -1,6 +1,4 @@ #include "qemu/osdep.h" -#include "stdbool.h" /* bool (in exec/gdbstub.h) */ -#include "stddef.h" /* NULL */ #include "exec/gdbstub.h" /* xml_builtin */ const char *const xml_builtin[][2] = { diff --git a/stubs/get-fd.c b/stubs/get-fd.c index 85881fb678..7dfdfb55f7 100644 --- a/stubs/get-fd.c +++ b/stubs/get-fd.c @@ -1,4 +1,5 @@ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "monitor/monitor.h" diff --git a/stubs/target-get-monitor-def.c b/stubs/target-get-monitor-def.c index 4d1033d12d..394e0f9a7d 100644 --- a/stubs/target-get-monitor-def.c +++ b/stubs/target-get-monitor-def.c @@ -20,8 +20,6 @@ */ #include "qemu/osdep.h" -#include "qemu/typedefs.h" -#include "stdint.h" int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval); diff --git a/stubs/target-monitor-defs.c b/stubs/target-monitor-defs.c index 203ebb0f27..ac07b19064 100644 --- a/stubs/target-monitor-defs.c +++ b/stubs/target-monitor-defs.c @@ -1,6 +1,4 @@ #include "qemu/osdep.h" -#include "stddef.h" -#include "qemu/typedefs.h" const MonitorDef *target_monitor_defs(void); diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index 2eab0609e4..8a155cae90 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -20,6 +20,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" #include "migration/vmstate.h" diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c index 76c33b97e7..8be0645eb0 100644 --- a/target-arm/arm-semi.c +++ b/target-arm/arm-semi.c @@ -30,6 +30,7 @@ #include "qemu-common.h" #include "exec/gdbstub.h" #include "hw/arm/arm.h" +#include "qemu/cutils.h" #endif #define TARGET_SYS_OPEN 0x01 diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 352d9f883d..e48e83acbb 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "internals.h" #include "qemu-common.h" diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c index fa5eda2cd1..1635debc1a 100644 --- a/target-arm/cpu64.c +++ b/target-arm/cpu64.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" #if !defined(CONFIG_USER_ONLY) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index f0c73df5b0..b13cff756a 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -11225,7 +11225,8 @@ done_generating: gen_tb_end(tb, num_insns); #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && + qemu_log_in_addr_range(pc_start)) { qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc->pc - pc_start, diff --git a/target-arm/translate.c b/target-arm/translate.c index 5a818afc02..940ec8d981 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -11958,7 +11958,8 @@ done_generating: gen_tb_end(tb, num_insns); #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && + qemu_log_in_addr_range(pc_start)) { qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc->pc - pc_start, diff --git a/target-cris/cpu.c b/target-cris/cpu.c index b2c8624dbf..1cb79dd977 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -22,6 +22,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" #include "mmu.h" diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 3ea6b294a4..ddae932ee1 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -17,6 +17,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" +#include "qemu/cutils.h" #include "cpu.h" #include "sysemu/kvm.h" @@ -360,7 +361,7 @@ static const char *cpuid_6_feature_name[] = { CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2, CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM, CPUID_7_0_EBX_RDSEED */ -#define TCG_7_0_ECX_FEATURES 0 +#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE) #define TCG_APM_FEATURES 0 #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT #define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1) @@ -2425,6 +2426,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *eax = 0; /* Maximum ECX value for sub-leaves */ *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */ *ecx = env->features[FEAT_7_0_ECX]; /* Feature flags */ + if ((*ecx & CPUID_7_0_ECX_PKU) && env->cr[4] & CR4_PKE_MASK) { + *ecx |= CPUID_7_0_ECX_OSPKE; + } *edx = 0; /* Reserved */ } else { *eax = 0; @@ -2732,9 +2736,13 @@ static void x86_cpu_reset(CPUState *s) if (env->features[FEAT_1_EDX] & CPUID_SSE) { xcr0 |= XSTATE_SSE_MASK; } - if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_MPX) { - xcr0 |= XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK; + for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) { + const ExtSaveArea *esa = &x86_ext_save_areas[i]; + if ((env->features[esa->feature] & esa->bits) == esa->bits) { + xcr0 |= 1ull << i; + } } + if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) { cr4 |= CR4_OSFXSR_MASK | CR4_OSXSAVE_MASK; } diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 5148c8252d..732eb6d7ec 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -232,6 +232,7 @@ #define CR4_OSXSAVE_MASK (1U << 18) #define CR4_SMEP_MASK (1U << 20) #define CR4_SMAP_MASK (1U << 21) +#define CR4_PKE_MASK (1U << 22) #define DR6_BD (1 << 13) #define DR6_BS (1 << 14) @@ -260,6 +261,7 @@ #define PG_PSE_BIT 7 #define PG_GLOBAL_BIT 8 #define PG_PSE_PAT_BIT 12 +#define PG_PKRU_BIT 59 #define PG_NX_BIT 63 #define PG_PRESENT_MASK (1 << PG_PRESENT_BIT) @@ -275,7 +277,8 @@ #define PG_ADDRESS_MASK 0x000ffffffffff000LL #define PG_HI_RSVD_MASK (PG_ADDRESS_MASK & ~PHYS_ADDR_MASK) #define PG_HI_USER_MASK 0x7ff0000000000000LL -#define PG_NX_MASK (1LL << PG_NX_BIT) +#define PG_PKRU_MASK (15ULL << PG_PKRU_BIT) +#define PG_NX_MASK (1ULL << PG_NX_BIT) #define PG_ERROR_W_BIT 1 @@ -284,6 +287,7 @@ #define PG_ERROR_U_MASK 0x04 #define PG_ERROR_RSVD_MASK 0x08 #define PG_ERROR_I_D_MASK 0x10 +#define PG_ERROR_PK_MASK 0x20 #define MCG_CTL_P (1ULL<<8) /* MCG_CAP register available */ #define MCG_SER_P (1ULL<<24) /* MCA recovery/new status bits */ diff --git a/target-i386/fpu_helper.c b/target-i386/fpu_helper.c index d1a7f4cbec..fee5573a10 100644 --- a/target-i386/fpu_helper.c +++ b/target-i386/fpu_helper.c @@ -1184,6 +1184,11 @@ static void do_xsave_bndcsr(CPUX86State *env, target_ulong addr, uintptr_t ra) cpu_stq_data_ra(env, addr + 8, env->bndcs_regs.sts, ra); } +static void do_xsave_pkru(CPUX86State *env, target_ulong addr, uintptr_t ra) +{ + cpu_stq_data_ra(env, addr, env->pkru, ra); +} + void helper_fxsave(CPUX86State *env, target_ulong ptr) { uintptr_t ra = GETPC(); @@ -1257,6 +1262,10 @@ static void do_xsave(CPUX86State *env, target_ulong ptr, uint64_t rfbm, target_ulong off = x86_ext_save_areas[XSTATE_BNDCSR_BIT].offset; do_xsave_bndcsr(env, ptr + off, ra); } + if (opt & XSTATE_PKRU_MASK) { + target_ulong off = x86_ext_save_areas[XSTATE_PKRU_BIT].offset; + do_xsave_pkru(env, ptr + off, ra); + } /* Update the XSTATE_BV field. */ old_bv = cpu_ldq_data_ra(env, ptr + 512, ra); @@ -1339,6 +1348,11 @@ static void do_xrstor_bndcsr(CPUX86State *env, target_ulong addr, uintptr_t ra) env->bndcs_regs.sts = cpu_ldq_data_ra(env, addr + 8, ra); } +static void do_xrstor_pkru(CPUX86State *env, target_ulong addr, uintptr_t ra) +{ + env->pkru = cpu_ldq_data_ra(env, addr, ra); +} + void helper_fxrstor(CPUX86State *env, target_ulong ptr) { uintptr_t ra = GETPC(); @@ -1438,6 +1452,19 @@ void helper_xrstor(CPUX86State *env, target_ulong ptr, uint64_t rfbm) } cpu_sync_bndcs_hflags(env); } + if (rfbm & XSTATE_PKRU_MASK) { + uint64_t old_pkru = env->pkru; + if (xstate_bv & XSTATE_PKRU_MASK) { + target_ulong off = x86_ext_save_areas[XSTATE_PKRU_BIT].offset; + do_xrstor_pkru(env, ptr + off, ra); + } else { + env->pkru = 0; + } + if (env->pkru != old_pkru) { + CPUState *cs = CPU(x86_env_get_cpu(env)); + tlb_flush(cs, 1); + } + } } uint64_t helper_xgetbv(CPUX86State *env, uint32_t ecx) diff --git a/target-i386/helper.c b/target-i386/helper.c index 3f60ec6122..575583942a 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -676,6 +676,10 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4) hflags |= HF_SMAP_MASK; } + if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) { + new_cr4 &= ~CR4_PKE_MASK; + } + env->cr[4] = new_cr4; env->hflags = hflags; @@ -920,6 +924,24 @@ do_check_protect_pse36: goto do_fault_protect; } + if ((env->cr[4] & CR4_PKE_MASK) && (env->hflags & HF_LMA_MASK) && + (ptep & PG_USER_MASK) && env->pkru) { + uint32_t pk = (pte & PG_PKRU_MASK) >> PG_PKRU_BIT; + uint32_t pkru_ad = (env->pkru >> pk * 2) & 1; + uint32_t pkru_wd = (env->pkru >> pk * 2) & 2; + + if (pkru_ad) { + prot &= ~(PAGE_READ | PAGE_WRITE); + } else if (pkru_wd && (is_user || env->cr[0] & CR0_WP_MASK)) { + prot &= ~PAGE_WRITE; + } + if ((prot & (1 << is_write1)) == 0) { + assert(is_write1 != 2); + error_code |= PG_ERROR_PK_MASK; + goto do_fault_protect; + } + } + /* yes, it can! */ is_dirty = is_write && !(pte & PG_DIRTY_MASK); if (!(pte & PG_ACCESSED_MASK) || is_dirty) { diff --git a/target-i386/helper.h b/target-i386/helper.h index e33451aea9..1320edc016 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -198,6 +198,8 @@ DEF_HELPER_FLAGS_3(xsaveopt, TCG_CALL_NO_WG, void, env, tl, i64) DEF_HELPER_FLAGS_3(xrstor, TCG_CALL_NO_WG, void, env, tl, i64) DEF_HELPER_FLAGS_2(xgetbv, TCG_CALL_NO_WG, i64, env, i32) DEF_HELPER_FLAGS_3(xsetbv, TCG_CALL_NO_WG, void, env, i32, i64) +DEF_HELPER_FLAGS_2(rdpkru, TCG_CALL_NO_WG, i64, env, i32) +DEF_HELPER_FLAGS_3(wrpkru, TCG_CALL_NO_WG, void, env, i32, i64) DEF_HELPER_FLAGS_1(clz, TCG_CALL_NO_RWG_SE, tl, tl) DEF_HELPER_FLAGS_1(ctz, TCG_CALL_NO_RWG_SE, tl, tl) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 08d6444741..87ab969ae1 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -13,6 +13,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include <sys/ioctl.h> #include <sys/mman.h> #include <sys/utsname.h> diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c index 5fbab8fd0c..e31ec976a4 100644 --- a/target-i386/misc_helper.c +++ b/target-i386/misc_helper.c @@ -609,3 +609,30 @@ void helper_debug(CPUX86State *env) cs->exception_index = EXCP_DEBUG; cpu_loop_exit(cs); } + +uint64_t helper_rdpkru(CPUX86State *env, uint32_t ecx) +{ + if ((env->cr[4] & CR4_PKE_MASK) == 0) { + raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); + } + if (ecx != 0) { + raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); + } + + return env->pkru; +} + +void helper_wrpkru(CPUX86State *env, uint32_t ecx, uint64_t val) +{ + CPUState *cs = CPU(x86_env_get_cpu(env)); + + if ((env->cr[4] & CR4_PKE_MASK) == 0) { + raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); + } + if (ecx != 0 || (val & 0xFFFFFFFF00000000ull)) { + raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); + } + + env->pkru = val; + tlb_flush(cs, 1); +} diff --git a/target-i386/translate.c b/target-i386/translate.c index dd8d5cc360..1a1214dcb1 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -7322,7 +7322,23 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, } gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); break; - + case 0xee: /* rdpkru */ + if (prefixes & PREFIX_LOCK) { + goto illegal_op; + } + tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]); + gen_helper_rdpkru(cpu_tmp1_i64, cpu_env, cpu_tmp2_i32); + tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_tmp1_i64); + break; + case 0xef: /* wrpkru */ + if (prefixes & PREFIX_LOCK) { + goto illegal_op; + } + tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX], + cpu_regs[R_EDX]); + tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]); + gen_helper_wrpkru(cpu_env, cpu_tmp2_i32, cpu_tmp1_i64); + break; CASE_MODRM_OP(6): /* lmsw */ if (s->cpl != 0) { gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index f93bb5d0dd..6e7e1b8e63 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index 6de74bf28e..0b5f9a581e 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" #include "migration/vmstate.h" diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index 7a42897a00..fdfb01917f 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -22,6 +22,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" #include "hw/qdev-properties.h" diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 7dc3a44a15..0e2ecbebec 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "kvm_mips.h" #include "qemu-common.h" diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 1e2b070cc3..4f3ebb9dbb 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -99,6 +99,7 @@ struct CPUMIPSFPUContext { uint32_t fcr0; #define FCR0_FREP 29 #define FCR0_UFRP 28 +#define FCR0_HAS2008 23 #define FCR0_F64 22 #define FCR0_L 21 #define FCR0_W 20 @@ -110,6 +111,8 @@ struct CPUMIPSFPUContext { #define FCR0_REV 0 /* fcsr */ uint32_t fcr31; +#define FCR31_ABS2008 19 +#define FCR31_NAN2008 18 #define SET_FP_COND(num,env) do { ((env).fcr31) |= ((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0) #define CLEAR_FP_COND(num,env) do { ((env).fcr31) &= ~((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0) #define GET_FP_COND(env) ((((env).fcr31 >> 24) & 0xfe) | (((env).fcr31 >> 23) & 0x1)) diff --git a/target-mips/translate.c b/target-mips/translate.c index 12ed8208d0..0f43bf4758 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -20012,6 +20012,7 @@ void cpu_state_reset(CPUMIPSState *env) env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask; env->CP0_PageGrain = env->cpu_model->CP0_PageGrain; env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0; + env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31; env->msair = env->cpu_model->MSAIR; env->insn_flags = env->cpu_model->insn_flags; diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index cdef59d952..3192db0960 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -84,6 +84,7 @@ struct mips_def_t { int32_t CP0_TCStatus_rw_bitmask; int32_t CP0_SRSCtl; int32_t CP1_fcr0; + int32_t CP1_fcr31; int32_t MSAIR; int32_t SEGBITS; int32_t PABITS; @@ -421,9 +422,10 @@ static const mips_def_t mips_defs[] = .CP0_Status_rw_bitmask = 0x3C68FF1F, .CP0_PageGrain_rw_bitmask = (1U << CP0PG_RIE) | (1 << CP0PG_XIE) | (1 << CP0PG_ELPA) | (1 << CP0PG_IEC), - .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_UFRP) | (1 << FCR0_F64) | - (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | - (1 << FCR0_S) | (0x03 << FCR0_PRID), + .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_UFRP) | (1 << FCR0_HAS2008) | + (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | + (1 << FCR0_D) | (1 << FCR0_S) | (0x03 << FCR0_PRID), + .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), .SEGBITS = 32, .PABITS = 40, .insn_flags = CPU_MIPS32R5 | ASE_MSA, @@ -458,9 +460,10 @@ static const mips_def_t mips_defs[] = .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) | (1U << CP0PG_RIE), .CP0_PageGrain_rw_bitmask = 0, - .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_F64) | (1 << FCR0_L) | - (1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) | - (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), + .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) | + (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | + (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), + .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), .SEGBITS = 32, .PABITS = 32, .insn_flags = CPU_MIPS32R6 | ASE_MICROMIPS, @@ -677,9 +680,10 @@ static const mips_def_t mips_defs[] = .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) | (1U << CP0PG_RIE), .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA), - .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_F64) | (1 << FCR0_L) | - (1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) | - (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), + .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) | + (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | + (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), + .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), .SEGBITS = 48, .PABITS = 48, .insn_flags = CPU_MIPS64R6 | ASE_MSA, diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c index b33c2b3741..b4ee84e906 100644 --- a/target-moxie/cpu.c +++ b/target-moxie/cpu.c @@ -18,6 +18,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" #include "migration/vmstate.h" diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index cafc07f788..ae6ed9e92c 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -18,6 +18,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 8d90d862de..676081e69d 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -474,9 +474,17 @@ struct ppc_slb_t { #define MSR_RI 1 /* Recoverable interrupt 1 */ #define MSR_LE 0 /* Little-endian mode 1 hflags */ -#define LPCR_ILE (1 << (63-38)) -#define LPCR_AIL_SHIFT (63-40) /* Alternate interrupt location */ -#define LPCR_AIL (3 << LPCR_AIL_SHIFT) +/* LPCR bits */ +#define LPCR_VPM0 (1ull << (63 - 0)) +#define LPCR_VPM1 (1ull << (63 - 1)) +#define LPCR_ISL (1ull << (63 - 2)) +#define LPCR_KBV (1ull << (63 - 3)) +#define LPCR_ILE (1ull << (63 - 38)) +#define LPCR_MER (1ull << (63 - 52)) +#define LPCR_LPES0 (1ull << (63 - 60)) +#define LPCR_LPES1 (1ull << (63 - 61)) +#define LPCR_AIL_SHIFT (63 - 40) /* Alternate interrupt location */ +#define LPCR_AIL (3ull << LPCR_AIL_SHIFT) #define msr_sf ((env->msr >> MSR_SF) & 1) #define msr_isf ((env->msr >> MSR_ISF) & 1) @@ -1260,6 +1268,7 @@ void store_booke_tcr (CPUPPCState *env, target_ulong val); void store_booke_tsr (CPUPPCState *env, target_ulong val); void ppc_tlb_invalidate_all (CPUPPCState *env); void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr); +void cpu_ppc_set_papr(PowerPCCPU *cpu); #endif #endif @@ -1346,11 +1355,14 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch) #define SPR_SRR1 (0x01B) #define SPR_CFAR (0x01C) #define SPR_AMR (0x01D) +#define SPR_ACOP (0x01F) #define SPR_BOOKE_PID (0x030) +#define SPR_BOOKS_PID (0x030) #define SPR_BOOKE_DECAR (0x036) #define SPR_BOOKE_CSRR0 (0x03A) #define SPR_BOOKE_CSRR1 (0x03B) #define SPR_BOOKE_DEAR (0x03D) +#define SPR_IAMR (0x03D) #define SPR_BOOKE_ESR (0x03E) #define SPR_BOOKE_IVPR (0x03F) #define SPR_MPC_EIE (0x050) @@ -1381,6 +1393,11 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch) #define SPR_MPC_ICTRL (0x09E) #define SPR_MPC_BAR (0x09F) #define SPR_PSPB (0x09F) +#define SPR_DAWR (0x0B4) +#define SPR_RPR (0x0BA) +#define SPR_CIABR (0x0BB) +#define SPR_DAWRX (0x0BC) +#define SPR_HFSCR (0x0BE) #define SPR_VRSAVE (0x100) #define SPR_USPRG0 (0x100) #define SPR_USPRG1 (0x101) @@ -1435,19 +1452,25 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch) #define SPR_HSRR1 (0x13B) #define SPR_BOOKE_IAC4 (0x13B) #define SPR_BOOKE_DAC1 (0x13C) -#define SPR_LPIDR (0x13D) +#define SPR_MMCRH (0x13C) #define SPR_DABR2 (0x13D) #define SPR_BOOKE_DAC2 (0x13D) +#define SPR_TFMR (0x13D) #define SPR_BOOKE_DVC1 (0x13E) #define SPR_LPCR (0x13E) #define SPR_BOOKE_DVC2 (0x13F) +#define SPR_LPIDR (0x13F) #define SPR_BOOKE_TSR (0x150) +#define SPR_HMER (0x150) +#define SPR_HMEER (0x151) #define SPR_PCR (0x152) +#define SPR_BOOKE_LPIDR (0x152) #define SPR_BOOKE_TCR (0x154) #define SPR_BOOKE_TLB0PS (0x158) #define SPR_BOOKE_TLB1PS (0x159) #define SPR_BOOKE_TLB2PS (0x15A) #define SPR_BOOKE_TLB3PS (0x15B) +#define SPR_AMOR (0x15D) #define SPR_BOOKE_MAS7_MAS3 (0x174) #define SPR_BOOKE_IVOR0 (0x190) #define SPR_BOOKE_IVOR1 (0x191) @@ -1666,7 +1689,9 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch) #define SPR_MPC_MD_DBRAM1 (0x32A) #define SPR_RCPU_L2U_RA3 (0x32B) #define SPR_TAR (0x32F) +#define SPR_IC (0x350) #define SPR_VTB (0x351) +#define SPR_MMCRC (0x353) #define SPR_440_INV0 (0x370) #define SPR_440_INV1 (0x371) #define SPR_440_INV2 (0x372) @@ -1683,6 +1708,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch) #define SPR_POWER_SPMC1 (0x37C) #define SPR_POWER_SPMC2 (0x37D) #define SPR_POWER_MMCRS (0x37E) +#define SPR_WORT (0x37F) #define SPR_PPR (0x380) #define SPR_750_GQR0 (0x390) #define SPR_440_DNV0 (0x390) @@ -1705,6 +1731,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch) #define SPR_440_DVLIM (0x398) #define SPR_750_WPAR (0x399) #define SPR_440_IVLIM (0x399) +#define SPR_TSCR (0x399) #define SPR_750_DMAU (0x39A) #define SPR_750_DMAL (0x39B) #define SPR_440_RSTCFG (0x39B) @@ -1879,9 +1906,10 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch) #define L1CSR1_ICE 0x00000001 /* Instruction Cache Enable */ /* HID0 bits */ -#define HID0_DEEPNAP (1 << 24) -#define HID0_DOZE (1 << 23) -#define HID0_NAP (1 << 22) +#define HID0_DEEPNAP (1 << 24) /* pre-2.06 */ +#define HID0_DOZE (1 << 23) /* pre-2.06 */ +#define HID0_NAP (1 << 22) /* pre-2.06 */ +#define HID0_HILE (1ull << (63 - 19)) /* POWER8 */ /*****************************************************************************/ /* PowerPC Instructions types definitions */ @@ -2230,6 +2258,25 @@ enum { PCR_TM_DIS = 1ull << (63-2), /* Trans. memory disable (POWER8) */ }; +/* HMER/HMEER */ +enum { + HMER_MALFUNCTION_ALERT = 1ull << (63 - 0), + HMER_PROC_RECV_DONE = 1ull << (63 - 2), + HMER_PROC_RECV_ERROR_MASKED = 1ull << (63 - 3), + HMER_TFAC_ERROR = 1ull << (63 - 4), + HMER_TFMR_PARITY_ERROR = 1ull << (63 - 5), + HMER_XSCOM_FAIL = 1ull << (63 - 8), + HMER_XSCOM_DONE = 1ull << (63 - 9), + HMER_PROC_RECV_AGAIN = 1ull << (63 - 11), + HMER_WARN_RISE = 1ull << (63 - 14), + HMER_WARN_FALL = 1ull << (63 - 15), + HMER_SCOM_FIR_HMI = 1ull << (63 - 16), + HMER_TRIG_FIR_HMI = 1ull << (63 - 17), + HMER_HYP_RESOURCE_ERR = 1ull << (63 - 20), + HMER_XSCOM_STATUS_MASK = 7ull << (63 - 23), + HMER_XSCOM_STATUS_LSH = (63 - 23), +}; + /*****************************************************************************/ static inline target_ulong cpu_read_xer(CPUPPCState *env) diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 776336b8b4..c4c81467e4 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -42,6 +42,7 @@ #include "exec/gdbstub.h" #include "exec/memattrs.h" #include "sysemu/hostmem.h" +#include "qemu/cutils.h" //#define DEBUG_KVM @@ -333,6 +334,12 @@ static long gethugepagesize(const char *mem_path) return fs.f_bsize; } +/* + * FIXME TOCTTOU: this iterates over memory backends' mem-path, which + * may or may not name the same files / on the same filesystem now as + * when we actually open and map them. Iterate over the file + * descriptors instead, and use qemu_fd_getpagesize(). + */ static int find_max_supported_pagesize(Object *obj, void *opaque) { char *mem_path; @@ -1371,7 +1378,7 @@ void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) /* Always wake up soon in case the interrupt was level based */ timer_mod(idle_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - (get_ticks_per_sec() / 50)); + (NANOSECONDS_PER_SECOND / 50)); } /* We don't know if there are more interrupts pending after this. However, @@ -1831,7 +1838,7 @@ uint32_t kvmppc_get_tbfreq(void) { char line[512]; char *ns; - uint32_t retval = get_ticks_per_sec(); + uint32_t retval = NANOSECONDS_PER_SECOND; if (read_cpuinfo("timebase", line, sizeof(line))) { return retval; @@ -2001,7 +2008,7 @@ int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len) hc[2] = cpu_to_be32(0x48000008); hc[3] = cpu_to_be32(bswap32(0x3860ffff)); - return 0; + return 1; } static inline int kvmppc_enable_hcall(KVMState *s, target_ulong hcall) diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c index d175fdad45..72c4ab5d75 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -18,6 +18,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "exec/helper-proto.h" #include "qemu/error-report.h" diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index fcb2cc5c79..ff217941b5 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -17,6 +17,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "exec/helper-proto.h" #include "sysemu/kvm.h" diff --git a/target-ppc/translate.c b/target-ppc/translate.c index e402ff9203..6f0e7b4fac 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -4282,14 +4282,17 @@ static inline void gen_op_mfspr(DisasContext *ctx) void (*read_cb)(DisasContext *ctx, int gprn, int sprn); uint32_t sprn = SPR(ctx->opcode); -#if !defined(CONFIG_USER_ONLY) - if (ctx->hv) +#if defined(CONFIG_USER_ONLY) + read_cb = ctx->spr_cb[sprn].uea_read; +#else + if (ctx->pr) { + read_cb = ctx->spr_cb[sprn].uea_read; + } else if (ctx->hv) { read_cb = ctx->spr_cb[sprn].hea_read; - else if (!ctx->pr) + } else { read_cb = ctx->spr_cb[sprn].oea_read; - else + } #endif - read_cb = ctx->spr_cb[sprn].uea_read; if (likely(read_cb != NULL)) { if (likely(read_cb != SPR_NOACCESS)) { (*read_cb)(ctx, rD(ctx->opcode), sprn); @@ -4437,14 +4440,17 @@ static void gen_mtspr(DisasContext *ctx) void (*write_cb)(DisasContext *ctx, int sprn, int gprn); uint32_t sprn = SPR(ctx->opcode); -#if !defined(CONFIG_USER_ONLY) - if (ctx->hv) +#if defined(CONFIG_USER_ONLY) + write_cb = ctx->spr_cb[sprn].uea_write; +#else + if (ctx->pr) { + write_cb = ctx->spr_cb[sprn].uea_write; + } else if (ctx->hv) { write_cb = ctx->spr_cb[sprn].hea_write; - else if (!ctx->pr) + } else { write_cb = ctx->spr_cb[sprn].oea_write; - else + } #endif - write_cb = ctx->spr_cb[sprn].uea_write; if (likely(write_cb != NULL)) { if (likely(write_cb != SPR_NOACCESS)) { (*write_cb)(ctx, sprn, rS(ctx->opcode)); diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index fb206aff29..0a33597f6b 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -579,17 +579,33 @@ static inline void vscr_init (CPUPPCState *env, uint32_t val) #define spr_register_kvm(env, num, name, uea_read, uea_write, \ oea_read, oea_write, one_reg_id, initial_value) \ _spr_register(env, num, name, uea_read, uea_write, initial_value) +#define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \ + oea_read, oea_write, hea_read, hea_write, \ + one_reg_id, initial_value) \ + _spr_register(env, num, name, uea_read, uea_write, initial_value) #else #if !defined(CONFIG_KVM) #define spr_register_kvm(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, one_reg_id, initial_value) \ + oea_read, oea_write, one_reg_id, initial_value) \ + _spr_register(env, num, name, uea_read, uea_write, \ + oea_read, oea_write, oea_read, oea_write, initial_value) +#define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \ + oea_read, oea_write, hea_read, hea_write, \ + one_reg_id, initial_value) \ _spr_register(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, initial_value) + oea_read, oea_write, hea_read, hea_write, initial_value) #else #define spr_register_kvm(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, one_reg_id, initial_value) \ + oea_read, oea_write, one_reg_id, initial_value) \ + _spr_register(env, num, name, uea_read, uea_write, \ + oea_read, oea_write, oea_read, oea_write, \ + one_reg_id, initial_value) +#define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \ + oea_read, oea_write, hea_read, hea_write, \ + one_reg_id, initial_value) \ _spr_register(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, one_reg_id, initial_value) + oea_read, oea_write, hea_read, hea_write, \ + one_reg_id, initial_value) #endif #endif @@ -598,6 +614,13 @@ static inline void vscr_init (CPUPPCState *env, uint32_t val) spr_register_kvm(env, num, name, uea_read, uea_write, \ oea_read, oea_write, 0, initial_value) +#define spr_register_hv(env, num, name, uea_read, uea_write, \ + oea_read, oea_write, hea_read, hea_write, \ + initial_value) \ + spr_register_kvm_hv(env, num, name, uea_read, uea_write, \ + oea_read, oea_write, hea_read, hea_write, \ + 0, initial_value) + static inline void _spr_register(CPUPPCState *env, int num, const char *name, void (*uea_read)(DisasContext *ctx, int gprn, int sprn), @@ -606,6 +629,8 @@ static inline void _spr_register(CPUPPCState *env, int num, void (*oea_read)(DisasContext *ctx, int gprn, int sprn), void (*oea_write)(DisasContext *ctx, int sprn, int gprn), + void (*hea_read)(DisasContext *opaque, int gprn, int sprn), + void (*hea_write)(DisasContext *opaque, int sprn, int gprn), #endif #if defined(CONFIG_KVM) uint64_t one_reg_id, @@ -633,6 +658,8 @@ static inline void _spr_register(CPUPPCState *env, int num, #if !defined(CONFIG_USER_ONLY) spr->oea_read = oea_read; spr->oea_write = oea_write; + spr->hea_read = hea_read; + spr->hea_write = hea_write; #endif #if defined(CONFIG_KVM) spr->one_reg_id = one_reg_id, @@ -1036,30 +1063,102 @@ static void gen_spr_7xx (CPUPPCState *env) #ifdef TARGET_PPC64 #ifndef CONFIG_USER_ONLY -static void spr_read_uamr (DisasContext *ctx, int gprn, int sprn) +static void spr_write_amr(DisasContext *ctx, int sprn, int gprn) { - gen_load_spr(cpu_gpr[gprn], SPR_AMR); - spr_load_dump_spr(SPR_AMR); -} + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + TCGv t2 = tcg_temp_new(); -static void spr_write_uamr (DisasContext *ctx, int sprn, int gprn) -{ - gen_store_spr(SPR_AMR, cpu_gpr[gprn]); + /* Note, the HV=1 PR=0 case is handled earlier by simply using + * spr_write_generic for HV mode in the SPR table + */ + + /* Build insertion mask into t1 based on context */ + if (ctx->pr) { + gen_load_spr(t1, SPR_UAMOR); + } else { + gen_load_spr(t1, SPR_AMOR); + } + + /* Mask new bits into t2 */ + tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]); + + /* Load AMR and clear new bits in t0 */ + gen_load_spr(t0, SPR_AMR); + tcg_gen_andc_tl(t0, t0, t1); + + /* Or'in new bits and write it out */ + tcg_gen_or_tl(t0, t0, t2); + gen_store_spr(SPR_AMR, t0); spr_store_dump_spr(SPR_AMR); + + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(t2); } -static void spr_write_uamr_pr (DisasContext *ctx, int sprn, int gprn) +static void spr_write_uamor(DisasContext *ctx, int sprn, int gprn) { TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + TCGv t2 = tcg_temp_new(); + + /* Note, the HV=1 case is handled earlier by simply using + * spr_write_generic for HV mode in the SPR table + */ + /* Build insertion mask into t1 based on context */ + gen_load_spr(t1, SPR_AMOR); + + /* Mask new bits into t2 */ + tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]); + + /* Load AMR and clear new bits in t0 */ gen_load_spr(t0, SPR_UAMOR); - tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]); - gen_store_spr(SPR_AMR, t0); - spr_store_dump_spr(SPR_AMR); + tcg_gen_andc_tl(t0, t0, t1); + + /* Or'in new bits and write it out */ + tcg_gen_or_tl(t0, t0, t2); + gen_store_spr(SPR_UAMOR, t0); + spr_store_dump_spr(SPR_UAMOR); + + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(t2); +} + +static void spr_write_iamr(DisasContext *ctx, int sprn, int gprn) +{ + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + TCGv t2 = tcg_temp_new(); + + /* Note, the HV=1 case is handled earlier by simply using + * spr_write_generic for HV mode in the SPR table + */ + + /* Build insertion mask into t1 based on context */ + gen_load_spr(t1, SPR_AMOR); + + /* Mask new bits into t2 */ + tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]); + + /* Load AMR and clear new bits in t0 */ + gen_load_spr(t0, SPR_IAMR); + tcg_gen_andc_tl(t0, t0, t1); + + /* Or'in new bits and write it out */ + tcg_gen_or_tl(t0, t0, t2); + gen_store_spr(SPR_IAMR, t0); + spr_store_dump_spr(SPR_IAMR); + + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(t2); } #endif /* CONFIG_USER_ONLY */ -static void gen_spr_amr (CPUPPCState *env) +static void gen_spr_amr(CPUPPCState *env, bool has_iamr) { #ifndef CONFIG_USER_ONLY /* Virtual Page Class Key protection */ @@ -1067,17 +1166,31 @@ static void gen_spr_amr (CPUPPCState *env) * userspace accessible, 29 is privileged. So we only need to set * the kvm ONE_REG id on one of them, we use 29 */ spr_register(env, SPR_UAMR, "UAMR", - &spr_read_uamr, &spr_write_uamr_pr, - &spr_read_uamr, &spr_write_uamr, + &spr_read_generic, &spr_write_amr, + &spr_read_generic, &spr_write_amr, 0); - spr_register_kvm(env, SPR_AMR, "AMR", + spr_register_kvm_hv(env, SPR_AMR, "AMR", SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_amr, &spr_read_generic, &spr_write_generic, KVM_REG_PPC_AMR, 0); - spr_register_kvm(env, SPR_UAMOR, "UAMOR", + spr_register_kvm_hv(env, SPR_UAMOR, "UAMOR", SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_uamor, &spr_read_generic, &spr_write_generic, KVM_REG_PPC_UAMOR, 0); + spr_register_hv(env, SPR_AMOR, "AMOR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0); + if (has_iamr) { + spr_register_kvm_hv(env, SPR_IAMR, "IAMR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_iamr, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_IAMR, 0); + } #endif /* !CONFIG_USER_ONLY */ } #endif /* TARGET_PPC64 */ @@ -7464,6 +7577,25 @@ static void gen_spr_book3s_dbg(CPUPPCState *env) KVM_REG_PPC_DABRX, 0x00000000); } +static void gen_spr_book3s_207_dbg(CPUPPCState *env) +{ + spr_register_kvm_hv(env, SPR_DAWR, "DAWR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DAWR, 0x00000000); + spr_register_kvm_hv(env, SPR_DAWRX, "DAWRX", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DAWRX, 0x00000000); + spr_register_kvm_hv(env, SPR_CIABR, "CIABR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_CIABR, 0x00000000); +} + static void gen_spr_970_dbg(CPUPPCState *env) { /* Breakpoints */ @@ -7878,6 +8010,36 @@ static void gen_spr_power8_pspb(CPUPPCState *env) KVM_REG_PPC_PSPB, 0); } +static void gen_spr_power8_ic(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + spr_register_hv(env, SPR_IC, "IC", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0); +#endif +} + +static void gen_spr_power8_book4(CPUPPCState *env) +{ + /* Add a number of P8 book4 registers */ +#if !defined(CONFIG_USER_ONLY) + spr_register_kvm(env, SPR_ACOP, "ACOP", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_ACOP, 0); + spr_register_kvm(env, SPR_BOOKS_PID, "PID", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PID, 0); + spr_register_kvm(env, SPR_WORT, "WORT", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_WORT, 0); +#endif +} + static void init_proc_book3s_64(CPUPPCState *env, int version) { gen_spr_ne_601(env); @@ -7899,7 +8061,7 @@ static void init_proc_book3s_64(CPUPPCState *env, int version) case BOOK3S_CPU_POWER7: case BOOK3S_CPU_POWER8: gen_spr_book3s_ids(env); - gen_spr_amr(env); + gen_spr_amr(env, version >= BOOK3S_CPU_POWER8); gen_spr_book3s_purr(env); env->ci_large_pages = true; break; @@ -7930,9 +8092,13 @@ static void init_proc_book3s_64(CPUPPCState *env, int version) gen_spr_power8_tm(env); gen_spr_power8_pspb(env); gen_spr_vtb(env); + gen_spr_power8_ic(env); + gen_spr_power8_book4(env); } if (version < BOOK3S_CPU_POWER8) { gen_spr_book3s_dbg(env); + } else { + gen_spr_book3s_207_dbg(env); } #if !defined(CONFIG_USER_ONLY) switch (version) { @@ -8332,8 +8498,33 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) pcc->l1_icache_size = 0x8000; pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr; } -#endif /* defined (TARGET_PPC64) */ +#if !defined(CONFIG_USER_ONLY) + +void cpu_ppc_set_papr(PowerPCCPU *cpu) +{ + CPUPPCState *env = &cpu->env; + ppc_spr_t *amor = &env->spr_cb[SPR_AMOR]; + + /* PAPR always has exception vectors in RAM not ROM. To ensure this, + * MSR[IP] should never be set. + * + * We also disallow setting of MSR_HV + */ + env->msr_mask &= ~((1ull << MSR_EP) | MSR_HVB); + + /* Set a full AMOR so guest can use the AMR as it sees fit */ + env->spr[SPR_AMOR] = amor->default_value = 0xffffffffffffffffull; + + /* Tell KVM that we're in PAPR mode */ + if (kvm_enabled()) { + kvmppc_set_papr(cpu); + } +} + +#endif /* !defined(CONFIG_USER_ONLY) */ + +#endif /* defined (TARGET_PPC64) */ /*****************************************************************************/ /* Generic CPU instantiation routine */ @@ -9703,7 +9894,7 @@ static void ppc_cpu_reset(CPUState *s) #if defined(TARGET_PPC64) if (env->mmu_model & POWERPC_MMU_64) { - env->msr |= (1ULL << MSR_SF); + msr |= (1ULL << MSR_SF); } #endif diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index 1cbf70355d..4bfff341dc 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -24,8 +24,10 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" +#include "qemu/cutils.h" #include "qemu/timer.h" #include "qemu/error-report.h" #include "hw/hw.h" diff --git a/target-s390x/helper.c b/target-s390x/helper.c index 76d5fbebe8..92abe7e676 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "exec/gdbstub.h" #include "qemu/timer.h" diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index 8621d70d4d..86ba38808b 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -20,6 +20,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" #include "migration/vmstate.h" diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index ce903f8dfd..fe4119e2bc 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -18,6 +18,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu/error-report.h" diff --git a/target-tilegx/cpu.c b/target-tilegx/cpu.c index eceeb2c997..d2d0912034 100644 --- a/target-tilegx/cpu.c +++ b/target-tilegx/cpu.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" #include "hw/qdev-properties.h" diff --git a/target-tricore/Makefile.objs b/target-tricore/Makefile.objs index 21e820d8f9..7a05670718 100644 --- a/target-tricore/Makefile.objs +++ b/target-tricore/Makefile.objs @@ -1 +1 @@ -obj-y += translate.o helper.o cpu.o op_helper.o +obj-y += translate.o helper.o cpu.o op_helper.o fpu_helper.o diff --git a/target-tricore/cpu.c b/target-tricore/cpu.c index f8b8518558..69fca8c068 100644 --- a/target-tricore/cpu.c +++ b/target-tricore/cpu.c @@ -18,6 +18,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h index 5fee376674..90045a93d2 100644 --- a/target-tricore/cpu.h +++ b/target-tricore/cpu.h @@ -183,8 +183,7 @@ struct CPUTriCoreState { uint32_t M2CNT; uint32_t M3CNT; /* Floating Point Registers */ - /* XXX: */ - + float_status fp_status; /* QEMU */ int error_code; uint32_t hflags; /* CPU State */ @@ -217,6 +216,7 @@ struct CPUTriCoreState { #define MASK_PSW_GW 0x00000100 #define MASK_PSW_CDE 0x00000080 #define MASK_PSW_CDC 0x0000007f +#define MASK_PSW_FPU_RM 0x3000000 #define MASK_SYSCON_PRO_TEN 0x2 #define MASK_SYSCON_FCD_SF 0x1 @@ -339,6 +339,8 @@ enum { uint32_t psw_read(CPUTriCoreState *env); void psw_write(CPUTriCoreState *env, uint32_t val); +void fpu_set_state(CPUTriCoreState *env); + #include "cpu-qom.h" #define MMU_USER_IDX 2 diff --git a/target-tricore/fpu_helper.c b/target-tricore/fpu_helper.c new file mode 100644 index 0000000000..98fe9472b1 --- /dev/null +++ b/target-tricore/fpu_helper.c @@ -0,0 +1,217 @@ +/* + * TriCore emulation for qemu: fpu helper. + * + * Copyright (c) 2016 Bastian Koppelmann University of Paderborn + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/helper-proto.h" + +#define ADD_NAN 0x7cf00001 +#define DIV_NAN 0x7fc00008 +#define MUL_NAN 0x7fc00002 +#define FPU_FS PSW_USB_C +#define FPU_FI PSW_USB_V +#define FPU_FV PSW_USB_SV +#define FPU_FZ PSW_USB_AV +#define FPU_FU PSW_USB_SAV + +/* we don't care about input_denormal */ +static inline uint8_t f_get_excp_flags(CPUTriCoreState *env) +{ + return get_float_exception_flags(&env->fp_status) + & (float_flag_invalid + | float_flag_overflow + | float_flag_underflow + | float_flag_output_denormal + | float_flag_divbyzero + | float_flag_inexact); +} + +static inline bool f_is_denormal(float32 arg) +{ + return float32_is_zero_or_denormal(arg) && !float32_is_zero(arg); +} + +static void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags) +{ + uint8_t some_excp = 0; + set_float_exception_flags(0, &env->fp_status); + + if (flags & float_flag_invalid) { + env->FPU_FI = 1 << 31; + some_excp = 1; + } + + if (flags & float_flag_overflow) { + env->FPU_FV = 1 << 31; + some_excp = 1; + } + + if (flags & float_flag_underflow || flags & float_flag_output_denormal) { + env->FPU_FU = 1 << 31; + some_excp = 1; + } + + if (flags & float_flag_divbyzero) { + env->FPU_FZ = 1 << 31; + some_excp = 1; + } + + if (flags & float_flag_inexact || flags & float_flag_output_denormal) { + env->PSW |= 1 << 26; + some_excp = 1; + } + + env->FPU_FS = some_excp; +} + +#define FADD_SUB(op) \ +uint32_t helper_f##op(CPUTriCoreState *env, uint32_t r1, uint32_t r2) \ +{ \ + float32 arg1 = make_float32(r1); \ + float32 arg2 = make_float32(r2); \ + uint32_t flags; \ + float32 f_result; \ + \ + f_result = float32_##op(arg2, arg1, &env->fp_status); \ + flags = f_get_excp_flags(env); \ + if (flags) { \ + /* If the output is a NaN, but the inputs aren't, \ + we return a unique value. */ \ + if ((flags & float_flag_invalid) \ + && !float32_is_any_nan(arg1) \ + && !float32_is_any_nan(arg2)) { \ + f_result = ADD_NAN; \ + } \ + f_update_psw_flags(env, flags); \ + } else { \ + env->FPU_FS = 0; \ + } \ + return (uint32_t)f_result; \ +} +FADD_SUB(add) +FADD_SUB(sub) + +uint32_t helper_fmul(CPUTriCoreState *env, uint32_t r1, uint32_t r2) +{ + uint32_t flags; + float32 arg1 = make_float32(r1); + float32 arg2 = make_float32(r2); + float32 f_result; + + f_result = float32_mul(arg1, arg2, &env->fp_status); + + flags = f_get_excp_flags(env); + if (flags) { + /* If the output is a NaN, but the inputs aren't, + we return a unique value. */ + if ((flags & float_flag_invalid) + && !float32_is_any_nan(arg1) + && !float32_is_any_nan(arg2)) { + f_result = MUL_NAN; + } + f_update_psw_flags(env, flags); + } else { + env->FPU_FS = 0; + } + return (uint32_t)f_result; + +} + +uint32_t helper_fdiv(CPUTriCoreState *env, uint32_t r1, uint32_t r2) +{ + uint32_t flags; + float32 arg1 = make_float32(r1); + float32 arg2 = make_float32(r2); + float32 f_result; + + f_result = float32_div(arg1, arg2 , &env->fp_status); + + flags = f_get_excp_flags(env); + if (flags) { + /* If the output is a NaN, but the inputs aren't, + we return a unique value. */ + if ((flags & float_flag_invalid) + && !float32_is_any_nan(arg1) + && !float32_is_any_nan(arg2)) { + f_result = DIV_NAN; + } + f_update_psw_flags(env, flags); + } else { + env->FPU_FS = 0; + } + + return (uint32_t)f_result; +} + +uint32_t helper_fcmp(CPUTriCoreState *env, uint32_t r1, uint32_t r2) +{ + uint32_t result, flags; + float32 arg1 = make_float32(r1); + float32 arg2 = make_float32(r2); + + set_flush_inputs_to_zero(0, &env->fp_status); + + result = 1 << (float32_compare_quiet(arg1, arg2, &env->fp_status) + 1); + result |= f_is_denormal(arg1) << 4; + result |= f_is_denormal(arg2) << 5; + + flags = f_get_excp_flags(env); + if (flags) { + f_update_psw_flags(env, flags); + } else { + env->FPU_FS = 0; + } + + set_flush_inputs_to_zero(1, &env->fp_status); + return result; +} + +uint32_t helper_ftoi(CPUTriCoreState *env, uint32_t arg) +{ + float32 f_arg = make_float32(arg); + int32_t result, flags; + + result = float32_to_int32(f_arg, &env->fp_status); + + flags = f_get_excp_flags(env); + if (flags) { + if (float32_is_any_nan(f_arg)) { + result = 0; + } + f_update_psw_flags(env, flags); + } else { + env->FPU_FS = 0; + } + return (uint32_t)result; +} + +uint32_t helper_itof(CPUTriCoreState *env, uint32_t arg) +{ + float32 f_result; + uint32_t flags; + f_result = int32_to_float32(arg, &env->fp_status); + + flags = f_get_excp_flags(env); + if (flags) { + f_update_psw_flags(env, flags); + } else { + env->FPU_FS = 0; + } + return (uint32_t)f_result; +} diff --git a/target-tricore/helper.c b/target-tricore/helper.c index 7d96daddb1..71b31cdb9b 100644 --- a/target-tricore/helper.c +++ b/target-tricore/helper.c @@ -110,10 +110,18 @@ void tricore_cpu_list(FILE *f, fprintf_function cpu_fprintf) g_slist_free(list); } +void fpu_set_state(CPUTriCoreState *env) +{ + set_float_rounding_mode(env->PSW & MASK_PSW_FPU_RM, &env->fp_status); + set_flush_inputs_to_zero(1, &env->fp_status); + set_flush_to_zero(1, &env->fp_status); + set_default_nan_mode(1, &env->fp_status); +} + uint32_t psw_read(CPUTriCoreState *env) { /* clear all USB bits */ - env->PSW &= 0xffffff; + env->PSW &= 0x6ffffff; /* now set them from the cache */ env->PSW |= ((env->PSW_USB_C != 0) << 31); env->PSW |= ((env->PSW_USB_V & (1 << 31)) >> 1); @@ -132,4 +140,6 @@ void psw_write(CPUTriCoreState *env, uint32_t val) env->PSW_USB_AV = (val & MASK_USB_AV) << 3; env->PSW_USB_SAV = (val & MASK_USB_SAV) << 4; env->PSW = val; + + fpu_set_state(env); } diff --git a/target-tricore/helper.h b/target-tricore/helper.h index 2c8ed78940..9333e161ab 100644 --- a/target-tricore/helper.h +++ b/target-tricore/helper.h @@ -105,6 +105,13 @@ DEF_HELPER_FLAGS_1(parity, TCG_CALL_NO_RWG_SE, i32, i32) /* float */ DEF_HELPER_FLAGS_4(pack, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32) DEF_HELPER_1(unpack, i64, i32) +DEF_HELPER_3(fadd, i32, env, i32, i32) +DEF_HELPER_3(fsub, i32, env, i32, i32) +DEF_HELPER_3(fmul, i32, env, i32, i32) +DEF_HELPER_3(fdiv, i32, env, i32, i32) +DEF_HELPER_3(fcmp, i32, env, i32, i32) +DEF_HELPER_2(ftoi, i32, env, i32) +DEF_HELPER_2(itof, i32, env, i32) /* dvinit */ DEF_HELPER_3(dvinit_b_13, i64, env, i32, i32) DEF_HELPER_3(dvinit_b_131, i64, env, i32, i32) diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c index 55f6724da8..40656c357c 100644 --- a/target-tricore/op_helper.c +++ b/target-tricore/op_helper.c @@ -1045,6 +1045,8 @@ uint64_t helper_msub64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2, } else { result = INT64_MIN; } + } else { + env->PSW_USB_V = 0; } } else { if (ovf < 0) { diff --git a/target-tricore/translate.c b/target-tricore/translate.c index d13e5c8c62..912bf226be 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -6672,6 +6672,21 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; + case OPC2_32_RR_MUL_F: + gen_helper_fmul(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC2_32_RR_DIV_F: + gen_helper_fdiv(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC2_32_RR_CMP_F: + gen_helper_fcmp(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC2_32_RR_FTOI: + gen_helper_ftoi(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]); + break; + case OPC2_32_RR_ITOF: + gen_helper_itof(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]); + break; default: generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } @@ -7013,48 +7028,60 @@ static void decode_rrr_divide(CPUTriCoreState *env, DisasContext *ctx) r3 = MASK_OP_RRR_S3(ctx->opcode); r4 = MASK_OP_RRR_D(ctx->opcode); - CHECK_REG_PAIR(r3); - switch (op2) { case OPC2_32_RRR_DVADJ: + CHECK_REG_PAIR(r3); CHECK_REG_PAIR(r4); GEN_HELPER_RRR(dvadj, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]); break; case OPC2_32_RRR_DVSTEP: + CHECK_REG_PAIR(r3); CHECK_REG_PAIR(r4); GEN_HELPER_RRR(dvstep, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]); break; case OPC2_32_RRR_DVSTEP_U: + CHECK_REG_PAIR(r3); CHECK_REG_PAIR(r4); GEN_HELPER_RRR(dvstep_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]); break; case OPC2_32_RRR_IXMAX: + CHECK_REG_PAIR(r3); CHECK_REG_PAIR(r4); GEN_HELPER_RRR(ixmax, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]); break; case OPC2_32_RRR_IXMAX_U: + CHECK_REG_PAIR(r3); CHECK_REG_PAIR(r4); GEN_HELPER_RRR(ixmax_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]); break; case OPC2_32_RRR_IXMIN: + CHECK_REG_PAIR(r3); CHECK_REG_PAIR(r4); GEN_HELPER_RRR(ixmin, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]); break; case OPC2_32_RRR_IXMIN_U: + CHECK_REG_PAIR(r3); CHECK_REG_PAIR(r4); GEN_HELPER_RRR(ixmin_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]); break; case OPC2_32_RRR_PACK: + CHECK_REG_PAIR(r3); gen_helper_pack(cpu_gpr_d[r4], cpu_PSW_C, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]); break; + case OPC2_32_RRR_ADD_F: + gen_helper_fadd(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r3]); + break; + case OPC2_32_RRR_SUB_F: + gen_helper_fsub(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r3]); + break; default: generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } @@ -8632,6 +8659,7 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) break; case OPCM_32_RRR_DIVIDE: decode_rrr_divide(env, ctx); + break; /* RRR2 Format */ case OPCM_32_RRR2_MADD: decode_rrr2_madd(env, ctx); @@ -8661,6 +8689,7 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) /* RRRR format */ case OPCM_32_RRRR_EXTRACT_INSERT: decode_rrrr_extract_insert(env, ctx); + break; /* RRRW format */ case OPCM_32_RRRW_EXTRACT_INSERT: decode_rrrw_extract_insert(env, ctx); @@ -8771,6 +8800,7 @@ void cpu_state_reset(CPUTriCoreState *env) { /* Reset Regs to Default Value */ env->PSW = 0xb80; + fpu_set_state(env); } static void tricore_tcg_init_csfr(void) diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h index 1bfed0ce48..df666b081f 100644 --- a/target-tricore/tricore-opcodes.h +++ b/target-tricore/tricore-opcodes.h @@ -1126,6 +1126,20 @@ enum { OPC2_32_RR_CRC32 = 0x03, OPC2_32_RR_DIV = 0x20, OPC2_32_RR_DIV_U = 0x21, + OPC2_32_RR_MUL_F = 0x04, + OPC2_32_RR_DIV_F = 0x05, + OPC2_32_RR_FTOI = 0x10, + OPC2_32_RR_ITOF = 0x14, + OPC2_32_RR_CMP_F = 0x00, + OPC2_32_RR_FTOIZ = 0x13, + OPC2_32_RR_FTOQ31 = 0x11, + OPC2_32_RR_FTOQ31Z = 0x18, + OPC2_32_RR_FTOU = 0x12, + OPC2_32_RR_FTOUZ = 0x17, + OPC2_32_RR_Q31TOF = 0x15, + OPC2_32_RR_QSEED_F = 0x19, + OPC2_32_RR_UPDFL = 0x0c, + OPC2_32_RR_UTOF = 0x16, }; /* OPCM_32_RR_IDIRECT */ enum { @@ -1209,6 +1223,10 @@ enum { OPC2_32_RRR_IXMIN = 0x08, OPC2_32_RRR_IXMIN_U = 0x09, OPC2_32_RRR_PACK = 0x00, + OPC2_32_RRR_ADD_F = 0x02, + OPC2_32_RRR_SUB_F = 0x03, + OPC2_32_RRR_MADD_F = 0x06, + OPC2_32_RRR_MSUB_F = 0x07, }; /* * RRR1 Format diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c index c92ccc4251..66f43acfff 100644 --- a/target-unicore32/cpu.c +++ b/target-unicore32/cpu.c @@ -13,6 +13,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" #include "migration/vmstate.h" diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index d572d56795..01b251fdc7 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -29,6 +29,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" #include "migration/vmstate.h" @@ -36,7 +36,7 @@ #define NDEBUG #endif -#include "qemu-common.h" +#include "qemu/cutils.h" #include "qemu/host-utils.h" #include "qemu/timer.h" @@ -2328,7 +2328,7 @@ void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf) #endif -int tcg_gen_code(TCGContext *s, tcg_insn_unit *gen_code_buf) +int tcg_gen_code(TCGContext *s, TranslationBlock *tb) { int i, oi, oi_next, num_insns; @@ -2351,7 +2351,8 @@ int tcg_gen_code(TCGContext *s, tcg_insn_unit *gen_code_buf) #endif #ifdef DEBUG_DISAS - if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) { + if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP) + && qemu_log_in_addr_range(tb->pc))) { qemu_log("OP:\n"); tcg_dump_ops(s); qemu_log("\n"); @@ -2378,7 +2379,8 @@ int tcg_gen_code(TCGContext *s, tcg_insn_unit *gen_code_buf) #endif #ifdef DEBUG_DISAS - if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) { + if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT) + && qemu_log_in_addr_range(tb->pc))) { qemu_log("OP after optimization and liveness analysis:\n"); tcg_dump_ops(s); qemu_log("\n"); @@ -2387,8 +2389,8 @@ int tcg_gen_code(TCGContext *s, tcg_insn_unit *gen_code_buf) tcg_reg_alloc_start(s); - s->code_buf = gen_code_buf; - s->code_ptr = gen_code_buf; + s->code_buf = tb->tc_ptr; + s->code_ptr = tb->tc_ptr; tcg_out_tb_init(s); @@ -636,7 +636,7 @@ void tcg_context_init(TCGContext *s); void tcg_prologue_init(TCGContext *s); void tcg_func_start(TCGContext *s); -int tcg_gen_code(TCGContext *s, tcg_insn_unit *gen_code_buf); +int tcg_gen_code(TCGContext *s, TranslationBlock *tb); void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size); diff --git a/tests/Makefile b/tests/Makefile index 60371ca008..ab185d8647 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -97,6 +97,8 @@ check-unit-y += tests/test-crypto-ivgen$(EXESUF) check-unit-y += tests/test-crypto-afsplit$(EXESUF) check-unit-y += tests/test-crypto-xts$(EXESUF) check-unit-y += tests/test-crypto-block$(EXESUF) +gcov-files-test-logging-y = tests/test-logging.c +check-unit-y += tests/test-logging$(EXESUF) check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh @@ -166,7 +168,7 @@ gcov-files-pci-y += hw/display/virtio-gpu-pci.c gcov-files-pci-$(CONFIG_VIRTIO_VGA) += hw/display/virtio-vga.c check-qtest-pci-y += tests/intel-hda-test$(EXESUF) gcov-files-pci-y += hw/audio/intel-hda.c hw/audio/hda-codec.c -check-qtest-pci-$(CONFIG_POSIX) += tests/ivshmem-test$(EXESUF) +check-qtest-pci-$(CONFIG_EVENTFD) += tests/ivshmem-test$(EXESUF) gcov-files-pci-y += hw/misc/ivshmem.c check-qtest-i386-y = tests/endianness-test$(EXESUF) @@ -436,6 +438,8 @@ tests/test-timed-average$(EXESUF): tests/test-timed-average.o qemu-timer.o \ tests/test-base64$(EXESUF): tests/test-base64.o \ libqemuutil.a libqemustub.a +tests/test-logging$(EXESUF): tests/test-logging.o $(test-util-obj-y) + tests/test-qapi-types.c tests/test-qapi-types.h :\ $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py) $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \ diff --git a/tests/boot-order-test.c b/tests/boot-order-test.c index 210964a00c..a6d8bd5cbf 100644 --- a/tests/boot-order-test.c +++ b/tests/boot-order-test.c @@ -15,9 +15,7 @@ #include "libqos/fw_cfg.h" #include "libqtest.h" -#define NO_QEMU_PROTOS -#include "hw/nvram/fw_cfg.h" -#undef NO_QEMU_PROTOS +#include "hw/nvram/fw_cfg_keys.h" typedef struct { const char *args; diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c index a2bb556906..ffffd872f2 100644 --- a/tests/check-qom-proplist.c +++ b/tests/check-qom-proplist.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include <glib.h> +#include "qapi/error.h" #include "qom/object.h" #include "qemu/module.h" diff --git a/tests/fw_cfg-test.c b/tests/fw_cfg-test.c index 398643aada..b4392c2d38 100644 --- a/tests/fw_cfg-test.c +++ b/tests/fw_cfg-test.c @@ -14,8 +14,7 @@ #include <glib.h> #include "libqtest.h" -#define NO_QEMU_PROTOS -#include "hw/nvram/fw_cfg.h" +#include "hw/nvram/fw_cfg_keys.h" #include "libqos/fw_cfg.h" static uint64_t ram_size = 128 << 20; diff --git a/tests/io-channel-helpers.c b/tests/io-channel-helpers.c index a4dedbe0ad..05e5579cf8 100644 --- a/tests/io-channel-helpers.c +++ b/tests/io-channel-helpers.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "io-channel-helpers.h" +#include "qapi/error.h" struct QIOChannelTest { QIOChannel *src; diff --git a/tests/ivshmem-test.c b/tests/ivshmem-test.c index e184c67a1d..c027ff1e09 100644 --- a/tests/ivshmem-test.c +++ b/tests/ivshmem-test.c @@ -110,25 +110,26 @@ static void setup_vm_cmd(IVState *s, const char *cmd, bool msix) s->pcibus = qpci_init_pc(); s->dev = get_device(s->pcibus); - /* FIXME: other bar order fails, mappings changes */ - s->mem_base = qpci_iomap(s->dev, 2, &barsize); - g_assert_nonnull(s->mem_base); - g_assert_cmpuint(barsize, ==, TMPSHMSIZE); + s->reg_base = qpci_iomap(s->dev, 0, &barsize); + g_assert_nonnull(s->reg_base); + g_assert_cmpuint(barsize, ==, 256); if (msix) { qpci_msix_enable(s->dev); } - s->reg_base = qpci_iomap(s->dev, 0, &barsize); - g_assert_nonnull(s->reg_base); - g_assert_cmpuint(barsize, ==, 256); + s->mem_base = qpci_iomap(s->dev, 2, &barsize); + g_assert_nonnull(s->mem_base); + g_assert_cmpuint(barsize, ==, TMPSHMSIZE); qpci_device_enable(s->dev); } static void setup_vm(IVState *s) { - char *cmd = g_strdup_printf("-device ivshmem,shm=%s,size=1M", tmpshm); + char *cmd = g_strdup_printf("-object memory-backend-file" + ",id=mb1,size=1M,share,mem-path=/dev/shm%s" + " -device ivshmem-plain,memdev=mb1", tmpshm); setup_vm_cmd(s, cmd, false); @@ -144,32 +145,41 @@ static void test_ivshmem_single(void) setup_vm(&state); s = &state; - /* valid io */ - out_reg(s, INTRMASK, 0); - in_reg(s, INTRSTATUS); - in_reg(s, IVPOSITION); + /* initial state of readable registers */ + g_assert_cmpuint(in_reg(s, INTRMASK), ==, 0); + g_assert_cmpuint(in_reg(s, INTRSTATUS), ==, 0); + g_assert_cmpuint(in_reg(s, IVPOSITION), ==, 0); + /* trigger interrupt via registers */ out_reg(s, INTRMASK, 0xffffffff); g_assert_cmpuint(in_reg(s, INTRMASK), ==, 0xffffffff); out_reg(s, INTRSTATUS, 1); - /* XXX: intercept IRQ, not seen in resp */ + /* check interrupt status */ g_assert_cmpuint(in_reg(s, INTRSTATUS), ==, 1); + /* reading clears */ + g_assert_cmpuint(in_reg(s, INTRSTATUS), ==, 0); + /* TODO intercept actual interrupt (needs qtest work) */ - /* invalid io */ + /* invalid register access */ out_reg(s, IVPOSITION, 1); + in_reg(s, DOORBELL); + + /* ring the (non-functional) doorbell */ out_reg(s, DOORBELL, 8 << 16); + /* write shared memory */ for (i = 0; i < G_N_ELEMENTS(data); i++) { data[i] = i; } qtest_memwrite(s->qtest, (uintptr_t)s->mem_base, data, sizeof(data)); + /* verify write */ for (i = 0; i < G_N_ELEMENTS(data); i++) { g_assert_cmpuint(((uint32_t *)tmpshmem)[i], ==, i); } + /* read it back and verify read */ memset(data, 0, sizeof(data)); - qtest_memread(s->qtest, (uintptr_t)s->mem_base, data, sizeof(data)); for (i = 0; i < G_N_ELEMENTS(data); i++) { g_assert_cmpuint(data[i], ==, i); @@ -276,8 +286,10 @@ static void *server_thread(void *data) static void setup_vm_with_server(IVState *s, int nvectors, bool msi) { char *cmd = g_strdup_printf("-chardev socket,id=chr0,path=%s,nowait " - "-device ivshmem,size=1M,chardev=chr0,vectors=%d,msi=%s", - tmpserver, nvectors, msi ? "true" : "false"); + "-device ivshmem%s,chardev=chr0,vectors=%d", + tmpserver, + msi ? "-doorbell" : ",size=1M,msi=off", + nvectors); setup_vm_cmd(s, cmd, msi); @@ -293,8 +305,7 @@ static void test_ivshmem_server(bool msi) int nvectors = 2; guint64 end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND; - memset(tmpshmem, 0x42, TMPSHMSIZE); - ret = ivshmem_server_init(&server, tmpserver, tmpshm, + ret = ivshmem_server_init(&server, tmpserver, tmpshm, true, TMPSHMSIZE, nvectors, g_test_verbose()); g_assert_cmpint(ret, ==, 0); @@ -302,49 +313,39 @@ static void test_ivshmem_server(bool msi) ret = ivshmem_server_start(&server); g_assert_cmpint(ret, ==, 0); - setup_vm_with_server(&state1, nvectors, msi); - s1 = &state1; - setup_vm_with_server(&state2, nvectors, msi); - s2 = &state2; - - g_assert_cmpuint(in_reg(s1, IVPOSITION), ==, 0xffffffff); - g_assert_cmpuint(in_reg(s2, IVPOSITION), ==, 0xffffffff); - - g_assert_cmpuint(qtest_readb(s1->qtest, (uintptr_t)s1->mem_base), ==, 0x00); - thread.server = &server; ret = pipe(thread.pipe); g_assert_cmpint(ret, ==, 0); thread.thread = g_thread_new("ivshmem-server", server_thread, &thread); g_assert(thread.thread != NULL); - /* waiting until mapping is done */ - while (g_get_monotonic_time() < end_time) { - g_usleep(1000); - - if (qtest_readb(s1->qtest, (uintptr_t)s1->mem_base) == 0x42 && - qtest_readb(s2->qtest, (uintptr_t)s2->mem_base) == 0x42) { - break; - } - } + setup_vm_with_server(&state1, nvectors, msi); + s1 = &state1; + setup_vm_with_server(&state2, nvectors, msi); + s2 = &state2; /* check got different VM ids */ vm1 = in_reg(s1, IVPOSITION); vm2 = in_reg(s2, IVPOSITION); - g_assert_cmpuint(vm1, !=, vm2); + g_assert_cmpint(vm1, >=, 0); + g_assert_cmpint(vm2, >=, 0); + g_assert_cmpint(vm1, !=, vm2); + /* check number of MSI-X vectors */ global_qtest = s1->qtest; if (msi) { ret = qpci_msix_table_size(s1->dev); g_assert_cmpuint(ret, ==, nvectors); } - /* ping vm2 -> vm1 */ + /* TODO test behavior before MSI-X is enabled */ + + /* ping vm2 -> vm1 on vector 0 */ if (msi) { ret = qpci_msix_pending(s1->dev, 0); g_assert_cmpuint(ret, ==, 0); } else { - out_reg(s1, INTRSTATUS, 0); + g_assert_cmpuint(in_reg(s1, INTRSTATUS), ==, 0); } out_reg(s2, DOORBELL, vm1 << 16); do { @@ -353,18 +354,18 @@ static void test_ivshmem_server(bool msi) } while (ret == 0 && g_get_monotonic_time() < end_time); g_assert_cmpuint(ret, !=, 0); - /* ping vm1 -> vm2 */ + /* ping vm1 -> vm2 on vector 1 */ global_qtest = s2->qtest; if (msi) { - ret = qpci_msix_pending(s2->dev, 0); + ret = qpci_msix_pending(s2->dev, 1); g_assert_cmpuint(ret, ==, 0); } else { - out_reg(s2, INTRSTATUS, 0); + g_assert_cmpuint(in_reg(s2, INTRSTATUS), ==, 0); } - out_reg(s1, DOORBELL, vm2 << 16); + out_reg(s1, DOORBELL, vm2 << 16 | 1); do { g_usleep(10000); - ret = msi ? qpci_msix_pending(s2->dev, 0) : in_reg(s2, INTRSTATUS); + ret = msi ? qpci_msix_pending(s2->dev, 1) : in_reg(s2, INTRSTATUS); } while (ret == 0 && g_get_monotonic_time() < end_time); g_assert_cmpuint(ret, !=, 0); @@ -415,7 +416,7 @@ static void test_ivshmem_memdev(void) /* just for the sake of checking memory-backend property */ setup_vm_cmd(&state, "-object memory-backend-ram,size=1M,id=mb1" - " -device ivshmem,x-memdev=mb1", false); + " -device ivshmem-plain,memdev=mb1", false); cleanup_vm(&state); } diff --git a/tests/libqos/malloc-pc.c b/tests/libqos/malloc-pc.c index 74f76c59db..eee706bd63 100644 --- a/tests/libqos/malloc-pc.c +++ b/tests/libqos/malloc-pc.c @@ -14,8 +14,7 @@ #include "libqos/malloc-pc.h" #include "libqos/fw_cfg.h" -#define NO_QEMU_PROTOS -#include "hw/nvram/fw_cfg.h" +#include "hw/nvram/fw_cfg_keys.h" #include "qemu-common.h" #include <glib.h> diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c index 08167c09fe..77f15e5a0e 100644 --- a/tests/libqos/pci-pc.c +++ b/tests/libqos/pci-pc.c @@ -184,7 +184,9 @@ static void *qpci_pc_iomap(QPCIBus *bus, QPCIDevice *dev, int barno, uint64_t *s if (io_type == PCI_BASE_ADDRESS_SPACE_IO) { uint16_t loc; - g_assert((s->pci_iohole_alloc + size) <= s->pci_iohole_size); + g_assert(QEMU_ALIGN_UP(s->pci_iohole_alloc, size) + size + <= s->pci_iohole_size); + s->pci_iohole_alloc = QEMU_ALIGN_UP(s->pci_iohole_alloc, size); loc = s->pci_iohole_start + s->pci_iohole_alloc; s->pci_iohole_alloc += size; @@ -194,7 +196,9 @@ static void *qpci_pc_iomap(QPCIBus *bus, QPCIDevice *dev, int barno, uint64_t *s } else { uint64_t loc; - g_assert((s->pci_hole_alloc + size) <= s->pci_hole_size); + g_assert(QEMU_ALIGN_UP(s->pci_hole_alloc, size) + size + <= s->pci_hole_size); + s->pci_hole_alloc = QEMU_ALIGN_UP(s->pci_hole_alloc, size); loc = s->pci_hole_start + s->pci_hole_alloc; s->pci_hole_alloc += size; diff --git a/tests/qom-test.c b/tests/qom-test.c index 3c6cfca788..bd5cdde261 100644 --- a/tests/qom-test.c +++ b/tests/qom-test.c @@ -11,6 +11,7 @@ #include <glib.h> #include "qemu-common.h" +#include "qemu/cutils.h" #include "libqtest.h" #include "qapi/qmp/types.h" diff --git a/tests/tcg/linux-test.c b/tests/tcg/linux-test.c index 1c6c01318e..5070d31446 100644 --- a/tests/tcg/linux-test.c +++ b/tests/tcg/linux-test.c @@ -39,6 +39,7 @@ #include <dirent.h> #include <setjmp.h> #include <sys/shm.h> +#include "qemu/cutils.h" #define TESTPATH "/tmp/linux-test.tmp" #define TESTPORT 7654 diff --git a/tests/tcg/test-i386-fprem.c b/tests/tcg/test-i386-fprem.c index e91fb1ae93..1a71623204 100644 --- a/tests/tcg/test-i386-fprem.c +++ b/tests/tcg/test-i386-fprem.c @@ -22,10 +22,8 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include "qemu/compiler.h" + #include "qemu/osdep.h" -#include <stdio.h> -#include <inttypes.h> /* * Inspired by <ieee754.h>'s union ieee854_long_double, but with single diff --git a/tests/test-aio.c b/tests/test-aio.c index a109bd0c42..687dfa062e 100644 --- a/tests/test-aio.c +++ b/tests/test-aio.c @@ -13,6 +13,7 @@ #include "qemu/osdep.h" #include <glib.h> #include "block/aio.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "qemu/sockets.h" #include "qemu/error-report.h" diff --git a/tests/test-base64.c b/tests/test-base64.c index ae0c107c7d..922e839dd6 100644 --- a/tests/test-base64.c +++ b/tests/test-base64.c @@ -21,9 +21,9 @@ #include "qemu/osdep.h" #include <glib.h> +#include "qapi/error.h" #include "qemu/base64.h" - static void test_base64_good(void) { const char input[] = diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c index c866da66c8..55fad9507a 100644 --- a/tests/test-blockjob-txn.c +++ b/tests/test-blockjob-txn.c @@ -12,6 +12,7 @@ #include "qemu/osdep.h" #include <glib.h> +#include "qapi/error.h" #include "qemu/main-loop.h" #include "block/blockjob.h" diff --git a/tests/test-crypto-afsplit.c b/tests/test-crypto-afsplit.c index ceaac0a06d..f9f2fcd417 100644 --- a/tests/test-crypto-afsplit.c +++ b/tests/test-crypto-afsplit.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "crypto/init.h" #include "crypto/afsplit.h" diff --git a/tests/test-crypto-block.c b/tests/test-crypto-block.c index cdbe09d4ed..a38110d3ff 100644 --- a/tests/test-crypto-block.c +++ b/tests/test-crypto-block.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "crypto/init.h" #include "crypto/block.h" #include "qemu/buffer.h" diff --git a/tests/test-crypto-cipher.c b/tests/test-crypto-cipher.c index e52b741f87..66d1c63fd5 100644 --- a/tests/test-crypto-cipher.c +++ b/tests/test-crypto-cipher.c @@ -23,6 +23,7 @@ #include "crypto/init.h" #include "crypto/cipher.h" +#include "qapi/error.h" typedef struct QCryptoCipherTestData QCryptoCipherTestData; struct QCryptoCipherTestData { diff --git a/tests/test-crypto-ivgen.c b/tests/test-crypto-ivgen.c index 96129da367..a5ff5d3da6 100644 --- a/tests/test-crypto-ivgen.c +++ b/tests/test-crypto-ivgen.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "crypto/ivgen.h" diff --git a/tests/test-crypto-pbkdf.c b/tests/test-crypto-pbkdf.c index bb9c14c110..8ceceb1827 100644 --- a/tests/test-crypto-pbkdf.c +++ b/tests/test-crypto-pbkdf.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "crypto/init.h" #ifndef _WIN32 #include <sys/resource.h> diff --git a/tests/test-crypto-secret.c b/tests/test-crypto-secret.c index 2bbc4d9e3c..aa26c20499 100644 --- a/tests/test-crypto-secret.c +++ b/tests/test-crypto-secret.c @@ -23,6 +23,8 @@ #include "crypto/init.h" #include "crypto/secret.h" +#include "qapi/error.h" +#include "qemu/module.h" static void test_secret_direct(void) { diff --git a/tests/test-crypto-tlscredsx509.c b/tests/test-crypto-tlscredsx509.c index 7ca387db65..af2f80e89c 100644 --- a/tests/test-crypto-tlscredsx509.c +++ b/tests/test-crypto-tlscredsx509.c @@ -22,6 +22,7 @@ #include "crypto-tls-x509-helpers.h" #include "crypto/tlscredsx509.h" +#include "qapi/error.h" #ifdef QCRYPTO_HAVE_TLS_TEST_SUPPORT diff --git a/tests/test-crypto-tlssession.c b/tests/test-crypto-tlssession.c index 036a86b0c3..1a4a066d76 100644 --- a/tests/test-crypto-tlssession.c +++ b/tests/test-crypto-tlssession.c @@ -24,6 +24,7 @@ #include "crypto/tlscredsx509.h" #include "crypto/tlssession.h" #include "qom/object_interfaces.h" +#include "qapi/error.h" #include "qemu/sockets.h" #include "qemu/acl.h" diff --git a/tests/test-cutils.c b/tests/test-cutils.c index 398700df45..fb8f5b5321 100644 --- a/tests/test-cutils.c +++ b/tests/test-cutils.c @@ -28,8 +28,7 @@ #include "qemu/osdep.h" #include <glib.h> -#include "qemu-common.h" - +#include "qemu/cutils.h" static void test_parse_uint_null(void) { diff --git a/tests/test-io-channel-command.c b/tests/test-io-channel-command.c index 885543760a..1d1f461bed 100644 --- a/tests/test-io-channel-command.c +++ b/tests/test-io-channel-command.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "io/channel-command.h" #include "io-channel-helpers.h" +#include "qapi/error.h" #ifndef WIN32 static void test_io_channel_command_fifo(bool async) diff --git a/tests/test-io-channel-file.c b/tests/test-io-channel-file.c index 1e7f3c7f12..6bfede6bb7 100644 --- a/tests/test-io-channel-file.c +++ b/tests/test-io-channel-file.c @@ -22,7 +22,7 @@ #include "io/channel-file.h" #include "io/channel-util.h" #include "io-channel-helpers.h" - +#include "qapi/error.h" static void test_io_channel_file(void) { diff --git a/tests/test-io-channel-socket.c b/tests/test-io-channel-socket.c index be0c3003d4..9d94adb9ac 100644 --- a/tests/test-io-channel-socket.c +++ b/tests/test-io-channel-socket.c @@ -22,6 +22,7 @@ #include "io/channel-socket.h" #include "io/channel-util.h" #include "io-channel-helpers.h" +#include "qapi/error.h" #ifndef AI_ADDRCONFIG # define AI_ADDRCONFIG 0 diff --git a/tests/test-io-task.c b/tests/test-io-task.c index ae46c56a47..5a9775086c 100644 --- a/tests/test-io-task.c +++ b/tests/test-io-task.c @@ -22,6 +22,7 @@ #include <glib.h> #include "io/task.h" +#include "qapi/error.h" #define TYPE_DUMMY "qemu:dummy" diff --git a/tests/test-logging.c b/tests/test-logging.c new file mode 100644 index 0000000000..ac8deedc9a --- /dev/null +++ b/tests/test-logging.c @@ -0,0 +1,141 @@ +/* + * logging unit-tests + * + * Copyright (C) 2016 Linaro Ltd. + * + * Author: Alex Bennée <alex.bennee@linaro.org> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include <glib.h> + +#include "qemu-common.h" +#include "include/qemu/log.h" + +static void test_parse_range(void) +{ + qemu_set_dfilter_ranges("0x1000+0x100"); + + g_assert_false(qemu_log_in_addr_range(0xfff)); + g_assert(qemu_log_in_addr_range(0x1000)); + g_assert(qemu_log_in_addr_range(0x1001)); + g_assert(qemu_log_in_addr_range(0x10ff)); + g_assert_false(qemu_log_in_addr_range(0x1100)); + + qemu_set_dfilter_ranges("0x1000-0x100"); + + g_assert_false(qemu_log_in_addr_range(0x1001)); + g_assert(qemu_log_in_addr_range(0x1000)); + g_assert(qemu_log_in_addr_range(0x0f01)); + g_assert_false(qemu_log_in_addr_range(0x0f00)); + + qemu_set_dfilter_ranges("0x1000..0x1100"); + + g_assert_false(qemu_log_in_addr_range(0xfff)); + g_assert(qemu_log_in_addr_range(0x1000)); + g_assert(qemu_log_in_addr_range(0x1100)); + g_assert_false(qemu_log_in_addr_range(0x1101)); + + qemu_set_dfilter_ranges("0x1000..0x1000"); + + g_assert_false(qemu_log_in_addr_range(0xfff)); + g_assert(qemu_log_in_addr_range(0x1000)); + g_assert_false(qemu_log_in_addr_range(0x1001)); + + qemu_set_dfilter_ranges("0x1000+0x100,0x2100-0x100,0x3000..0x3100"); + g_assert(qemu_log_in_addr_range(0x1050)); + g_assert(qemu_log_in_addr_range(0x2050)); + g_assert(qemu_log_in_addr_range(0x3050)); +} + +#ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS +static void test_parse_invalid_range_subprocess(void) +{ + qemu_set_dfilter_ranges("0x1000+onehundred"); +} +static void test_parse_invalid_range(void) +{ + g_test_trap_subprocess("/logging/parse_invalid_range/subprocess", 0, 0); + g_test_trap_assert_failed(); + g_test_trap_assert_stdout(""); + g_test_trap_assert_stderr("*Failed to parse range in: 0x1000+onehundred\n"); +} +static void test_parse_zero_range_subprocess(void) +{ + qemu_set_dfilter_ranges("0x1000+0"); +} +static void test_parse_zero_range(void) +{ + g_test_trap_subprocess("/logging/parse_zero_range/subprocess", 0, 0); + g_test_trap_assert_failed(); + g_test_trap_assert_stdout(""); + g_test_trap_assert_stderr("*Failed to parse range in: 0x1000+0\n"); +} + +/* As the only real failure from a bad log filename path spec is + * reporting to the user we have to use the g_test_trap_subprocess + * mechanism and check no errors reported on stderr. + */ +static void test_parse_path_subprocess(void) +{ + /* All these should work without issue */ + qemu_set_log_filename("/tmp/qemu.log"); + qemu_set_log_filename("/tmp/qemu-%d.log"); + qemu_set_log_filename("/tmp/qemu.log.%d"); +} +static void test_parse_path(void) +{ + g_test_trap_subprocess ("/logging/parse_path/subprocess", 0, 0); + g_test_trap_assert_passed(); + g_test_trap_assert_stdout(""); + g_test_trap_assert_stderr(""); +} +static void test_parse_invalid_path_subprocess(void) +{ + qemu_set_log_filename("/tmp/qemu-%d%d.log"); +} +static void test_parse_invalid_path(void) +{ + g_test_trap_subprocess ("/logging/parse_invalid_path/subprocess", 0, 0); + g_test_trap_assert_passed(); + g_test_trap_assert_stdout(""); + g_test_trap_assert_stderr("Bad logfile format: /tmp/qemu-%d%d.log\n"); +} +#endif /* CONFIG_HAS_GLIB_SUBPROCESS_TESTS */ + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/logging/parse_range", test_parse_range); +#ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS + g_test_add_func("/logging/parse_invalid_range/subprocess", test_parse_invalid_range_subprocess); + g_test_add_func("/logging/parse_invalid_range", test_parse_invalid_range); + g_test_add_func("/logging/parse_zero_range/subprocess", test_parse_zero_range_subprocess); + g_test_add_func("/logging/parse_zero_range", test_parse_zero_range); + g_test_add_func("/logging/parse_path", test_parse_path); + g_test_add_func("/logging/parse_path/subprocess", test_parse_path_subprocess); + g_test_add_func("/logging/parse_invalid_path", test_parse_invalid_path); + g_test_add_func("/logging/parse_invalid_path/subprocess", test_parse_invalid_path_subprocess); +#endif + + return g_test_run(); +} diff --git a/tests/test-opts-visitor.c b/tests/test-opts-visitor.c index 297a02d6a2..008e677388 100644 --- a/tests/test-opts-visitor.c +++ b/tests/test-opts-visitor.c @@ -15,6 +15,7 @@ #include "qemu/config-file.h" /* qemu_add_opts() */ #include "qemu/option.h" /* qemu_opts_parse() */ +#include "qapi/error.h" #include "qapi/opts-visitor.h" /* opts_visitor_new() */ #include "test-qapi-visit.h" /* visit_type_UserDefOptions() */ diff --git a/tests/test-qemu-opts.c b/tests/test-qemu-opts.c index 848374e2bd..32abed5ea1 100644 --- a/tests/test-qemu-opts.c +++ b/tests/test-qemu-opts.c @@ -8,6 +8,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qapi/qmp/qstring.h" #include "qemu/config-file.h" diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c index 6a33aa41e5..d71727e272 100644 --- a/tests/test-qmp-input-strict.c +++ b/tests/test-qmp-input-strict.c @@ -15,6 +15,7 @@ #include <glib.h> #include "qemu-common.h" +#include "qapi/error.h" #include "qapi/qmp-input-visitor.h" #include "test-qapi-types.h" #include "test-qapi-visit.h" diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c index 5941e90b35..80527eb850 100644 --- a/tests/test-qmp-input-visitor.c +++ b/tests/test-qmp-input-visitor.c @@ -14,6 +14,7 @@ #include <glib.h> #include "qemu-common.h" +#include "qapi/error.h" #include "qapi/qmp-input-visitor.h" #include "test-qapi-types.h" #include "test-qapi-visit.h" diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c index dc35752969..c70926793a 100644 --- a/tests/test-qmp-output-visitor.c +++ b/tests/test-qmp-output-visitor.c @@ -14,6 +14,7 @@ #include <glib.h> #include "qemu-common.h" +#include "qapi/error.h" #include "qapi/qmp-output-visitor.h" #include "test-qapi-types.h" #include "test-qapi-visit.h" diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c index 4b48ec25d3..9e6906a567 100644 --- a/tests/test-string-input-visitor.c +++ b/tests/test-string-input-visitor.c @@ -14,6 +14,7 @@ #include <glib.h> #include "qemu-common.h" +#include "qapi/error.h" #include "qapi/string-input-visitor.h" #include "test-qapi-types.h" #include "test-qapi-visit.h" diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c index 0beccf98c7..1ecd75b853 100644 --- a/tests/test-string-output-visitor.c +++ b/tests/test-string-output-visitor.c @@ -14,6 +14,7 @@ #include <glib.h> #include "qemu-common.h" +#include "qapi/error.h" #include "qapi/string-output-visitor.h" #include "test-qapi-types.h" #include "test-qapi-visit.h" diff --git a/tests/test-thread-pool.c b/tests/test-thread-pool.c index 40600b40bb..88dc7316b3 100644 --- a/tests/test-thread-pool.c +++ b/tests/test-thread-pool.c @@ -4,6 +4,7 @@ #include "block/aio.h" #include "block/thread-pool.h" #include "block/block.h" +#include "qapi/error.h" #include "qemu/timer.h" #include "qemu/error-report.h" diff --git a/tests/test-throttle.c b/tests/test-throttle.c index 59675fa57b..744a524368 100644 --- a/tests/test-throttle.c +++ b/tests/test-throttle.c @@ -16,6 +16,7 @@ #include <glib.h> #include <math.h> #include "block/aio.h" +#include "qapi/error.h" #include "qemu/throttle.h" #include "qemu/error-report.h" #include "block/throttle-groups.h" diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c index ef4dac5e01..9adbc30a41 100644 --- a/tests/test-visitor-serialization.c +++ b/tests/test-visitor-serialization.c @@ -18,6 +18,7 @@ #include "qemu-common.h" #include "test-qapi-types.h" #include "test-qapi-visit.h" +#include "qapi/error.h" #include "qapi/qmp/types.h" #include "qapi/qmp-input-visitor.h" #include "qapi/qmp-output-visitor.h" diff --git a/tests/test-xbzrle.c b/tests/test-xbzrle.c index abd309d418..49f64195a6 100644 --- a/tests/test-xbzrle.c +++ b/tests/test-xbzrle.c @@ -12,6 +12,7 @@ */ #include "qemu/osdep.h" #include "qemu-common.h" +#include "qemu/cutils.h" #include "include/migration/migration.h" #define PAGE_SIZE 4096 diff --git a/trace/control.c b/trace/control.c index 20d3370bf8..ccddda537f 100644 --- a/trace/control.c +++ b/trace/control.c @@ -9,6 +9,7 @@ #include "qemu/osdep.h" #include "trace/control.h" +#include "qemu/help_option.h" #ifdef CONFIG_TRACE_SIMPLE #include "trace/simple.h" #endif diff --git a/trace/control.h b/trace/control.h index f0fe535804..e2ba6d4de1 100644 --- a/trace/control.h +++ b/trace/control.h @@ -11,7 +11,6 @@ #define TRACE__CONTROL_H #include "qemu-common.h" -#include "qemu/typedefs.h" #include "trace/generated-events.h" diff --git a/trace/qmp.c b/trace/qmp.c index 6320b4b3b1..8aa2660aac 100644 --- a/trace/qmp.c +++ b/trace/qmp.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include "qemu/typedefs.h" #include "qmp-commands.h" #include "trace/control.h" diff --git a/translate-all.c b/translate-all.c index e9f409b762..b4df1ec68f 100644 --- a/translate-all.c +++ b/translate-all.c @@ -1120,7 +1120,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, the tcg optimization currently hidden inside tcg_gen_code. All that should be required is to flush the TBs, allocate a new TB, re-initialize it per above, and re-do the actual code generation. */ - gen_code_size = tcg_gen_code(&tcg_ctx, gen_code_buf); + gen_code_size = tcg_gen_code(&tcg_ctx, tb); if (unlikely(gen_code_size < 0)) { goto buffer_overflow; } @@ -1137,7 +1137,8 @@ TranslationBlock *tb_gen_code(CPUState *cpu, #endif #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) && + qemu_log_in_addr_range(tb->pc)) { qemu_log("OUT: [size=%d]\n", gen_code_size); log_disas(tb->tc_ptr, gen_code_size); qemu_log("\n"); diff --git a/ui/cocoa.m b/ui/cocoa.m index 7063a025c0..691471493f 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -33,6 +33,7 @@ #include "sysemu/sysemu.h" #include "qmp-commands.h" #include "sysemu/blockdev.h" +#include <Carbon/Carbon.h> #ifndef MAC_OS_X_VERSION_10_5 #define MAC_OS_X_VERSION_10_5 1050 @@ -72,178 +73,139 @@ bool stretch_video; NSTextField *pauseLabel; NSArray * supportedImageFileTypes; -// keymap conversion -int keymap[] = -{ -// SdlI macI macH SdlH 104xtH 104xtC sdl - 30, // 0 0x00 0x1e A QZ_a - 31, // 1 0x01 0x1f S QZ_s - 32, // 2 0x02 0x20 D QZ_d - 33, // 3 0x03 0x21 F QZ_f - 35, // 4 0x04 0x23 H QZ_h - 34, // 5 0x05 0x22 G QZ_g - 44, // 6 0x06 0x2c Z QZ_z - 45, // 7 0x07 0x2d X QZ_x - 46, // 8 0x08 0x2e C QZ_c - 47, // 9 0x09 0x2f V QZ_v - 0, // 10 0x0A Undefined - 48, // 11 0x0B 0x30 B QZ_b - 16, // 12 0x0C 0x10 Q QZ_q - 17, // 13 0x0D 0x11 W QZ_w - 18, // 14 0x0E 0x12 E QZ_e - 19, // 15 0x0F 0x13 R QZ_r - 21, // 16 0x10 0x15 Y QZ_y - 20, // 17 0x11 0x14 T QZ_t - 2, // 18 0x12 0x02 1 QZ_1 - 3, // 19 0x13 0x03 2 QZ_2 - 4, // 20 0x14 0x04 3 QZ_3 - 5, // 21 0x15 0x05 4 QZ_4 - 7, // 22 0x16 0x07 6 QZ_6 - 6, // 23 0x17 0x06 5 QZ_5 - 13, // 24 0x18 0x0d = QZ_EQUALS - 10, // 25 0x19 0x0a 9 QZ_9 - 8, // 26 0x1A 0x08 7 QZ_7 - 12, // 27 0x1B 0x0c - QZ_MINUS - 9, // 28 0x1C 0x09 8 QZ_8 - 11, // 29 0x1D 0x0b 0 QZ_0 - 27, // 30 0x1E 0x1b ] QZ_RIGHTBRACKET - 24, // 31 0x1F 0x18 O QZ_o - 22, // 32 0x20 0x16 U QZ_u - 26, // 33 0x21 0x1a [ QZ_LEFTBRACKET - 23, // 34 0x22 0x17 I QZ_i - 25, // 35 0x23 0x19 P QZ_p - 28, // 36 0x24 0x1c ENTER QZ_RETURN - 38, // 37 0x25 0x26 L QZ_l - 36, // 38 0x26 0x24 J QZ_j - 40, // 39 0x27 0x28 ' QZ_QUOTE - 37, // 40 0x28 0x25 K QZ_k - 39, // 41 0x29 0x27 ; QZ_SEMICOLON - 43, // 42 0x2A 0x2b \ QZ_BACKSLASH - 51, // 43 0x2B 0x33 , QZ_COMMA - 53, // 44 0x2C 0x35 / QZ_SLASH - 49, // 45 0x2D 0x31 N QZ_n - 50, // 46 0x2E 0x32 M QZ_m - 52, // 47 0x2F 0x34 . QZ_PERIOD - 15, // 48 0x30 0x0f TAB QZ_TAB - 57, // 49 0x31 0x39 SPACE QZ_SPACE - 41, // 50 0x32 0x29 ` QZ_BACKQUOTE - 14, // 51 0x33 0x0e BKSP QZ_BACKSPACE - 0, // 52 0x34 Undefined - 1, // 53 0x35 0x01 ESC QZ_ESCAPE - 220, // 54 0x36 0xdc E0,5C R GUI QZ_RMETA - 219, // 55 0x37 0xdb E0,5B L GUI QZ_LMETA - 42, // 56 0x38 0x2a L SHFT QZ_LSHIFT - 58, // 57 0x39 0x3a CAPS QZ_CAPSLOCK - 56, // 58 0x3A 0x38 L ALT QZ_LALT - 29, // 59 0x3B 0x1d L CTRL QZ_LCTRL - 54, // 60 0x3C 0x36 R SHFT QZ_RSHIFT - 184,// 61 0x3D 0xb8 E0,38 R ALT QZ_RALT - 157,// 62 0x3E 0x9d E0,1D R CTRL QZ_RCTRL - 0, // 63 0x3F Undefined - 0, // 64 0x40 Undefined - 0, // 65 0x41 Undefined - 0, // 66 0x42 Undefined - 55, // 67 0x43 0x37 KP * QZ_KP_MULTIPLY - 0, // 68 0x44 Undefined - 78, // 69 0x45 0x4e KP + QZ_KP_PLUS - 0, // 70 0x46 Undefined - 69, // 71 0x47 0x45 NUM QZ_NUMLOCK - 0, // 72 0x48 Undefined - 0, // 73 0x49 Undefined - 0, // 74 0x4A Undefined - 181,// 75 0x4B 0xb5 E0,35 KP / QZ_KP_DIVIDE - 152,// 76 0x4C 0x9c E0,1C KP EN QZ_KP_ENTER - 0, // 77 0x4D undefined - 74, // 78 0x4E 0x4a KP - QZ_KP_MINUS - 0, // 79 0x4F Undefined - 0, // 80 0x50 Undefined - 0, // 81 0x51 QZ_KP_EQUALS - 82, // 82 0x52 0x52 KP 0 QZ_KP0 - 79, // 83 0x53 0x4f KP 1 QZ_KP1 - 80, // 84 0x54 0x50 KP 2 QZ_KP2 - 81, // 85 0x55 0x51 KP 3 QZ_KP3 - 75, // 86 0x56 0x4b KP 4 QZ_KP4 - 76, // 87 0x57 0x4c KP 5 QZ_KP5 - 77, // 88 0x58 0x4d KP 6 QZ_KP6 - 71, // 89 0x59 0x47 KP 7 QZ_KP7 - 0, // 90 0x5A Undefined - 72, // 91 0x5B 0x48 KP 8 QZ_KP8 - 73, // 92 0x5C 0x49 KP 9 QZ_KP9 - 0, // 93 0x5D Undefined - 0, // 94 0x5E Undefined - 0, // 95 0x5F Undefined - 63, // 96 0x60 0x3f F5 QZ_F5 - 64, // 97 0x61 0x40 F6 QZ_F6 - 65, // 98 0x62 0x41 F7 QZ_F7 - 61, // 99 0x63 0x3d F3 QZ_F3 - 66, // 100 0x64 0x42 F8 QZ_F8 - 67, // 101 0x65 0x43 F9 QZ_F9 - 0, // 102 0x66 Undefined - 87, // 103 0x67 0x57 F11 QZ_F11 - 0, // 104 0x68 Undefined - 183,// 105 0x69 0xb7 QZ_PRINT - 0, // 106 0x6A Undefined - 70, // 107 0x6B 0x46 SCROLL QZ_SCROLLOCK - 0, // 108 0x6C Undefined - 68, // 109 0x6D 0x44 F10 QZ_F10 - 0, // 110 0x6E Undefined - 88, // 111 0x6F 0x58 F12 QZ_F12 - 0, // 112 0x70 Undefined - 110,// 113 0x71 0x0 QZ_PAUSE - 210,// 114 0x72 0xd2 E0,52 INSERT QZ_INSERT - 199,// 115 0x73 0xc7 E0,47 HOME QZ_HOME - 201,// 116 0x74 0xc9 E0,49 PG UP QZ_PAGEUP - 211,// 117 0x75 0xd3 E0,53 DELETE QZ_DELETE - 62, // 118 0x76 0x3e F4 QZ_F4 - 207,// 119 0x77 0xcf E0,4f END QZ_END - 60, // 120 0x78 0x3c F2 QZ_F2 - 209,// 121 0x79 0xd1 E0,51 PG DN QZ_PAGEDOWN - 59, // 122 0x7A 0x3b F1 QZ_F1 - 203,// 123 0x7B 0xcb e0,4B L ARROW QZ_LEFT - 205,// 124 0x7C 0xcd e0,4D R ARROW QZ_RIGHT - 208,// 125 0x7D 0xd0 E0,50 D ARROW QZ_DOWN - 200,// 126 0x7E 0xc8 E0,48 U ARROW QZ_UP -/* completed according to http://www.libsdl.org/cgi/cvsweb.cgi/SDL12/src/video/quartz/SDL_QuartzKeys.h?rev=1.6&content-type=text/x-cvsweb-markup */ - -/* Additional 104 Key XP-Keyboard Scancodes from http://www.computer-engineering.org/ps2keyboard/scancodes1.html */ -/* - 221 // 0xdd e0,5d APPS - // E0,2A,E0,37 PRNT SCRN - // E1,1D,45,E1,9D,C5 PAUSE - 83 // 0x53 0x53 KP . -// ACPI Scan Codes - 222 // 0xde E0, 5E Power - 223 // 0xdf E0, 5F Sleep - 227 // 0xe3 E0, 63 Wake -// Windows Multimedia Scan Codes - 153 // 0x99 E0, 19 Next Track - 144 // 0x90 E0, 10 Previous Track - 164 // 0xa4 E0, 24 Stop - 162 // 0xa2 E0, 22 Play/Pause - 160 // 0xa0 E0, 20 Mute - 176 // 0xb0 E0, 30 Volume Up - 174 // 0xae E0, 2E Volume Down - 237 // 0xed E0, 6D Media Select - 236 // 0xec E0, 6C E-Mail - 161 // 0xa1 E0, 21 Calculator - 235 // 0xeb E0, 6B My Computer - 229 // 0xe5 E0, 65 WWW Search - 178 // 0xb2 E0, 32 WWW Home - 234 // 0xea E0, 6A WWW Back - 233 // 0xe9 E0, 69 WWW Forward - 232 // 0xe8 E0, 68 WWW Stop - 231 // 0xe7 E0, 67 WWW Refresh - 230 // 0xe6 E0, 66 WWW Favorites -*/ +// Mac to QKeyCode conversion +const int mac_to_qkeycode_map[] = { + [kVK_ANSI_A] = Q_KEY_CODE_A, + [kVK_ANSI_B] = Q_KEY_CODE_B, + [kVK_ANSI_C] = Q_KEY_CODE_C, + [kVK_ANSI_D] = Q_KEY_CODE_D, + [kVK_ANSI_E] = Q_KEY_CODE_E, + [kVK_ANSI_F] = Q_KEY_CODE_F, + [kVK_ANSI_G] = Q_KEY_CODE_G, + [kVK_ANSI_H] = Q_KEY_CODE_H, + [kVK_ANSI_I] = Q_KEY_CODE_I, + [kVK_ANSI_J] = Q_KEY_CODE_J, + [kVK_ANSI_K] = Q_KEY_CODE_K, + [kVK_ANSI_L] = Q_KEY_CODE_L, + [kVK_ANSI_M] = Q_KEY_CODE_M, + [kVK_ANSI_N] = Q_KEY_CODE_N, + [kVK_ANSI_O] = Q_KEY_CODE_O, + [kVK_ANSI_P] = Q_KEY_CODE_P, + [kVK_ANSI_Q] = Q_KEY_CODE_Q, + [kVK_ANSI_R] = Q_KEY_CODE_R, + [kVK_ANSI_S] = Q_KEY_CODE_S, + [kVK_ANSI_T] = Q_KEY_CODE_T, + [kVK_ANSI_U] = Q_KEY_CODE_U, + [kVK_ANSI_V] = Q_KEY_CODE_V, + [kVK_ANSI_W] = Q_KEY_CODE_W, + [kVK_ANSI_X] = Q_KEY_CODE_X, + [kVK_ANSI_Y] = Q_KEY_CODE_Y, + [kVK_ANSI_Z] = Q_KEY_CODE_Z, + + [kVK_ANSI_0] = Q_KEY_CODE_0, + [kVK_ANSI_1] = Q_KEY_CODE_1, + [kVK_ANSI_2] = Q_KEY_CODE_2, + [kVK_ANSI_3] = Q_KEY_CODE_3, + [kVK_ANSI_4] = Q_KEY_CODE_4, + [kVK_ANSI_5] = Q_KEY_CODE_5, + [kVK_ANSI_6] = Q_KEY_CODE_6, + [kVK_ANSI_7] = Q_KEY_CODE_7, + [kVK_ANSI_8] = Q_KEY_CODE_8, + [kVK_ANSI_9] = Q_KEY_CODE_9, + + [kVK_ANSI_Grave] = Q_KEY_CODE_GRAVE_ACCENT, + [kVK_ANSI_Minus] = Q_KEY_CODE_MINUS, + [kVK_ANSI_Equal] = Q_KEY_CODE_EQUAL, + [kVK_Delete] = Q_KEY_CODE_BACKSPACE, + [kVK_CapsLock] = Q_KEY_CODE_CAPS_LOCK, + [kVK_Tab] = Q_KEY_CODE_TAB, + [kVK_Return] = Q_KEY_CODE_RET, + [kVK_ANSI_LeftBracket] = Q_KEY_CODE_BRACKET_LEFT, + [kVK_ANSI_RightBracket] = Q_KEY_CODE_BRACKET_RIGHT, + [kVK_ANSI_Backslash] = Q_KEY_CODE_BACKSLASH, + [kVK_ANSI_Semicolon] = Q_KEY_CODE_SEMICOLON, + [kVK_ANSI_Quote] = Q_KEY_CODE_APOSTROPHE, + [kVK_ANSI_Comma] = Q_KEY_CODE_COMMA, + [kVK_ANSI_Period] = Q_KEY_CODE_DOT, + [kVK_ANSI_Slash] = Q_KEY_CODE_SLASH, + [kVK_Shift] = Q_KEY_CODE_SHIFT, + [kVK_RightShift] = Q_KEY_CODE_SHIFT_R, + [kVK_Control] = Q_KEY_CODE_CTRL, + [kVK_RightControl] = Q_KEY_CODE_CTRL_R, + [kVK_Option] = Q_KEY_CODE_ALT, + [kVK_RightOption] = Q_KEY_CODE_ALT_R, + [kVK_Command] = Q_KEY_CODE_META_L, + [0x36] = Q_KEY_CODE_META_R, /* There is no kVK_RightCommand */ + [kVK_Space] = Q_KEY_CODE_SPC, + + [kVK_ANSI_Keypad0] = Q_KEY_CODE_KP_0, + [kVK_ANSI_Keypad1] = Q_KEY_CODE_KP_1, + [kVK_ANSI_Keypad2] = Q_KEY_CODE_KP_2, + [kVK_ANSI_Keypad3] = Q_KEY_CODE_KP_3, + [kVK_ANSI_Keypad4] = Q_KEY_CODE_KP_4, + [kVK_ANSI_Keypad5] = Q_KEY_CODE_KP_5, + [kVK_ANSI_Keypad6] = Q_KEY_CODE_KP_6, + [kVK_ANSI_Keypad7] = Q_KEY_CODE_KP_7, + [kVK_ANSI_Keypad8] = Q_KEY_CODE_KP_8, + [kVK_ANSI_Keypad9] = Q_KEY_CODE_KP_9, + [kVK_ANSI_KeypadDecimal] = Q_KEY_CODE_KP_DECIMAL, + [kVK_ANSI_KeypadEnter] = Q_KEY_CODE_KP_ENTER, + [kVK_ANSI_KeypadPlus] = Q_KEY_CODE_KP_ADD, + [kVK_ANSI_KeypadMinus] = Q_KEY_CODE_KP_SUBTRACT, + [kVK_ANSI_KeypadMultiply] = Q_KEY_CODE_KP_MULTIPLY, + [kVK_ANSI_KeypadDivide] = Q_KEY_CODE_KP_DIVIDE, + [kVK_ANSI_KeypadEquals] = Q_KEY_CODE_KP_EQUALS, + [kVK_ANSI_KeypadClear] = Q_KEY_CODE_NUM_LOCK, + + [kVK_UpArrow] = Q_KEY_CODE_UP, + [kVK_DownArrow] = Q_KEY_CODE_DOWN, + [kVK_LeftArrow] = Q_KEY_CODE_LEFT, + [kVK_RightArrow] = Q_KEY_CODE_RIGHT, + + [kVK_Help] = Q_KEY_CODE_INSERT, + [kVK_Home] = Q_KEY_CODE_HOME, + [kVK_PageUp] = Q_KEY_CODE_PGUP, + [kVK_PageDown] = Q_KEY_CODE_PGDN, + [kVK_End] = Q_KEY_CODE_END, + [kVK_ForwardDelete] = Q_KEY_CODE_DELETE, + + [kVK_Escape] = Q_KEY_CODE_ESC, + + /* The Power key can't be used directly because the operating system uses + * it. This key can be emulated by using it in place of another key such as + * F1. Don't forget to disable the real key binding. + */ + /* [kVK_F1] = Q_KEY_CODE_POWER, */ + + [kVK_F1] = Q_KEY_CODE_F1, + [kVK_F2] = Q_KEY_CODE_F2, + [kVK_F3] = Q_KEY_CODE_F3, + [kVK_F4] = Q_KEY_CODE_F4, + [kVK_F5] = Q_KEY_CODE_F5, + [kVK_F6] = Q_KEY_CODE_F6, + [kVK_F7] = Q_KEY_CODE_F7, + [kVK_F8] = Q_KEY_CODE_F8, + [kVK_F9] = Q_KEY_CODE_F9, + [kVK_F10] = Q_KEY_CODE_F10, + [kVK_F11] = Q_KEY_CODE_F11, + [kVK_F12] = Q_KEY_CODE_F12, + [kVK_F13] = Q_KEY_CODE_PRINT, + [kVK_F14] = Q_KEY_CODE_SCROLL_LOCK, + [kVK_F15] = Q_KEY_CODE_PAUSE, + + /* + * The eject and volume keys can't be used here because they are handled at + * a lower level than what an Application can see. + */ }; static int cocoa_keycode_to_qemu(int keycode) { - if (ARRAY_SIZE(keymap) <= keycode) { + if (ARRAY_SIZE(mac_to_qkeycode_map) <= keycode) { fprintf(stderr, "(cocoa) warning unknown keycode 0x%x\n", keycode); return 0; } - return keymap[keycode]; + return mac_to_qkeycode_map[keycode]; } /* Displays an alert dialog box with the specified message */ @@ -557,21 +519,24 @@ QemuCocoaView *cocoaView; case NSFlagsChanged: keycode = cocoa_keycode_to_qemu([event keyCode]); - if ((keycode == 219 || keycode == 220) && !isMouseGrabbed) { + if ((keycode == Q_KEY_CODE_META_L || keycode == Q_KEY_CODE_META_R) + && !isMouseGrabbed) { /* Don't pass command key changes to guest unless mouse is grabbed */ keycode = 0; } if (keycode) { - if (keycode == 58 || keycode == 69) { // emulate caps lock and num lock keydown and keyup - qemu_input_event_send_key_number(dcl->con, keycode, true); - qemu_input_event_send_key_number(dcl->con, keycode, false); + // emulate caps lock and num lock keydown and keyup + if (keycode == Q_KEY_CODE_CAPS_LOCK || + keycode == Q_KEY_CODE_NUM_LOCK) { + qemu_input_event_send_key_qcode(dcl->con, keycode, true); + qemu_input_event_send_key_qcode(dcl->con, keycode, false); } else if (qemu_console_is_graphic(NULL)) { if (modifiers_state[keycode] == 0) { // keydown - qemu_input_event_send_key_number(dcl->con, keycode, true); + qemu_input_event_send_key_qcode(dcl->con, keycode, true); modifiers_state[keycode] = 1; } else { // keyup - qemu_input_event_send_key_number(dcl->con, keycode, false); + qemu_input_event_send_key_qcode(dcl->con, keycode, false); modifiers_state[keycode] = 0; } } @@ -598,14 +563,14 @@ QemuCocoaView *cocoaView; switch (keycode) { // enable graphic console - case 0x02 ... 0x0a: // '1' to '9' keys - console_select(keycode - 0x02); + case Q_KEY_CODE_1 ... Q_KEY_CODE_9: // '1' to '9' keys + console_select(keycode - 11); break; } // handle keys for graphic console } else if (qemu_console_is_graphic(NULL)) { - qemu_input_event_send_key_number(dcl->con, keycode, true); + qemu_input_event_send_key_qcode(dcl->con, keycode, true); // handlekeys for Monitor } else { @@ -653,7 +618,7 @@ QemuCocoaView *cocoaView; } if (qemu_console_is_graphic(NULL)) { - qemu_input_event_send_key_number(dcl->con, keycode, false); + qemu_input_event_send_key_qcode(dcl->con, keycode, false); } break; case NSMouseMoved: @@ -823,7 +788,7 @@ QemuCocoaView *cocoaView; for (index = 0; index < max_index; index++) { if (modifiers_state[index]) { modifiers_state[index] = 0; - qemu_input_event_send_key_number(dcl->con, index, false); + qemu_input_event_send_key_qcode(dcl->con, index, false); } } } @@ -858,6 +823,7 @@ QemuCocoaView *cocoaView; - (void)ejectDeviceMedia:(id)sender; - (void)changeDeviceMedia:(id)sender; - (BOOL)verifyQuit; +- (void)openDocumentation:(NSString *)filename; @end @implementation QemuCocoaAppController @@ -994,20 +960,42 @@ QemuCocoaView *cocoaView; [cocoaView toggleFullScreen:sender]; } +/* Tries to find then open the specified filename */ +- (void) openDocumentation: (NSString *) filename +{ + /* Where to look for local files */ + NSString *path_array[] = {@"../share/doc/qemu/", @"../doc/qemu/", @"../"}; + NSString *full_file_path; + + /* iterate thru the possible paths until the file is found */ + int index; + for (index = 0; index < ARRAY_SIZE(path_array); index++) { + full_file_path = [[NSBundle mainBundle] executablePath]; + full_file_path = [full_file_path stringByDeletingLastPathComponent]; + full_file_path = [NSString stringWithFormat: @"%@/%@%@", full_file_path, + path_array[index], filename]; + if ([[NSWorkspace sharedWorkspace] openFile: full_file_path] == YES) { + return; + } + } + + /* If none of the paths opened a file */ + NSBeep(); + QEMU_Alert(@"Failed to open file"); +} + - (void)showQEMUDoc:(id)sender { COCOA_DEBUG("QemuCocoaAppController: showQEMUDoc\n"); - [[NSWorkspace sharedWorkspace] openFile:[NSString stringWithFormat:@"%@/../doc/qemu/qemu-doc.html", - [[NSBundle mainBundle] resourcePath]] withApplication:@"Help Viewer"]; + [self openDocumentation: @"qemu-doc.html"]; } - (void)showQEMUTec:(id)sender { COCOA_DEBUG("QemuCocoaAppController: showQEMUTec\n"); - [[NSWorkspace sharedWorkspace] openFile:[NSString stringWithFormat:@"%@/../doc/qemu/qemu-tech.html", - [[NSBundle mainBundle] resourcePath]] withApplication:@"Help Viewer"]; + [self openDocumentation: @"qemu-tech.html"]; } /* Stretches video to fit host monitor size */ diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c index 54be44ccea..558edfdeb7 100644 --- a/ui/egl-helpers.c +++ b/ui/egl-helpers.c @@ -2,7 +2,6 @@ #include <glob.h> #include <dirent.h> -#include "config-host.h" #include "ui/egl-helpers.h" EGLDisplay *qemu_egl_display; @@ -36,6 +36,7 @@ #include "qemu/osdep.h" #include "qemu-common.h" +#include "qemu/cutils.h" #include "ui/console.h" #include "ui/gtk.h" diff --git a/ui/input-linux.c b/ui/input-linux.c index 2cf5d4990c..9c921cc0ad 100644 --- a/ui/input-linux.c +++ b/ui/input-linux.c @@ -5,11 +5,13 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/config-file.h" #include "qemu/sockets.h" #include "sysemu/sysemu.h" #include "ui/input.h" +#include "qom/object_interfaces.h" #include <sys/ioctl.h> #include "standard-headers/linux/input.h" @@ -127,10 +129,21 @@ static int qemu_input_linux_to_qcode(unsigned int lnx) return linux_to_qcode[lnx]; } +#define TYPE_INPUT_LINUX "input-linux" +#define INPUT_LINUX(obj) \ + OBJECT_CHECK(InputLinux, (obj), TYPE_INPUT_LINUX) +#define INPUT_LINUX_GET_CLASS(obj) \ + OBJECT_GET_CLASS(InputLinuxClass, (obj), TYPE_INPUT_LINUX) +#define INPUT_LINUX_CLASS(klass) \ + OBJECT_CLASS_CHECK(InputLinuxClass, (klass), TYPE_INPUT_LINUX) + typedef struct InputLinux InputLinux; +typedef struct InputLinuxClass InputLinuxClass; struct InputLinux { - const char *evdev; + Object parent; + + char *evdev; int fd; bool repeat; bool grab_request; @@ -139,9 +152,14 @@ struct InputLinux { bool keydown[KEY_CNT]; int keycount; int wheel; + bool initialized; QTAILQ_ENTRY(InputLinux) next; }; +struct InputLinuxClass { + ObjectClass parent_class; +}; + static QTAILQ_HEAD(, InputLinux) inputs = QTAILQ_HEAD_INITIALIZER(inputs); static void input_linux_toggle_grab(InputLinux *il) @@ -196,6 +214,13 @@ static void input_linux_event_keyboard(void *opaque) */ continue; } + if (event.code >= KEY_CNT) { + /* + * Should not happen. But better safe than sorry, + * and we make Coverity happy too. + */ + continue; + } /* keep track of key state */ if (!il->keydown[event.code] && event.value) { il->keydown[event.code] = true; @@ -309,25 +334,21 @@ static void input_linux_event_mouse(void *opaque) } } -int input_linux_init(void *opaque, QemuOpts *opts, Error **errp) +static void input_linux_complete(UserCreatable *uc, Error **errp) { - InputLinux *il = g_new0(InputLinux, 1); + InputLinux *il = INPUT_LINUX(uc); uint32_t evtmap; int rc, ver; - il->evdev = qemu_opt_get(opts, "evdev"); - il->grab_all = qemu_opt_get_bool(opts, "grab-all", false); - il->repeat = qemu_opt_get_bool(opts, "repeat", false); - if (!il->evdev) { error_setg(errp, "no input device specified"); - goto err_free; + return; } il->fd = open(il->evdev, O_RDWR); if (il->fd < 0) { error_setg_file_open(errp, errno, il->evdev); - goto err_free; + return; } qemu_set_nonblock(il->fd); @@ -356,36 +377,111 @@ int input_linux_init(void *opaque, QemuOpts *opts, Error **errp) } input_linux_toggle_grab(il); QTAILQ_INSERT_TAIL(&inputs, il, next); - return 0; + il->initialized = true; + return; err_close: close(il->fd); -err_free: - g_free(il); - return -1; + return; +} + +static void input_linux_instance_finalize(Object *obj) +{ + InputLinux *il = INPUT_LINUX(obj); + + if (il->initialized) { + QTAILQ_REMOVE(&inputs, il, next); + close(il->fd); + } + g_free(il->evdev); +} + +static char *input_linux_get_evdev(Object *obj, Error **errp) +{ + InputLinux *il = INPUT_LINUX(obj); + + return g_strdup(il->evdev); +} + +static void input_linux_set_evdev(Object *obj, const char *value, + Error **errp) +{ + InputLinux *il = INPUT_LINUX(obj); + + if (il->evdev) { + error_setg(errp, "evdev property already set"); + return; + } + il->evdev = g_strdup(value); } -static QemuOptsList qemu_input_linux_opts = { - .name = "input-linux", - .head = QTAILQ_HEAD_INITIALIZER(qemu_input_linux_opts.head), - .implied_opt_name = "evdev", - .desc = { - { - .name = "evdev", - .type = QEMU_OPT_STRING, - },{ - .name = "grab-all", - .type = QEMU_OPT_BOOL, - },{ - .name = "repeat", - .type = QEMU_OPT_BOOL, - }, - { /* end of list */ } - }, +static bool input_linux_get_grab_all(Object *obj, Error **errp) +{ + InputLinux *il = INPUT_LINUX(obj); + + return il->grab_all; +} + +static void input_linux_set_grab_all(Object *obj, bool value, + Error **errp) +{ + InputLinux *il = INPUT_LINUX(obj); + + il->grab_all = value; +} + +static bool input_linux_get_repeat(Object *obj, Error **errp) +{ + InputLinux *il = INPUT_LINUX(obj); + + return il->repeat; +} + +static void input_linux_set_repeat(Object *obj, bool value, + Error **errp) +{ + InputLinux *il = INPUT_LINUX(obj); + + il->repeat = value; +} + +static void input_linux_instance_init(Object *obj) +{ + object_property_add_str(obj, "evdev", + input_linux_get_evdev, + input_linux_set_evdev, NULL); + object_property_add_bool(obj, "grab_all", + input_linux_get_grab_all, + input_linux_set_grab_all, NULL); + object_property_add_bool(obj, "repeat", + input_linux_get_repeat, + input_linux_set_repeat, NULL); +} + +static void input_linux_class_init(ObjectClass *oc, void *data) +{ + UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); + + ucc->complete = input_linux_complete; +} + +static const TypeInfo input_linux_info = { + .name = TYPE_INPUT_LINUX, + .parent = TYPE_OBJECT, + .class_size = sizeof(InputLinuxClass), + .class_init = input_linux_class_init, + .instance_size = sizeof(InputLinux), + .instance_init = input_linux_instance_init, + .instance_finalize = input_linux_instance_finalize, + .interfaces = (InterfaceInfo[]) { + { TYPE_USER_CREATABLE }, + { } + } }; -static void input_linux_register_config(void) +static void register_types(void) { - qemu_add_opts(&qemu_input_linux_opts); + type_register_static(&input_linux_info); } -opts_init(input_linux_register_config); + +type_init(register_types); @@ -30,6 +30,7 @@ #include <SDL_syswm.h> #include "qemu-common.h" +#include "qemu/cutils.h" #include "ui/console.h" #include "ui/input.h" #include "sysemu/sysemu.h" diff --git a/ui/spice-core.c b/ui/spice-core.c index e1179258d0..61db3c18b3 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -828,6 +828,11 @@ void qemu_spice_init(void) #ifdef HAVE_SPICE_GL if (qemu_opt_get_bool(opts, "gl", 0)) { + if ((port != 0) || (tls_port != 0)) { + error_report("SPICE GL support is local-only for now and " + "incompatible with -spice port/tls-port"); + exit(1); + } if (egl_rendernode_init() == 0) { display_opengl = 1; } diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c index 56e45e3473..5ae29c14cf 100644 --- a/ui/vnc-auth-sasl.c +++ b/ui/vnc-auth-sasl.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "vnc.h" /* Max amount of data we send/recv for SASL steps to prevent DOS */ diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c index 8f3bb11cea..11c8c9a819 100644 --- a/ui/vnc-auth-vencrypt.c +++ b/ui/vnc-auth-vencrypt.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "vnc.h" +#include "qapi/error.h" #include "qemu/main-loop.h" static void start_auth_vencrypt_subauth(VncState *vs) diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c index 1d3ecc2330..7c79a4c372 100644 --- a/ui/vnc-ws.c +++ b/ui/vnc-ws.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "vnc.h" #include "io/channel-websock.h" @@ -44,6 +44,7 @@ #include "crypto/tlscredsanon.h" #include "crypto/tlscredsx509.h" #include "qom/object_interfaces.h" +#include "qemu/cutils.h" #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT #define VNC_REFRESH_INTERVAL_INC 50 diff --git a/util/base64.c b/util/base64.c index d4bf2a61f9..9d3c46cbcc 100644 --- a/util/base64.c +++ b/util/base64.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu/base64.h" static const char *base64_valid_chars = diff --git a/util/coroutine-sigaltstack.c b/util/coroutine-sigaltstack.c index 6b8aee7a2b..a7c3366553 100644 --- a/util/coroutine-sigaltstack.c +++ b/util/coroutine-sigaltstack.c @@ -26,7 +26,6 @@ #undef _FORTIFY_SOURCE #endif #include "qemu/osdep.h" -#include <setjmp.h> #include <pthread.h> #include "qemu-common.h" #include "qemu/coroutine_int.h" diff --git a/util/coroutine-ucontext.c b/util/coroutine-ucontext.c index 4914f60199..2bb7e10d4b 100644 --- a/util/coroutine-ucontext.c +++ b/util/coroutine-ucontext.c @@ -23,7 +23,6 @@ #undef _FORTIFY_SOURCE #endif #include "qemu/osdep.h" -#include <setjmp.h> #include <ucontext.h> #include "qemu-common.h" #include "qemu/coroutine_int.h" diff --git a/util/cutils.c b/util/cutils.c index c3dd53453a..43d1afbbec 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -29,6 +29,7 @@ #include "qemu/sockets.h" #include "qemu/iov.h" #include "net/net.h" +#include "qemu/cutils.h" void strpadcpy(char *buf, int buf_size, const char *str, char pad) { @@ -160,6 +161,38 @@ int qemu_fdatasync(int fd) #endif } +/* vector definitions */ +#ifdef __ALTIVEC__ +#include <altivec.h> +/* The altivec.h header says we're allowed to undef these for + * C++ compatibility. Here we don't care about C++, but we + * undef them anyway to avoid namespace pollution. + */ +#undef vector +#undef pixel +#undef bool +#define VECTYPE __vector unsigned char +#define SPLAT(p) vec_splat(vec_ld(0, p), 0) +#define ALL_EQ(v1, v2) vec_all_eq(v1, v2) +#define VEC_OR(v1, v2) ((v1) | (v2)) +/* altivec.h may redefine the bool macro as vector type. + * Reset it to POSIX semantics. */ +#define bool _Bool +#elif defined __SSE2__ +#include <emmintrin.h> +#define VECTYPE __m128i +#define SPLAT(p) _mm_set1_epi8(*(p)) +#define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0xFFFF) +#define VEC_OR(v1, v2) (_mm_or_si128(v1, v2)) +#else +#define VECTYPE unsigned long +#define SPLAT(p) (*(p) * (~0UL / 255)) +#define ALL_EQ(v1, v2) ((v1) == (v2)) +#define VEC_OR(v1, v2) ((v1) | (v2)) +#endif + +#define BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR 8 + static bool can_use_buffer_find_nonzero_offset_inner(const void *buf, size_t len) { diff --git a/util/error.c b/util/error.c index 47f93afe5f..cae2511732 100644 --- a/util/error.c +++ b/util/error.c @@ -13,6 +13,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/error-report.h" diff --git a/util/event_notifier-posix.c b/util/event_notifier-posix.c index 2e30e74bd6..e150301c33 100644 --- a/util/event_notifier-posix.c +++ b/util/event_notifier-posix.c @@ -12,6 +12,7 @@ #include "qemu/osdep.h" #include "qemu-common.h" +#include "qemu/cutils.h" #include "qemu/event_notifier.h" #include "sysemu/char.h" #include "qemu/main-loop.h" @@ -20,11 +21,17 @@ #include <sys/eventfd.h> #endif +#ifdef CONFIG_EVENTFD +/* + * Initialize @e with existing file descriptor @fd. + * @fd must be a genuine eventfd object, emulation with pipe won't do. + */ void event_notifier_init_fd(EventNotifier *e, int fd) { e->rfd = fd; e->wfd = fd; } +#endif int event_notifier_init(EventNotifier *e, int active) { @@ -12,6 +12,7 @@ #include "qemu/osdep.h" #include "qemu-common.h" +#include "qemu/id.h" bool id_wellformed(const char *id) { diff --git a/util/iov.c b/util/iov.c index 062f4e50c3..003fcce66f 100644 --- a/util/iov.c +++ b/util/iov.c @@ -17,8 +17,10 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" #include "qemu/iov.h" #include "qemu/sockets.h" +#include "qemu/cutils.h" size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt, size_t offset, const void *buf, size_t bytes) diff --git a/util/log.c b/util/log.c index 8b921de588..b219081e91 100644 --- a/util/log.c +++ b/util/log.c @@ -20,12 +20,16 @@ #include "qemu/osdep.h" #include "qemu-common.h" #include "qemu/log.h" +#include "qemu/range.h" +#include "qemu/error-report.h" +#include "qemu/cutils.h" #include "trace/control.h" static char *logfilename; FILE *qemu_logfile; int qemu_loglevel; static int log_append = 0; +static GArray *debug_regions; void qemu_log(const char *fmt, ...) { @@ -38,17 +42,6 @@ void qemu_log(const char *fmt, ...) va_end(ap); } -void qemu_log_mask(int mask, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - if ((qemu_loglevel & mask) && qemu_logfile) { - vfprintf(qemu_logfile, fmt, ap); - } - va_end(ap); -} - /* enable or disable low levels log */ void do_qemu_set_log(int log_flags, bool use_own_buffers) { @@ -96,15 +89,115 @@ void do_qemu_set_log(int log_flags, bool use_own_buffers) qemu_log_close(); } } - +/* + * Allow the user to include %d in their logfile which will be + * substituted with the current PID. This is useful for debugging many + * nested linux-user tasks but will result in lots of logs. + */ void qemu_set_log_filename(const char *filename) { + char *pidstr; g_free(logfilename); - logfilename = g_strdup(filename); + + pidstr = strstr(filename, "%"); + if (pidstr) { + /* We only accept one %d, no other format strings */ + if (pidstr[1] != 'd' || strchr(pidstr + 2, '%')) { + error_report("Bad logfile format: %s", filename); + logfilename = NULL; + } else { + logfilename = g_strdup_printf(filename, getpid()); + } + } else { + logfilename = g_strdup(filename); + } qemu_log_close(); qemu_set_log(qemu_loglevel); } +/* Returns true if addr is in our debug filter or no filter defined + */ +bool qemu_log_in_addr_range(uint64_t addr) +{ + if (debug_regions) { + int i = 0; + for (i = 0; i < debug_regions->len; i++) { + struct Range *range = &g_array_index(debug_regions, Range, i); + if (addr >= range->begin && addr <= range->end) { + return true; + } + } + return false; + } else { + return true; + } +} + + +void qemu_set_dfilter_ranges(const char *filter_spec) +{ + gchar **ranges = g_strsplit(filter_spec, ",", 0); + if (ranges) { + gchar **next = ranges; + gchar *r = *next++; + debug_regions = g_array_sized_new(FALSE, FALSE, + sizeof(Range), g_strv_length(ranges)); + while (r) { + char *range_op = strstr(r, "-"); + char *r2 = range_op ? range_op + 1 : NULL; + if (!range_op) { + range_op = strstr(r, "+"); + r2 = range_op ? range_op + 1 : NULL; + } + if (!range_op) { + range_op = strstr(r, ".."); + r2 = range_op ? range_op + 2 : NULL; + } + if (range_op) { + const char *e = NULL; + uint64_t r1val, r2val; + + if ((qemu_strtoull(r, &e, 0, &r1val) == 0) && + (qemu_strtoull(r2, NULL, 0, &r2val) == 0) && + r2val > 0) { + struct Range range; + + g_assert(e == range_op); + + switch (*range_op) { + case '+': + { + range.begin = r1val; + range.end = r1val + (r2val - 1); + break; + } + case '-': + { + range.end = r1val; + range.begin = r1val - (r2val - 1); + break; + } + case '.': + range.begin = r1val; + range.end = r2val; + break; + default: + g_assert_not_reached(); + } + g_array_append_val(debug_regions, range); + + } else { + g_error("Failed to parse range in: %s", r); + } + } else { + g_error("Bad range specifier in: %s", r); + } + r = *next++; + } + g_strfreev(ranges); + } +} + const QEMULogItem qemu_log_items[] = { { CPU_LOG_TB_OUT_ASM, "out_asm", "show generated host assembly code for each compiled TB" }, @@ -120,7 +213,7 @@ const QEMULogItem qemu_log_items[] = { { CPU_LOG_EXEC, "exec", "show trace before each executed TB (lots of logs)" }, { CPU_LOG_TB_CPU, "cpu", - "show CPU state before block translation" }, + "show CPU registers before entering a TB (lots of logs)" }, { CPU_LOG_MMU, "mmu", "log MMU-related activities" }, { CPU_LOG_PCALL, "pcall", diff --git a/util/osdep.c b/util/osdep.c index 8356bdd3d8..d56d071111 100644 --- a/util/osdep.c +++ b/util/osdep.c @@ -37,6 +37,7 @@ extern int madvise(caddr_t, size_t, int); #endif #include "qemu-common.h" +#include "qemu/cutils.h" #include "qemu/sockets.h" #include "qemu/error-report.h" #include "monitor/monitor.h" diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 7615be4e7a..20ca141dec 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -46,11 +46,12 @@ #include "sysemu/sysemu.h" #include "trace.h" +#include "qapi/error.h" #include "qemu/sockets.h" #include <sys/mman.h> #include <libgen.h> -#include <setjmp.h> #include <sys/signal.h> +#include "qemu/cutils.h" #ifdef CONFIG_LINUX #include <sys/syscall.h> diff --git a/util/oslib-win32.c b/util/oslib-win32.c index a3f0664763..c926db4a5c 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -32,10 +32,12 @@ #include "qemu/osdep.h" #include <windows.h> #include <glib.h> +#include "qapi/error.h" #include "sysemu/sysemu.h" #include "qemu/main-loop.h" #include "trace.h" #include "qemu/sockets.h" +#include "qemu/cutils.h" /* this must come after including "trace.h" */ #include <shlobj.h> diff --git a/util/path.c b/util/path.c index d09e8c5e14..5479f76c6d 100644 --- a/util/path.c +++ b/util/path.c @@ -7,6 +7,8 @@ #include <sys/param.h> #include <dirent.h> #include "qemu-common.h" +#include "qemu/cutils.h" +#include "qemu/path.h" struct pathelem { diff --git a/util/qemu-option.c b/util/qemu-option.c index e7aa43f857..dd9e73df54 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -25,11 +25,15 @@ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu-common.h" #include "qemu/error-report.h" #include "qapi/qmp/types.h" #include "qapi/qmp/qerror.h" #include "qemu/option_int.h" +#include "qemu/cutils.h" +#include "qemu/id.h" +#include "qemu/help_option.h" /* * Extracts the name of an option from the parameter string (p points at the diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 540649a7af..b87e17fa56 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -18,11 +18,13 @@ #include "qemu/osdep.h" #include "monitor/monitor.h" +#include "qapi/error.h" #include "qemu/sockets.h" #include "qemu/main-loop.h" #include "qapi/qmp-input-visitor.h" #include "qapi/qmp-output-visitor.h" #include "qapi-visit.h" +#include "qemu/cutils.h" #ifndef AI_ADDRCONFIG # define AI_ADDRCONFIG 0 diff --git a/util/readline.c b/util/readline.c index e94c97521b..bbdee790b0 100644 --- a/util/readline.c +++ b/util/readline.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include "qemu-common.h" #include "qemu/readline.h" +#include "qemu/cutils.h" #define IS_NORM 0 #define IS_ESC 1 diff --git a/util/throttle.c b/util/throttle.c index 371c769455..71246b2343 100644 --- a/util/throttle.c +++ b/util/throttle.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu/throttle.h" #include "qemu/timer.h" #include "block/aio.h" diff --git a/util/unicode.c b/util/unicode.c index 524dca8c7c..a812a35171 100644 --- a/util/unicode.c +++ b/util/unicode.c @@ -11,7 +11,7 @@ */ #include "qemu/osdep.h" -#include "qemu-common.h" +#include "qemu/unicode.h" /** * mod_utf8_codepoint: @@ -22,7 +22,8 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" - +#include "qemu/cutils.h" +#include "qemu/help_option.h" #ifdef CONFIG_SECCOMP #include "sysemu/seccomp.h" @@ -3354,6 +3355,9 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_D: log_file = optarg; break; + case QEMU_OPTION_DFILTER: + qemu_set_dfilter_ranges(optarg); + break; case QEMU_OPTION_s: add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT); break; @@ -3729,12 +3733,6 @@ int main(int argc, char **argv, char **envp) #endif break; } - case QEMU_OPTION_input_linux: - if (!qemu_opts_parse_noisily(qemu_find_opts("input-linux"), - optarg, true)) { - exit(1); - } - break; case QEMU_OPTION_no_acpi: acpi_enabled = 0; break; @@ -4598,10 +4596,6 @@ int main(int argc, char **argv, char **envp) qemu_spice_display_init(); } #endif -#ifdef CONFIG_LINUX - qemu_opts_foreach(qemu_find_opts("input-linux"), - input_linux_init, NULL, &error_fatal); -#endif if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) { exit(1); |